1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-24 16:38:07 +02:00

Add support for & examples of translatable strings with context...

... This includes functions callable from Nyquist but not yet any examples
of strings with context in any .ny files.

This does include some examples of strings with context, and with both plurals
and context, in C++ files.  It is not intended to fix possible ambiguities
exhaustively.

Note that wxWidgets 3.1.1 is sufficient to support contexts.

If Audacity is build with wxWidgets 3.0, it will run, but strings with
context will fail to translate.
This commit is contained in:
Paul Licameli 2020-05-24 14:58:57 -04:00
commit e526b2b940
7 changed files with 75 additions and 13 deletions

View File

@ -5,7 +5,7 @@ sed -E 's/\.\.\///g' |\
xargs xgettext \
--default-domain=audacity \
--directory=.. \
--keyword=_ --keyword=XO --keyword=XXO --keyword=XP:1,2 \
--keyword=_ --keyword=XO --keyword=XC:1,2c --keyword=XXO --keyword=XP:1,2 --keyword=XPC:1,2,4c \
--add-comments=" i18n" \
--add-location=file \
--copyright-holder='Audacity Team' \
@ -19,7 +19,7 @@ sed -E 's/\.\.\///g' |\
xargs xgettext \
--default-domain=audacity \
--directory=.. \
--keyword=_ --keyword=ngettext:1,2 \
--keyword=_ --keyword=_C:1,2c --keyword=ngettext:1,2 --keyword=ngettextc:1,2,4c \
--add-comments=" i18n" \
--add-location=file \
--copyright-holder='Audacity Team' \

View File

@ -363,7 +363,7 @@ wxString TranslatableString::DoChooseFormat(
? ( nn == 1 ? singular : plural )
: wxGetTranslation(
singular, plural, nn
#if wxCHECK_VERSION(3, 1, 3)
#if HAS_I18N_CONTEXTS
, wxString{} // domain
, context
#endif

View File

@ -32,7 +32,13 @@ extern AUDACITY_DLL_API const wxString& GetCustomSubstitution(const wxString& st
// '&', preceding menu accelerators, should NOT occur in the argument.
#define XO(s) (TranslatableString{ wxT(s), {} })
// Marks strings for extraction only, where '&', preceding men accelerators, MAY
// Alternative taking a second context argument. A context is a string literal,
// which is not translated, but serves to disambiguate uses of the first string
// that might need differing translations, such as "Light" meaning not-heavy in
// one place but not-dark elsewhere.
#define XC(s, c) (TranslatableString{ wxT(s), {} }.Context(c))
// Marks strings for extraction only, where '&', preceding menu accelerators, MAY
// occur.
// For now, expands exactly as macro XO does, but in future there will be a
// type distinction - for example XXO should be used for menu item names that
@ -86,6 +92,10 @@ extern AUDACITY_DLL_API const wxString& GetCustomSubstitution(const wxString& st
#define XP(sing, plur, n) \
TranslatableString{ wxT(sing), {} }.Plural<(n)>( wxT(plur) )
// Like XP but with an additional context argument, as for XC
#define XPC(sing, plur, n, c) \
TranslatableString{ wxT(sing), {} }.Context(c).Plural<(n)>( wxT(plur) )
#endif
class Internat
@ -151,4 +161,9 @@ TranslatableStrings Msgids(
const EnumValueSymbol strings[], size_t nStrings);
TranslatableStrings Msgids( const std::vector<EnumValueSymbol> &strings );
// Whether disambiguationg contexts are supported
// If not, then the program builds and runs, but strings in the catalog with
// contexts will fail to translate
#define HAS_I18N_CONTEXTS wxCHECK_VERSION(3, 1, 1)
#endif

View File

@ -1897,10 +1897,13 @@ bool PluginManager::DropFile(const wxString &fileName)
// Ask whether to enable the plug-ins
if (auto nIds = ids.size()) {
auto message = XP(
auto message = XPC(
/* i18n-hint A plug-in is an optional added program for a sound
effect, or generator, or analyzer */
"Enable this plug-in?\n",
"Enable these plug-ins?\n",
0
0,
"plug-ins"
)( nIds );
for (const auto &name : names)
message.Join( Verbatim( name ), wxT("\n") );

View File

@ -94,7 +94,8 @@ kBackgroundStrings[ ScreenshotCommand::nBackgrounds ] =
{
// These are acceptable dual purpose internal/visible names
{ XO("Blue") },
{ XO("White") },
/* i18n-hint: This really means the color, not as in "white noise" */
{ XC("White", "color") },
{ XO("None") },
};

View File

@ -41,9 +41,13 @@ enum kTypes
static const EnumValueSymbol kTypeStrings[nTypes] =
{
// These are acceptable dual purpose internal/visible names
{ XO("White") },
{ XO("Pink") },
{ XO("Brownian") }
/* i18n-hint: not a color, but "white noise" having a uniform spectrum */
{ XC("White", "noise") },
/* i18n-hint: not a color, but "pink noise" having a spectrum with more power
in low frequencies */
{ XC("Pink", "noise") },
/* i18n-hint: a kind of noise spectrum also known as "red" or "brown" */
{ XC("Brownian", "noise") }
};
// Define keys, defaults, minimums, and maximums for the effect parameters

View File

@ -1443,8 +1443,8 @@ bool NyquistEffect::ProcessOne()
if (rval == nyx_string) {
// Assume the string has already been translated within the Lisp runtime
// if necessary, by gettext or ngettext defined below, before it is
// communicated back to C++
// if necessary, by one of the gettext functions defined below, before it
// is communicated back to C++
auto msg = Verbatim( NyquistToWxString(nyx_get_string()) );
if (!msg.empty()) { // Empty string may be used as a No-Op return value.
Effect::MessageBox( msg );
@ -3332,20 +3332,58 @@ void NyquistOutputDialog::OnOk(wxCommandEvent & /* event */)
static LVAL gettext()
{
auto string = UTF8CTOWX(getstring(xlgastring()));
#if !HAS_I18N_CONTEXTS
// allow ignored context argument
if ( moreargs() )
nextarg();
#endif
xllastarg();
return cvstring(GetCustomTranslation(string).mb_str(wxConvUTF8));
}
static LVAL gettextc()
{
#if HAS_I18N_CONTEXTS
auto string = UTF8CTOWX(getstring(xlgastring()));
auto context = UTF8CTOWX(getstring(xlgastring()));
xllastarg();
return cvstring(wxGetTranslation( string, "", 0, "", context )
.mb_str(wxConvUTF8));
#else
return gettext();
#endif
}
static LVAL ngettext()
{
auto string1 = UTF8CTOWX(getstring(xlgastring()));
auto string2 = UTF8CTOWX(getstring(xlgastring()));
auto number = getfixnum(xlgafixnum());
#if !HAS_I18N_CONTEXTS
// allow ignored context argument
if ( moreargs() )
nextarg();
#endif
xllastarg();
return cvstring(
wxGetTranslation(string1, string2, number).mb_str(wxConvUTF8));
}
static LVAL ngettextc()
{
#if HAS_I18N_CONTEXTS
auto string1 = UTF8CTOWX(getstring(xlgastring()));
auto string2 = UTF8CTOWX(getstring(xlgastring()));
auto number = getfixnum(xlgafixnum());
auto context = UTF8CTOWX(getstring(xlgastring()));
xllastarg();
return cvstring(wxGetTranslation( string1, string2, number, "", context )
.mb_str(wxConvUTF8));
#else
return ngettext();
#endif
}
/*--------------------Audacity Automation -------------------------*/
/* These functions may later move to their own source file. */
extern void * ExecForLisp( char * pIn );
@ -3413,8 +3451,9 @@ static void RegisterFunctions()
// All function names must be UP-CASED
static const FUNDEF functions[] = {
{ "_", SUBR, gettext },
// to do: more i18n functions, for contexts and plurals
{ "_C", SUBR, gettextc },
{ "NGETTEXT", SUBR, ngettext },
{ "NGETTEXTC", SUBR, ngettextc },
{ "AUD-DO", SUBR, xlc_aud_do },
};