#!/usr/bin/env python3 # This script generates dists/org.scummvm.scummvm.metainfo.xml file with multilanguage support. # The multilanguage data is extracted from po/*.po files import re import os import xml.sax.saxutils METAINFO_OUTPUT_FILE = 'dists/org.scummvm.scummvm.metainfo.xml' METAINFO_XML_TEMPLATE = ''' org.scummvm.scummvm CC0-1.0 GPL-3.0-or-later ScummVM Interpreter for numerous adventure games and role-playing games I18N: One line summary as shown in *nix distributions The ScummVM Team org.scummvm.scummvm.desktop scummvm

ScummVM is a program which allows you to run a wide variety of classic graphical point-and-click adventure games and role-playing games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the game, allowing you to play them on systems for which they were never designed!

I18N: 1 of 3 paragraph of ScummVM description in *nix distributions

Currently, ScummVM supports a huge library of adventures with over 250 games in total. It supports many classics published by legendary studios like LucasArts, Sierra On-Line, Revolution Software, Cyan, Inc. and Westwood Studios.

I18N: 2 of 3 paragraph of ScummVM description in *nix distributions

Next to ground-breaking titles like the Monkey Island series, Broken Sword, Myst, Blade Runner and countless other games you will find some really obscure adventures and truly hidden gems to explore.

I18N: 3 of 3 paragraph of ScummVM description in *nix distributions

https://www.scummvm.org/frs/extras/storefront/screenshots/screenshot_1.png ScummVM Launcher https://www.scummvm.org/frs/extras/storefront/screenshots/screenshot_2.png ScummVM running 'Flight of the Amazon Queen' https://www.scummvm.org/frs/extras/storefront/screenshots/screenshot_3.png ScummVM running 'Beneath a Steel Sky' https://www.scummvm.org/frs/extras/storefront/screenshots/screenshot_4.png ScummVM running 'The Curse of Monkey Island' https://www.scummvm.org/frs/extras/storefront/screenshots/screenshot_5.png ScummVM running a demo of 'Myst' https://www.scummvm.org scummvm-devel@lists.scummvm.org none none none none none none none none none none none none none none none none none none none none none none none none none none none
''' SUMMARY_TAG = 'dists/org.scummvm.scummvm.metainfo.xml.cpp:32' SUMMARY_PAT = r' I18N: One line summary as shown in *nix distributions' PAR_TAGS = [ 'dists/org.scummvm.scummvm.metainfo.xml.cpp:37', # Paragraph 1 'dists/org.scummvm.scummvm.metainfo.xml.cpp:45', # Paragraph 2 'dists/org.scummvm.scummvm.metainfo.xml.cpp:51', # Paragraph 3 ] PAR_PATS = [ r'

I18N: 1 of 3 paragraph of ScummVM description in *nix distributions

', r'

I18N: 2 of 3 paragraph of ScummVM description in *nix distributions

', r'

I18N: 3 of 3 paragraph of ScummVM description in *nix distributions

', ] BASE_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..')) def extract_po_line(file, tag): with open(os.path.join(BASE_PATH, 'po', file), 'r') as f: content = f.read() pattern = r'#: {0}\nmsgid ".+"\nmsgstr "(.+)"\n'.format(re.escape(tag)) line_match = re.search(pattern, content) if line_match: return line_match.group(1) else: return None def extract_po_par(file, tag): with open(os.path.join(BASE_PATH, 'po', file), 'r') as f: content = f.read() pattern = r'#: {0}\nmsgid ""\n(?:".*"\n)+msgstr ""\n((?:".+"\n)+)'.format(re.escape(tag)) par_match = re.search(pattern, content) if par_match: par = par_match.group(1) # Remove trailing \n par = par[:-1] # Remove quotes at start and end of line return [line[1:-1] for line in par.split('\n')] else: return None def po_to_lang(po_file_name): # Remove .po extension lang = po_file_name[:-3] region_subtag = None variant_subtag = None # we use - for locale modifier (tarask) if '-' in lang: lang, variant_subtag = lang.split('-', maxsplit=1) if '_' in lang: lang, region_subtag = lang.split('_', maxsplit=1) primary_subtag = lang assert(len(primary_subtag) == 2) assert(region_subtag is None or len(region_subtag) == 2) assert(variant_subtag is None or 6 <= len(variant_subtag) <= 8) lang = primary_subtag.lower() if region_subtag: lang += '-' + region_subtag.upper() if variant_subtag: lang += '-' + variant_subtag.lower() return primary_subtag, lang def get_summary_translations(po_file_names): summary_translations = [] for file, lang in po_file_names.items(): summary = extract_po_line(file, SUMMARY_TAG) if summary is None: continue summary = xml.sax.saxutils.escape(summary) summary_translations.append(' {1}'.format( lang, summary)) return '\n'.join(summary_translations) def substitute_summary_translations(po_file_names, xml): summary_translations = get_summary_translations(po_file_names) return xml.replace(SUMMARY_PAT, summary_translations) def get_parx_translations(po_file_names, tag): parx_translations = [] for file, lang in po_file_names.items(): parx = extract_po_par(file, tag) if parx is None: continue # In XML a newline will be replace by a space character # Join everything making it pretty and remove trailing spaces parx = '\n'.join(line.rstrip(' ') for line in parx) parx = xml.sax.saxutils.escape(parx) parx_translations.append('

{1}

'.format(lang, parx)) return '\n'.join(parx_translations) def substitute_parx_translations(po_file_names, xml): for tag, pat in zip(PAR_TAGS, PAR_PATS): parx_translations = get_parx_translations(po_file_names, tag) xml = xml.replace(pat, parx_translations) return xml def get_po_files(): po_file_names = [] for filename in os.listdir(os.path.join(BASE_PATH, 'po')): if filename.endswith(".po"): po_file_names.append(filename) po_file_names.sort() po_langs = {} last_primary = None last_file = None for file in po_file_names: primary_subtag, lang = po_to_lang(file) if last_primary != primary_subtag: # We are sorted so it's a new primary group last_primary = primary_subtag did_dedup = False # Try with primary subtag first po_langs[file] = primary_subtag else: if not did_dedup: # Fix last file name because we have duplicate po_langs[last_file] = po_to_lang(last_file)[1] did_dedup = True # We got a duplicate lang code: deduplicate po_langs[file] = lang last_file = file return po_langs def main(): po_file_names = get_po_files() xml = substitute_summary_translations( po_file_names, METAINFO_XML_TEMPLATE) xml = substitute_parx_translations(po_file_names, xml) with open(os.path.join(BASE_PATH, METAINFO_OUTPUT_FILE), 'w') as f: f.write(xml) if __name__ == '__main__': main()