Index: ps/trunk/source/tools/i18n/generateLongStringTranslations.py =================================================================== --- ps/trunk/source/tools/i18n/generateLongStringTranslations.py (revision 24965) +++ ps/trunk/source/tools/i18n/generateLongStringTranslations.py (nonexistent) @@ -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() Property changes on: ps/trunk/source/tools/i18n/generateLongStringTranslations.py ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/source/tools/i18n/generateDebugTranslation.py =================================================================== --- ps/trunk/source/tools/i18n/generateDebugTranslation.py (nonexistent) +++ ps/trunk/source/tools/i18n/generateDebugTranslation.py (revision 24966) @@ -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() Property changes on: ps/trunk/source/tools/i18n/generateDebugTranslation.py ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: ps/trunk/source/tools/i18n/i18n_helper/globber.py =================================================================== --- ps/trunk/source/tools/i18n/i18n_helper/globber.py (revision 24965) +++ ps/trunk/source/tools/i18n/i18n_helper/globber.py (revision 24966) @@ -1,22 +1,22 @@ """Utils to list .po""" import os from typing import List 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) for filename in os.listdir(str(l10nFolderPath)): if filename.startswith("long") or not filename.endswith(".po"): continue if filename.split(".")[1] != inputFileName.split(".")[0]: continue if not filters or filename.split(".")[0] in filters: existingTranslationCatalogs.append( Catalog.readFrom(os.path.join(l10nFolderPath, filename), locale=filename.split('.')[0])) return existingTranslationCatalogs