Skip to content

Commit

Permalink
check language (#521)
Browse files Browse the repository at this point in the history
* check language

* language tests

* Update drawBot/drawBotDrawingTools.py

Co-authored-by: Just van Rossum <justvanrossum@gmail.com>

---------

Co-authored-by: Just van Rossum <justvanrossum@gmail.com>
  • Loading branch information
typemytype and justvanrossum authored Dec 5, 2023
1 parent 08b62c2 commit 567a1b7
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
11 changes: 7 additions & 4 deletions drawBot/drawBotDrawingTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from .context.tools import openType
from .context.tools import drawBotbuiltins

from .misc import DrawBotError, warnings, VariableController, optimizePath, isPDF, isEPS, isGIF, transformationAtCenter, clearMemoizeCache
from .misc import DrawBotError, warnings, VariableController, optimizePath, isPDF, isEPS, isGIF, transformationAtCenter, clearMemoizeCache, validateLanguageCode


def _getmodulecontents(module, names=None):
Expand Down Expand Up @@ -1516,8 +1516,9 @@ def tabs(self, *tabs):
def language(self, language):
"""
Set the preferred language as language tag or None to use the default language.
Support is depending on local OS.
A language tag might be a [iso639-2 or iso639-1](https://www.loc.gov/standards/iso639-2/php/English_list.php)
code or a locale identifier supported by local OS.
A warning will be issued if the language tag is not supported.
`language()` will activate the `locl` OpenType features, if supported by the current font.
Expand All @@ -1541,6 +1542,8 @@ def language(self, language):
# darw the text again with a language set
textBox(word, box)
"""
if not validateLanguageCode(language):
warnings.warn(f"Language '{language}' is not available.")
self._dummyContext.language(language)
self._checkLanguageHyphenation()
self._addInstruction("language", language)
Expand All @@ -1557,7 +1560,7 @@ def _checkLanguageHyphenation(self):
if language and self._dummyContext._state.hyphenation:
locale = CoreText.CFLocaleCreate(None, language)
if not CoreText.CFStringIsHyphenationAvailableForLocale(locale):
warnings.warn("Language '%s' has no hyphenation available." % language)
warnings.warn(f"Language '{language}' has no hyphenation available.")

def openTypeFeatures(self, *args, **features):
"""
Expand Down
19 changes: 19 additions & 0 deletions drawBot/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,25 @@ def nsStringLength(s):
return len(s.encode("utf-16-be")) // 2


# ===================
# = language tools =
# ===================

def canonicalLocaleCode(localeCode):
parsedLoc = AppKit.NSLocale.componentsFromLocaleIdentifier_(localeCode)
parts = [
parsedLoc[AppKit.kCFLocaleLanguageCode],
parsedLoc.get(AppKit.kCFLocaleScriptCode),
parsedLoc.get(AppKit.kCFLocaleCountryCode),
]
return "_".join(part for part in parts if part)


def validateLanguageCode(localeCode):
localeCode = canonicalLocaleCode(localeCode)
return localeCode in AppKit.NSLocale.availableLocaleIdentifiers()


# ============
# = warnings =
# ============
Expand Down
30 changes: 29 additions & 1 deletion tests/testMisc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from collections import OrderedDict
from fontTools.ttLib import TTFont
import drawBot
from drawBot.misc import DrawBotError, warnings
from drawBot.misc import DrawBotError, warnings, validateLanguageCode
from drawBot.scriptTools import ScriptRunner
from testSupport import StdOutCollector, testDataDir

Expand Down Expand Up @@ -394,6 +394,34 @@ def test_remap(self):
assert drawBot.remap(25, 10, 20, 30, 50) == 60
assert drawBot.remap(25, 10, 20, 30, 50, clamp=True) == 50

def test_validateLanguageCode(self):
expectedLanguageValidation = [
("ab", False),
("abk", False),
("abz", False),
("AB", False),
("af", True),
("afr", True),
("af_NA", True),
("afr_NA", True),
("af_ZZ", False),
("afr_ZZ", False),
("en-us", True),
("en_us", True),
("EN-US", True),
("en-zz", False),
("sr_Cyrl_ME", True),
("en", True),
]
for language, expectedValue in expectedLanguageValidation:
assert validateLanguageCode(language) == expectedValue

with StdOutCollector(captureStdErr=True) as output:
drawBot.language(language)
if expectedValue:
assert output.lines() == []
else:
assert output.lines() == [f"*** DrawBot warning: Language '{language}' is not available. ***"]


def _roundInstanceLocations(instanceLocations):
Expand Down

0 comments on commit 567a1b7

Please sign in to comment.