Skip to content

Instantly share code, notes, and snippets.

@moyogo
Created October 15, 2019 13:20
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save moyogo/a72da86f96b2d74c6a09245f1786e2e7 to your computer and use it in GitHub Desktop.
Check language CLDR locales supported by a font
'''
Requires pyicu, fontTools
Authors:
Denis Moyogo Jacquerye [https://github.com/moyogo]
MIT License [https://opensource.org/licenses/MIT]
'''
import sys
import icu
from fontTools.ttLib import TTFont
import argparse
def main():
parser = argparse.ArgumentParser(
description='Check CLDR languages supported by a font.'
)
parser.add_argument(
'font', metavar='FONT', type=str,
help='TTF/OTF Font file.'
)
parser.add_argument(
'--langs-file', type=str,
help='File with CLDR language names.'
)
parser.add_argument(
'--punctuation', action='store_true',
help='Take punctuation into account.'
)
parser.add_argument(
'--show-available-locales', action='store_true',
help='List all the available CLDR locales'
)
args = parser.parse_args()
font_path = args.font
langs_path = args.langs_file
# get font characters
font = TTFont(font_path)
cmap = font.getBestCmap()
font_chars = frozenset(chr(c) for c in cmap.keys())
print(">>> %i characters in font" % len(font_chars))
# get CLDR locales
locales = icu.Locale.getAvailableLocales()
locale_names = set(l.getDisplayName() for l in locales.values())
if args.show_available_locales:
print(">>> Available CLDR locales:")
print("\n".join(sorted(locale_names)))
# get languages to check
langs = set()
if args.langs_file:
wrong_locale = False
with open(langs_path) as fp:
for line in fp.readlines():
lang = line.strip()
if lang not in locale_names:
print("::: error: %s not an ICU locale" % lang)
wrong_locale = True
langs.add(lang)
if wrong_locale:
return
# find supported locales
supported_locales = set()
unsupported = dict()
for locale_key in locales.keys():
locale_data = icu.LocaleData(locale_key)
# alphabetical characters
locale_chars = set("".join(locale_data.getExemplarSet(0)))
# punctuation characters
if args.punctuation:
locale_chars |= set("".join(locale_data.getExemplarSet(3)))
locale = icu.Locale(locale_key)
if locale_chars.intersection(font_chars) == locale_chars:
locale_script = locale.getScript()
supported_locales.add(locale.getDisplayName())
else:
unsupported[locale.getDisplayName()] = \
locale_chars.difference(font_chars)
diff = langs.difference(supported_locales)
if True:
print(">>> %i supported CLDR locales" % (len(supported_locales)))
if args.langs_file:
print(">>> %i unsupported out of %i locales: " % (len(diff), len(langs)))
for d in sorted(diff):
print(d, ",".join("%04X" % ord(c) for c in sorted(unsupported[d])))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment