diff --git a/docs/linux/keyman-config.md b/docs/linux/keyman-config.md index 88939ea3e4..1f13bc1a54 100644 --- a/docs/linux/keyman-config.md +++ b/docs/linux/keyman-config.md @@ -193,7 +193,18 @@ This will create `.mo` files, e.g. `locale/de/LC_MESSAGES/keyman-config.mo`. ### Testing localization ```bash -LANGUAGE=de ./km-config +TEXTDOMAINDIR=./locale LANGUAGE=de ./km-config +``` + +## Testing that all strings are localizable + +To test that all strings can be translated, you can run the following +command. This will create and compile a TEST.po file +which shows all localizable strings in uppercase, and then run +km-config with the TEST.po file. + +```bash +make test-po ``` ## Debugging unit tests diff --git a/linux/.gitignore b/linux/.gitignore index a67e991b30..c60f2f9a05 100644 --- a/linux/.gitignore +++ b/linux/.gitignore @@ -42,3 +42,4 @@ watch .pc/ # Debian patch files will be re-generated debian/patches/ +TEST.po diff --git a/linux/keyman-config/Makefile b/linux/keyman-config/Makefile index 8176f0f144..59359417f4 100644 --- a/linux/keyman-config/Makefile +++ b/linux/keyman-config/Makefile @@ -3,11 +3,8 @@ default: echo "Use ./build.sh command instead of make!" -version_reconf: - cd .. && ./scripts/reconf.sh - -version: version_reconf - $(eval KEYMAN_VERSION := $(shell ./build.sh build && python3 -c "from keyman_config import __releaseversion__; print(__releaseversion__)")) +version: + $(eval KEYMAN_VERSION := $(shell ./build.sh build > /dev/null && python3 -c "from keyman_config import __releaseversion__; print(__releaseversion__)")) # i18n @@ -31,3 +28,15 @@ $(MOFILES): %/LC_MESSAGES/keyman-config.mo: %.po msgfmt -v --check --output-file=$@ $^ compile-po: $(MOFILES) + +create-test-po: + cd locale && \ + msginit --locale=TEST --width=98 --no-translator --input keyman-config.pot --output-file=TEST.po && \ + mv TEST.po TEST1.po && \ + ../../scripts/create-test-po.py TEST1.po TEST.po && \ + rm TEST1.po + +test-po: create-test-po + mkdir -p locale/TEST/LC_MESSAGES + msgfmt -v --check --output-file=locale/TEST/LC_MESSAGES/keyman-config.mo locale/TEST.po + TEXTDOMAINDIR=./locale LANGUAGE=TEST ./km-config diff --git a/linux/keyman-config/build.sh b/linux/keyman-config/build.sh index 09061feda2..bd5cf44939 100755 --- a/linux/keyman-config/build.sh +++ b/linux/keyman-config/build.sh @@ -80,7 +80,7 @@ build_action() { version.py.in > version.py popd pushd buildtools - if [ -f build-langtags.py ]; then + if [[ -f build-langtags.py ]]; then builder_echo "Create lang_tags_map.py" python3 ./build-langtags.py else diff --git a/linux/keyman-config/keyman_config/__init__.py b/linux/keyman-config/keyman_config/__init__.py index 937bcc7d08..4293c708fd 100644 --- a/linux/keyman-config/keyman_config/__init__.py +++ b/linux/keyman-config/keyman_config/__init__.py @@ -161,8 +161,10 @@ def add_standard_arguments(parser): parser.add_argument('-v', '--verbose', action='store_true', help='verbose logging') parser.add_argument('-vv', '--veryverbose', action='store_true', help='very verbose logging') - -gettext.bindtextdomain('keyman-config', '/usr/share/locale') +if os.environ.get('TEXTDOMAINDIR'): + gettext.bindtextdomain('keyman-config', os.environ['TEXTDOMAINDIR']) +else: + gettext.bindtextdomain('keyman-config', '/usr/share/locale') gettext.textdomain('keyman-config') diff --git a/linux/scripts/create-test-po.py b/linux/scripts/create-test-po.py new file mode 100755 index 0000000000..f1efeacc1f --- /dev/null +++ b/linux/scripts/create-test-po.py @@ -0,0 +1,43 @@ +#!/usr/bin/python3 +# This script is used to convert all strings in a .po file to uppercase. +# It is used to test the .po file translations. +import polib +import sys +import re + + +# Requires installation of python3-polib + +def uppercase_except_braces(s): + # Replace all text outside braces and %... (to next space) with uppercase, keep inside braces and %... as is + def repl(match): + text = match.group(0) + if text.startswith('{') and text.endswith('}'): + return text + return text if text.startswith('%') else text.upper() + + # This regex splits the string into: + # - brace blocks: { ... } + # - percent blocks: %... (up to next space or end of string) + # - everything else + pattern = r'\{[^}]*\}|%[^\s]*|[^{%]+' + return re.sub(pattern, repl, s) + + +if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + +po = polib.pofile(sys.argv[1]) + +for entry in po: + # Only update if not a fuzzy translation and not the header + if not entry.obsolete and entry.msgid and not entry.msgid_plural: + entry.msgstr = uppercase_except_braces(entry.msgid) + elif not entry.obsolete and entry.msgid: + # For plural forms + for idx in entry.msgstr_plural: + entry.msgstr_plural[idx] = uppercase_except_braces(entry.msgid_plural) + +po.save(f"{sys.argv[2]}") +print(f"Updated file written to {sys.argv[2]}")