Skip to content

Instantly share code, notes, and snippets.

@javmarina
Last active September 22, 2020 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save javmarina/3a334160dffd1d511c785d1e71b3c595 to your computer and use it in GitHub Desktop.
Save javmarina/3a334160dffd1d511c785d1e71b3c595 to your computer and use it in GitHub Desktop.
AndroidStringsXmlPrettifier: use the same structure and order as values/strings.xml for all the translations.
import os
import platform
import xml.etree.ElementTree as ET
class CommentedTreeBuilder(ET.TreeBuilder):
def comment(self, data):
self.start(ET.Comment, {})
self.data(data)
self.end(ET.Comment)
def get_android_studio_projects_folder():
if platform.system() == "Windows":
return r"C:\Users\{}\AndroidStudioProjects".format(os.getlogin())
else:
return os.path.join("home", os.getlogin(), "AndroidStudioProjects")
def process_xml(base_filename, target_filename):
'''
Base refers to the default locale (/values folder) and target refers to the specified locale (/values-xx)
'''
parser = ET.XMLParser(target=CommentedTreeBuilder())
ET.register_namespace("tools", "http://schemas.android.com/tools")
target_tree = ET.parse(target_filename)
target_root = target_tree.getroot()
strings = {}
for child in target_root.findall("string"):
string_name = child.attrib["name"]
if child.get("translatable", default="true") == "false":
print(string_name + " is marked as not-translatable but has a translation in " + target_filename)
strings[string_name] = child.text
plurals = {}
for child in target_root.findall("plurals"):
values = {}
for item in child.findall("item"):
values[item.attrib["quantity"]] = item.text
plurals[child.attrib["name"]] = values
base_tree = ET.parse(base_filename, parser)
base_root = base_tree.getroot()
for child in base_root.findall("string"):
string_name = child.get("name")
if string_name in strings:
if child.get("translatable", default="true") == "false":
print(string_name + " marked as not-translatable but a translation exists")
child.text = strings[string_name]
else:
if child.get("translatable", default="true") == "true":
print(string_name + " is not translated but should be")
base_root.remove(child)
for child in base_root.findall("plurals"):
plural_name = child.get("name")
if child.get("translatable", default="true") == "false":
print("Plurals should always be translatable. " + plural_name + " is not.")
if plural_name in plurals:
if child.get("translatable", default="true") == "false":
print(plural_name + " marked as not-translatable but a translation exists. WARNING: plurals should always be translated!")
# Replace all plurals
for item in child.findall("item"):
child.remove(item)
for key, value in plurals[plural_name].items():
new_element = ET.Element("item")
new_element.set("quantity", key)
new_element.text = value
child.append(new_element)
else:
if child.get("translatable", default="true") == "true":
print(plural_name + " is not translated but should be")
base_root.remove(child)
base_tree.write(target_filename, encoding="utf-8", xml_declaration=True, method="xml")
def main():
default_folder = get_android_studio_projects_folder()
print("Selected Android Studio projects folder: " + default_folder)
response = input("Is it correct? (Y/N) ")
if response.lower() == "y":
folder = default_folder
else:
folder = input("Please write the folder location: ")
project_name = input("Write the project name: ")
module_name = input("Write the module name: ")
res_path = os.path.join(folder, project_name, module_name, "src", "main", "res")
base_xml = os.path.join(res_path, "values", "strings.xml")
iso_code = input("Introduce the ISO code of the language: ")
target_xml = os.path.join(res_path, "values-" + iso_code.lower(), "strings.xml")
process_xml(base_xml, target_xml)
print("Done! Press any key to exit. You might need to adjust the modified file (" + target_xml + ")")
input() # pause
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment