From a6a86973dd54d623394fdbfc61e6e4c0ca263cc0 Mon Sep 17 00:00:00 2001
From: Lex Neva <github.com@lexneva.name>
Date: Tue, 2 Apr 2019 23:07:38 -0400
Subject: [PATCH] add localization for font names and descriptions

---
 Makefile                    |  1 +
 bin/inkstitch-fonts-gettext | 19 +++++++++++++++++++
 lib/i18n.py                 | 28 ++++++++++++++++++++++++++--
 lib/lettering/font.py       | 25 ++++++++++++++++++++++---
 4 files changed, 68 insertions(+), 5 deletions(-)
 create mode 100755 bin/inkstitch-fonts-gettext

diff --git a/Makefile b/Makefile
index ed86a36ce..5635547e2 100644
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,7 @@ inx: locales
 messages.po:
 	rm -f messages.po
 	bin/pyembroidery-gettext > pyembroidery-format-descriptions.py
+	bin/inkstitch-fonts-gettext > inkstitch-fonts-metadata.py
 	pybabel extract -o messages.po -F babel.conf --add-location=full --add-comments=l10n,L10n,L10N --sort-by-file --strip-comments -k N_ .
 	rm pyembroidery-format-descriptions.py
 
diff --git a/bin/inkstitch-fonts-gettext b/bin/inkstitch-fonts-gettext
new file mode 100755
index 000000000..8a3aa7289
--- /dev/null
+++ b/bin/inkstitch-fonts-gettext
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+import os
+import json
+
+# generate fake python code containing the names and descriptions of all built-
+# in fonts as gettext calls so that pybabel will extract them into messages.po
+
+fonts_dir = os.path.join(os.path.dirname(__file__), "..", "fonts")
+
+for font in os.listdir(fonts_dir):
+	with open(os.path.join(fonts_dir, font, "font.json")) as font_json:
+		font_metadata = json.load(font_json)
+		
+		print "# L10N name of font in fonts/%s" % font
+		print "_(%s)" % repr(font_metadata.get("name", ""))
+		
+		print "# L10N description of font in fonts/%s" % font
+		print "_(%s)" % repr(font_metadata.get("description", ""))
\ No newline at end of file
diff --git a/lib/i18n.py b/lib/i18n.py
index 98f63ec17..f57bbf9c7 100644
--- a/lib/i18n.py
+++ b/lib/i18n.py
@@ -1,7 +1,9 @@
-import sys
+import gettext
 import os
 from os.path import dirname, realpath
-import gettext
+import sys
+
+from .utils import cache
 
 _ = translation = None
 locale_dir = None
@@ -33,5 +35,27 @@ def localize(languages=None):
     _ = translation.ugettext
 
 
+@cache
+def get_languages():
+    """return a list of languages configured by the user
+
+    I really wish gettext provided this as a function.  Instead, we've duplicated
+    its code below.
+    """
+
+    languages = []
+
+    for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
+        val = os.environ.get(envar)
+        if val:
+            languages = val.split(':')
+            break
+
+    if 'C' not in languages:
+        languages.append('C')
+
+    return languages
+
+
 _set_locale_dir()
 localize()
diff --git a/lib/lettering/font.py b/lib/lettering/font.py
index 6f749d289..46e2648dd 100644
--- a/lib/lettering/font.py
+++ b/lib/lettering/font.py
@@ -8,7 +8,7 @@ import inkex
 
 from ..elements import nodes_to_elements
 from ..exceptions import InkstitchException
-from ..i18n import _
+from ..i18n import _, get_languages
 from ..stitches.auto_satin import auto_satin
 from ..svg import PIXELS_PER_MM
 from ..svg.tags import SVG_GROUP_TAG, SVG_PATH_TAG, INKSCAPE_LABEL
@@ -32,6 +32,25 @@ def font_metadata(name, default=None, multiplier=None):
     return property(getter)
 
 
+def localized_font_metadata(name, default=None):
+    def getter(self):
+        # If the font contains a localized version of the attribute, use it.
+        for language in get_languages():
+            attr = "%s_%s" % (name, language)
+            if attr in self.metadata:
+                return self.metadata.get(attr)
+
+        if name in self.metadata:
+            # This may be a font packaged with Ink/Stitch, in which case the
+            # text will have been sent to CrowdIn for community translation.
+            # Try to fetch the translated version.
+            return _(self.metadata.get(name))
+        else:
+            return default
+
+    return property(getter)
+
+
 class Font(object):
     """Represents a font with multiple variants.
 
@@ -79,8 +98,8 @@ class Font(object):
                 # we'll deal with missing variants when we apply lettering
                 pass
 
-    name = font_metadata('name', '')
-    description = font_metadata('description', '')
+    name = localized_font_metadata('name', '')
+    description = localized_font_metadata('description', '')
     default_variant = font_metadata('default_variant', FontVariant.LEFT_TO_RIGHT)
     default_glyph = font_metadata('defalt_glyph', u"�")
     letter_spacing = font_metadata('letter_spacing', 1.5, multiplier=PIXELS_PER_MM)