Localising scripts

Is it possible to localise Python scripts to other languages, especially menu titles and popup help?

Not yet.

You mean the tooltips in the menu, right?

image

We have discussed this a bit. We came up with two different formats:

#MenuTitles: jp:izgfuz, en:asdhgvkaghs, de:kdhfo

or

__MenuTitle__ = {
	"jp": "izgfuz",
	"en": "asdhgvkaghs",
	"de": "kdhfo"
}

and for the tooltip:

__doc__="""
Create effect for selected glyphs.
jp: asjdh ajhsdg
cn: aishd jahsdb
"""

__doc__="""
Create effect for selected glyphs.
🇦🇹: asjdh ajhsdg
🇫🇮: aishd jahsdb
"""

in this case, it would show everything in older versions but newer versions would only show one language.

or:

__MenuDescription__ = {
	"en": "Create effect for selected glyphs.",
	"jp": "asjdh ajhsdg",
	"cn": "aishd jahsdb"
}

What do you think?

2 Likes

Yes that’s it. At least I didn’t say balloon help :slight_smile:

@GeorgSeifert Typing flags is cumbersome, also language doesn’t equal country. And I think I like consistency with the rest of the UI (just sticking to one language), namely the dictionary approach.

Sorry for asking here.

How can I assign strings of zh-Hant & zh-Hans separately in localize() function?

It should work with the full language tag.

I’ve tried several tag names, and none of them worked.

print Glyphs.defaults["AppleLanguages"]
print Glyphs.localize({'en': 'Test', 'zh-TW': 'Hello'})
print Glyphs.localize({'en': 'Test', 'zh-HK': 'Hello'})
print Glyphs.localize({'en': 'Test', 'zh-Hant': 'Hello'})
print Glyphs.localize({'en': 'Test', 'zh-Hant-TW': 'Hello'})
print Glyphs.localize({'en': 'Test', 'zh-Hant-HK': 'Hello'})
print Glyphs.localize({'en': 'Test', 'zh': 'Hello'})

the result is: (in macro view)

(
    "zh-Hant-TW",
    ja
)
Test
Test
Test
Test
Test
Hello

Only the tag ‘zh’ worked. But it usually means Simplified Chinese.

As Toshi indicated, localization should be based on BCP 47 language tags, not on country codes or flags. So instead of country code JP use language tag ja, instead of country code CN use language tag zh, instead of flag :austria: use language tag de-AT, instead of flag :finland: use language tag fi.

Somehow I forgot to answer this:
the possible keys in for Glyphs.localize() are:

"en"
"ru"
"ar"
"fr"
"ja"
"es"
"de"
"ko"
"zh-Hans"
"zh-Hant"
"pt"
"tr"
"it"
"cs"

Those keys are used by Glyphs itself for its localization:

1 Like

‘zh-Hant’ still didn’t work in Glyphs 3.0.3

image

image


I’ve tried same script.

  print(Glyphs.defaults["AppleLanguages"])
  print(Glyphs.localize({'en': 'Test', 'zh-TW': 'Hello'}))
  print(Glyphs.localize({'en': 'Test', 'zh-HK': 'Hello'}))
  print(Glyphs.localize({'en': 'Test', 'zh-Hant': 'Hello'}))
  print(Glyphs.localize({'en': 'Test', 'zh-Hant-TW': 'Hello'}))
  print(Glyphs.localize({'en': 'Test', 'zh-Hant-HK': 'Hello'}))
  print(Glyphs.localize({'en': 'Test', 'zh': 'Hello'}))

Glyphs.defaults[“AppleLanguages”] returns ‘zh-Hant-TW’.
Now ‘zh-Hant-TW’ worked, but ‘zh-Hant’ can not.

(
    "zh-Hant-TW",
    "ja-TW"
)
Test
Test
Test
Hello
Test
Hello
1 Like

https://developer.apple.com/documentation/foundation/nsbundle/1417249-preferredlocalizationsfromarray?language=objc

from Foundation import NSBundle

def localize(localization):
	if isinstance(localization, dict):
		for locale_identifier in NSBundle.preferredLocalizationsFromArray_(tuple(localization.keys())):
			if locale_identifier in localization:
				return localization[locale_identifier]
		return localization[next(iter(localization.keys()))]
	return localization

print(Glyphs.defaults["AppleLanguages"])
print(localize({'en': 'Test', 'zh-TW':      'Hello'}))
print(localize({'en': 'Test', 'zh-HK':      'Hello'}))
print(localize({'en': 'Test', 'zh-Hant':    'Hello'}))
print(localize({'en': 'Test', 'zh-Hant-TW': 'Hello'}))
print(localize({'en': 'Test', 'zh-Hant-HK': 'Hello'}))
print(localize({'en': 'Test', 'zh':         'Hello'}))
(
    "zh-Hant-TW",
    "ja-TW"
)
Hello
Hello
Hello
Hello
Hello
Test

Not sure how I should treat zh, but how about using + [NSBundle preferredLocalizationsFromArray:]? Tested on G3 launched with the following switches:

$ open '/Applications/Glyphs 3.app' --args -AppleLanguages '(zh-Hant-TW, ja-TW)' -AppleLocale zh-TW

Thanks for the test code. I found the problem and fixed it.

I saw the release note for 3.0.4 (3099), but I’m afraid that the issue has not been fully fixed:

if Glyphs.defaults["AppleLanguages"] == ('zh-Hant-TW', 'ja-TW'):
	# $ open '/Applications/Glyphs 3.app' --args -AppleLanguages '(zh-Hant-TW, ja-TW)' -AppleLocale zh-TW
	assert localize({'en': 'English', 'zh-TW':      'Traditional', 'zh-CN':      'Simplified'}) == 'Traditional'
	assert localize({'en': 'English', 'zh-HK':      'Traditional', 'zh-CN':      'Simplified'}) == 'Traditional'
	assert localize({'en': 'English', 'zh-Hant':    'Traditional', 'zh-Hans':    'Simplified'}) == 'Traditional'
	assert localize({'en': 'English', 'zh-Hant-TW': 'Traditional', 'zh-Hans-CN': 'Simplified'}) == 'Traditional'
	assert localize({'en': 'English', 'zh-Hant-HK': 'Traditional', 'zh-Hans-CN': 'Simplified'}) == 'Traditional'
	assert localize({'en': 'English', 'zh-TW':      'Traditional'})                             == 'Traditional'
	assert localize({'en': 'English', 'zh-HK':      'Traditional'})                             == 'Traditional'
	assert localize({'en': 'English', 'zh-Hant':    'Traditional'})                             == 'Traditional'
	assert localize({'en': 'English', 'zh-Hant-TW': 'Traditional'})                             == 'Traditional'
	assert localize({'en': 'English', 'zh-Hant-HK': 'Traditional'})                             == 'Traditional'
	assert localize({'en': 'English', 'zh-CN':      'Simplified'})                              == 'English'
	assert localize({'en': 'English', 'zh-Hans':    'Simplified'})                              == 'English'
	assert localize({'en': 'English', 'zh-Hans-CN': 'Simplified'})                              == 'English'
	assert localize({'en': 'English', 'zh':         'Traditional or Simplified'})               == 'English'
elif Glyphs.defaults["AppleLanguages"] == ('zh-Hans-CN',):
    # open '/Applications/Glyphs 3.app' --args -AppleLanguages '(zh-Hans-CN)' -AppleLocale zh-CN 
	assert localize({'en': 'English', 'zh-TW':      'Traditional', 'zh-CN':      'Simplified'}) == 'Simplified'
	assert localize({'en': 'English', 'zh-HK':      'Traditional', 'zh-CN':      'Simplified'}) == 'Simplified'
	assert localize({'en': 'English', 'zh-Hant':    'Traditional', 'zh-Hans':    'Simplified'}) == 'Simplified'
	assert localize({'en': 'English', 'zh-Hant-TW': 'Traditional', 'zh-Hans-CN': 'Simplified'}) == 'Simplified'
	assert localize({'en': 'English', 'zh-Hant-HK': 'Traditional', 'zh-Hans-CN': 'Simplified'}) == 'Simplified'
	assert localize({'en': 'English', 'zh-TW':      'Traditional'})                             == 'English'
	assert localize({'en': 'English', 'zh-HK':      'Traditional'})                             == 'English'
	assert localize({'en': 'English', 'zh-Hant':    'Traditional'})                             == 'English'
	assert localize({'en': 'English', 'zh-Hant-TW': 'Traditional'})                             == 'English'
	assert localize({'en': 'English', 'zh-Hant-HK': 'Traditional'})                             == 'English'
	assert localize({'en': 'English', 'zh-CN':      'Simplified'})                              == 'Simplified'
	assert localize({'en': 'English', 'zh-Hans':    'Simplified'})                              == 'Simplified'
	assert localize({'en': 'English', 'zh-Hans-CN': 'Simplified'})                              == 'Simplified'
	assert localize({'en': 'English', 'zh':         'Traditional or Simplified'})               == 'Traditional or Simplified'
else:
	assert False

Sorry for the lengthy snippet, but the above is the expectation when I use the localize() function in my last post. I guess the result should be close to what @ButKo expects here, and it should also match what you’ll get with NSLocalizedString() in fully localised Cocoa apps. It might be tricky to mimick it in pure Python though. And back to the point, I also would like to see that the @Tosche’s request gets implemented…

The current implementation assumes that you only use the script tag as keys, without the language suffix.
So zh-Hant works, but zh-Hant-HK might not. Glyphs itself doesn’t distinguish between languages, either. And it will not fall back to a different language. So this line:

	assert localize({'en': 'English', 'zh-Hant-HK': 'Traditional', 'zh-Hans-CN': 'Simplified'}) == 'Traditional'

is rightfully returning English as the language is set to Taiwan and you are looking for Hongkong.

CFBundle_Locale.c (OS X 10.10.5)
ualoc.cpp (OS X 10.11.6)
ualoc.cpp (OS X 10.10.5)

Thanks for your explanation! I was just skimming the source code of the several Apple-patched versions of ICU, and I have a very vague memory that AppleLanguages used to return zh-TW/zh-HK/zh-MO instead of zh-Hant-* on OS X 10.10. That’s why I originally thought it would be hard to get it right, but after some experiments now I see it works if I use zh-Hans and zh-Hant for keys. Still, questions like ‘should en-GB be preferred over en-US in en-IN environment?’ or ‘will zh-Hant people prefer zh-Hans over en-US?’ would remain, and I think that’s where the ICU portion comes into play. l10n is so easy to shoot myself in the foot…

I would expect only scripts as keys, without the country suffix. How often you need a label in a dialog be different for GB or US?

Yep, I agree. I don’t see any issues since Glyphs doesn’t have region-specific translations for now – I think it’s safe to assume that no one would try to translate scripts/plugins to languages/variants not supported by the host application.

https://github.com/search?q=zh+Glyphs.localize+language%3Apython&type=Code

People tend to put Simplified Chinese to zh. When the user prefers zh-Hant-* as a system language, macOS doesn’t fallback to zh (= zh-Hans) but to the base language (en). The current Glyphs.localize() fallbacks to zh, and that is the only difference/inconsistency I see so far. Simply discouraging the use of zh as a key might solve the problem.

1 Like