Index: ps/trunk/source/tools/i18n/generateDebugTranslation.py
===================================================================
--- ps/trunk/source/tools/i18n/generateDebugTranslation.py
+++ ps/trunk/source/tools/i18n/generateDebugTranslation.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 Wildfire Games.
+# This file is part of 0 A.D.
+#
+# 0 A.D. is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# 0 A.D. is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with 0 A.D. If not, see .
+
+import argparse
+import os
+import sys
+import multiprocessing
+
+from i18n_helper import projectRootDirectory
+from i18n_helper.catalog import Catalog
+from i18n_helper.globber import getCatalogs
+
+
+DEBUG_PREFIX = 'X_X '
+
+
+def generate_long_strings(root_path, input_file_name, output_file_name, languages=None):
+ """
+ Generate the 'long strings' debug catalog.
+ This catalog contains the longest singular and plural string,
+ found amongst all translated languages or a filtered subset.
+ It can be used to check if GUI elements are large enough.
+ The catalog is long.*.po
+ """
+ print("Generating", output_file_name)
+ input_file_path = os.path.join(root_path, input_file_name)
+ output_file_path = os.path.join(root_path, output_file_name)
+
+ template_catalog = Catalog.readFrom(input_file_path)
+ # Pretend we write English to get plurals.
+ long_string_catalog = Catalog(locale="en")
+
+ # Fill catalog with English strings.
+ for message in template_catalog:
+ long_string_catalog.add(
+ id=message.id, string=message.id, context=message.context)
+
+ # Load existing translation catalogs.
+ existing_translation_catalogs = getCatalogs(input_file_path, languages)
+
+ # If any existing translation has more characters than the average expansion, use that instead.
+ for translation_catalog in existing_translation_catalogs:
+ for long_string_catalog_message in long_string_catalog:
+ translation_message = translation_catalog.get(
+ long_string_catalog_message.id, long_string_catalog_message.context)
+ if not translation_message or not translation_message.string:
+ continue
+
+ if not long_string_catalog_message.pluralizable or not translation_message.pluralizable:
+ if len(translation_message.string) > len(long_string_catalog_message.string):
+ long_string_catalog_message.string = translation_message.string
+ continue
+
+ longest_singular_string = translation_message.string[0]
+ longest_plural_string = translation_message.string[1 if len(
+ translation_message.string) > 1 else 0]
+
+ candidate_singular_string = long_string_catalog_message.string[0]
+ # There might be between 0 and infinite plural forms.
+ candidate_plural_string = ""
+ for candidate_string in long_string_catalog_message.string[1:]:
+ if len(candidate_string) > len(candidate_plural_string):
+ candidate_plural_string = candidate_string
+
+ changed = False
+ if len(candidate_singular_string) > len(longest_singular_string):
+ longest_singular_string = candidate_singular_string
+ changed = True
+ if len(candidate_plural_string) > len(longest_plural_string):
+ longest_plural_string = candidate_plural_string
+ changed = True
+
+ if changed:
+ long_string_catalog_message.string = [
+ longest_singular_string, longest_plural_string]
+ translation_message = long_string_catalog_message
+ long_string_catalog.writeTo(output_file_path)
+
+
+def generate_debug(root_path, input_file_name, output_file_name):
+ """
+ Generate a debug catalog to identify untranslated strings.
+ This prefixes all strings with DEBUG_PREFIX, to easily identify
+ untranslated strings while still making the game navigable.
+ The catalog is debug.*.po
+ """
+ print("Generating", output_file_name)
+ input_file_path = os.path.join(root_path, input_file_name)
+ output_file_path = os.path.join(root_path, output_file_name)
+
+ template_catalog = Catalog.readFrom(input_file_path)
+ # Pretend we write English to get plurals.
+ out_catalog = Catalog(locale="en")
+
+ for message in template_catalog:
+ if message.pluralizable:
+ out_catalog.add(
+ id=message.id,
+ string=(DEBUG_PREFIX + message.id[0],),
+ context=message.context)
+ else:
+ out_catalog.add(
+ id=message.id,
+ string=DEBUG_PREFIX + message.id,
+ context=message.context)
+
+ out_catalog.writeTo(output_file_path)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--debug",
+ help="Generate debug localisation to identify non-translated strings.",
+ action="store_true")
+ parser.add_argument("--long",
+ help="Generate 'long strings' localisation to identify GUI elements too small.",
+ action="store_true")
+ parser.add_argument("--languages",
+ nargs="+",
+ help="For long strings, restrict to these languages")
+ args = parser.parse_args()
+
+ if not args.debug and not args.long:
+ parser.print_help()
+ sys.exit(0)
+
+ found_pot_files = 0
+ for root, _, filenames in os.walk(projectRootDirectory):
+ for filename in filenames:
+ if len(filename) > 4 and filename[-4:] == ".pot" and os.path.basename(root) == "l10n":
+ found_pot_files += 1
+ if args.debug:
+ multiprocessing.Process(
+ target=generate_debug,
+ args=(root, filename, "debug." + filename[:-1])
+ ).start()
+ if args.long:
+ multiprocessing.Process(
+ target=generate_long_strings,
+ args=(root, filename, "long." +
+ filename[:-1], args.languages)
+ ).start()
+
+ if found_pot_files == 0:
+ print("This script did not work because no ‘.pot’ files were found. "
+ "Please, run ‘updateTemplates.py’ to generate the ‘.pot’ files, and run ‘pullTranslations.py’ to pull the latest translations from Transifex. "
+ "Then you can run this script to generate ‘.po’ files with obvious debug strings.")
+
+
+if __name__ == "__main__":
+ main()
Index: ps/trunk/source/tools/i18n/generateLongStringTranslations.py
===================================================================
--- ps/trunk/source/tools/i18n/generateLongStringTranslations.py
+++ ps/trunk/source/tools/i18n/generateLongStringTranslations.py
@@ -1,98 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2020 Wildfire Games.
-# This file is part of 0 A.D.
-#
-# 0 A.D. is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# 0 A.D. is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with 0 A.D. If not, see .
-
-import os, sys
-import multiprocessing
-
-from i18n_helper import l10nToolsDirectory, projectRootDirectory
-from i18n_helper.catalog import Catalog
-from i18n_helper.globber import getCatalogs
-
-l10nFolderName = "l10n"
-
-
-def generateLongStringTranslationFromPotIntoPo(inputFilePath, outputFilePath):
- templateCatalog = Catalog.readFrom(inputFilePath)
- longStringCatalog = Catalog(locale="en") # Pretend we write English to get plurals.
-
- # Fill catalog with English strings.
- for message in templateCatalog:
- longStringCatalog.add(id=message.id, string=message.id, context=message.context)
-
- # If language codes were specified on the command line, filder by those.
- filters = sys.argv[1:]
-
- # Load existing translation catalogs.
- existingTranslationCatalogs = getCatalogs(inputFilePath, filters)
-
- # If any existing translation has more characters than the average expansion, use that instead.
- for translationCatalog in existingTranslationCatalogs:
- for longStringCatalogMessage in longStringCatalog:
- translationMessage = translationCatalog.get(longStringCatalogMessage.id, longStringCatalogMessage.context)
- if not translationMessage or not translationMessage.string:
- continue
-
- if not longStringCatalogMessage.pluralizable or not translationMessage.pluralizable:
- if len(translationMessage.string) > len(longStringCatalogMessage.string):
- longStringCatalogMessage.string = translationMessage.string
- continue
-
- longestSingularString = translationMessage.string[0]
- longestPluralString = translationMessage.string[1 if len(translationMessage.string) > 1 else 0]
-
- candidateSingularString = longStringCatalogMessage.string[0]
- candidatePluralString = "" # There might be between 0 and infinite plural forms.
- for candidateString in longStringCatalogMessage.string[1:]:
- if len(candidateString) > len(candidatePluralString):
- candidatePluralString = candidateString
-
- changed = False
- if len(candidateSingularString) > len(longestSingularString):
- longestSingularString = candidateSingularString
- changed = True
- if len(candidatePluralString) > len(longestPluralString):
- longestPluralString = candidatePluralString
- changed = True
-
- if changed:
- longStringCatalogMessage.string = [longestSingularString, longestPluralString]
- translationMessage = longStringCatalogMessage
- longStringCatalog.writeTo(outputFilePath)
-
-
-def main():
-
- foundPots = 0
- for root, folders, filenames in os.walk(projectRootDirectory):
- for filename in filenames:
- if len(filename) > 4 and filename[-4:] == ".pot" and os.path.basename(root) == "l10n":
- foundPots += 1
- print("Generating", "long." + filename[:-1])
- multiprocessing.Process(
- target=generateLongStringTranslationFromPotIntoPo,
- args=(os.path.join(root, filename), os.path.join(root, "long." + filename[:-1]))
- ).start()
-
- if foundPots == 0:
- print("This script did not work because no ‘.pot’ files were found. "
- "Please, run ‘updateTemplates.py’ to generate the ‘.pot’ files, and run ‘pullTranslations.py’ to pull the latest translations from Transifex. "
- "Then you can run this script to generate ‘.po’ files with the longest strings.")
-
-
-if __name__ == "__main__":
- main()
Index: ps/trunk/source/tools/i18n/i18n_helper/globber.py
===================================================================
--- ps/trunk/source/tools/i18n/i18n_helper/globber.py
+++ ps/trunk/source/tools/i18n/i18n_helper/globber.py
@@ -4,8 +4,8 @@
from i18n_helper.catalog import Catalog
-def getCatalogs(inputFilePath, filters = None) -> List[Catalog]:
- """Returns a list of "real" catalogs (.po) in the fiven folder."""
+def getCatalogs(inputFilePath, filters : List[str] = None) -> List[Catalog]:
+ """Returns a list of "real" catalogs (.po) in the given folder."""
existingTranslationCatalogs = []
l10nFolderPath = os.path.dirname(inputFilePath)
inputFileName = os.path.basename(inputFilePath)