3 # Copyright (C) 2022 Wildfire Games.
4 # This file is part of 0 A.D.
6 # 0 A.D. is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 2 of the License, or
9 # (at your option) any later version.
11 # 0 A.D. is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
22 import multiprocessing
24 from i18n_helper
import l10nFolderName
, projectRootDirectory
25 from i18n_helper
.catalog
import Catalog
26 from i18n_helper
.globber
import getCatalogs
32 def generate_long_strings(root_path
, input_file_name
, output_file_name
, languages
=None):
34 Generate the 'long strings' debug catalog.
35 This catalog contains the longest singular and plural string,
36 found amongst all translated languages or a filtered subset.
37 It can be used to check if GUI elements are large enough.
38 The catalog is long.*.po
40 print("Generating", output_file_name
)
41 input_file_path
= os
.path
.join(root_path
, input_file_name
)
42 output_file_path
= os
.path
.join(root_path
, output_file_name
)
44 template_catalog
= Catalog
.readFrom(input_file_path
)
45 # Pretend we write English to get plurals.
46 long_string_catalog
= Catalog(locale
="en")
48 # Fill catalog with English strings.
49 for message
in template_catalog
:
50 long_string_catalog
.add(
51 id=message
.id, string
=message
.id, context
=message
.context
)
53 # Load existing translation catalogs.
54 existing_translation_catalogs
= getCatalogs(input_file_path
, languages
)
56 # If any existing translation has more characters than the average expansion, use that instead.
57 for translation_catalog
in existing_translation_catalogs
:
58 for long_string_catalog_message
in long_string_catalog
:
59 translation_message
= translation_catalog
.get(
60 long_string_catalog_message
.id, long_string_catalog_message
.context
)
61 if not translation_message
or not translation_message
.string
:
64 if not long_string_catalog_message
.pluralizable
or not translation_message
.pluralizable
:
65 if len(translation_message
.string
) > len(long_string_catalog_message
.string
):
66 long_string_catalog_message
.string
= translation_message
.string
69 longest_singular_string
= translation_message
.string
[0]
70 longest_plural_string
= translation_message
.string
[1 if len(
71 translation_message
.string
) > 1 else 0]
73 candidate_singular_string
= long_string_catalog_message
.string
[0]
74 # There might be between 0 and infinite plural forms.
75 candidate_plural_string
= ""
76 for candidate_string
in long_string_catalog_message
.string
[1:]:
77 if len(candidate_string
) > len(candidate_plural_string
):
78 candidate_plural_string
= candidate_string
81 if len(candidate_singular_string
) > len(longest_singular_string
):
82 longest_singular_string
= candidate_singular_string
84 if len(candidate_plural_string
) > len(longest_plural_string
):
85 longest_plural_string
= candidate_plural_string
89 long_string_catalog_message
.string
= [
90 longest_singular_string
, longest_plural_string
]
91 translation_message
= long_string_catalog_message
92 long_string_catalog
.writeTo(output_file_path
)
95 def generate_debug(root_path
, input_file_name
, output_file_name
):
97 Generate a debug catalog to identify untranslated strings.
98 This prefixes all strings with DEBUG_PREFIX, to easily identify
99 untranslated strings while still making the game navigable.
100 The catalog is debug.*.po
102 print("Generating", output_file_name
)
103 input_file_path
= os
.path
.join(root_path
, input_file_name
)
104 output_file_path
= os
.path
.join(root_path
, output_file_name
)
106 template_catalog
= Catalog
.readFrom(input_file_path
)
107 # Pretend we write English to get plurals.
108 out_catalog
= Catalog(locale
="en")
110 for message
in template_catalog
:
111 if message
.pluralizable
:
114 string
=(DEBUG_PREFIX
+ message
.id[0],),
115 context
=message
.context
)
119 string
=DEBUG_PREFIX
+ message
.id,
120 context
=message
.context
)
122 out_catalog
.writeTo(output_file_path
)
126 parser
= argparse
.ArgumentParser()
127 parser
.add_argument("--debug",
128 help="Generate debug localisation to identify non-translated strings.",
130 parser
.add_argument("--long",
131 help="Generate 'long strings' localisation to identify GUI elements too small.",
133 parser
.add_argument("--languages",
135 help="For long strings, restrict to these languages")
136 args
= parser
.parse_args()
138 if not args
.debug
and not args
.long:
143 for root
, _
, filenames
in os
.walk(projectRootDirectory
):
144 for filename
in filenames
:
145 if len(filename
) > 4 and filename
[-4:] == ".pot" and os
.path
.basename(root
) == l10nFolderName
:
148 multiprocessing
.Process(
149 target
=generate_debug
,
150 args
=(root
, filename
, "debug." + filename
[:-1])
153 multiprocessing
.Process(
154 target
=generate_long_strings
,
155 args
=(root
, filename
, "long." +
156 filename
[:-1], args
.languages
)
159 if found_pot_files
== 0:
160 print("This script did not work because no ‘.pot’ files were found. "
161 "Please, run ‘updateTemplates.py’ to generate the ‘.pot’ files, and run ‘pullTranslations.py’ to pull the latest translations from Transifex. "
162 "Then you can run this script to generate ‘.po’ files with obvious debug strings.")
165 if __name__
== "__main__":