Module:Calc fn name
This module is used in Calc function articles to save translator time. It replaces an English Calc function name with its translation automatically according to the language of the article.
The Python script used to extract the translated function names is included below (click expand to see it).
#!/usr/bin/env python3 # # Script for extracting translated Calc function names from LibreOffice # .po files and outputting a Lua table that can be used in a wiki module. # The Lua output depends on https://github.com/SirAnthony/slpp # Also outputs a JSON list of English function names sorted from longest # to shortest, with single character names omitted. The list is used with # a Firefox Greasemonkey script to replace function names with # the wiki module invocation. import json import sys import slpp from pathlib import Path if len(sys.argv) != 2: sys.exit('Please give argument for the location of translations/source/ with trailing slash, example: python function_names_to_json.py /home/user/libreoffice/translations/source/') translations = sys.argv[1] if not Path(translations).exists(): sys.exit('Error: the directory does not exist.') if not translations.endswith('/'): sys.exit('Error: no trailing slash in path.') functions = {} class LuaSpaces(slpp.SLPP): def __init__(self): slpp.SLPP.__init__(self) self.tab = ' ' def suffix(fn_name): if fn_name in ['CUMIPMT', 'CUMPRINC', 'EFFECT', 'NOMINAL', 'ISEVEN', 'ISODD' ]: return '_ADD' elif fn_name in ['GCD', 'LCM', 'NETWORKDAYS', 'WEEKNUM']: return '_EXCEL2003' return '' with open(translations + 'ab/formula/messages.po', 'r') as m: lines = m.readlines() for i in range(len(lines)): if lines[i].find('formula/inc/core_resource.hrc') >= 0: fn_name = lines[i+2].rsplit('"', 2)[1] # we want even the error strings, but not the ones that have lowercase letters if fn_name.isupper(): functions[fn_name] = {} i += 3 with open(translations + 'ab/scaddins/messages.po', 'r') as m: lines = m.readlines() for i in range(len(lines)): if lines[i].find('scaddins/inc/strings.hrc') >= 0: fn_name = lines[i+2].rsplit('"', 2)[1] fn_name += suffix(fn_name) functions[fn_name] = {} i += 3 fn_names = functions.keys() basepath = Path(translations) for entry in sorted(basepath.iterdir()): if entry.is_dir(): with open(translations + entry.name + '/formula/messages.po', 'r') as m: lines = m.readlines() for fn_name in fn_names: for i in range(len(lines)): if lines[i].find('msgid "' + fn_name + '"') >= 0: tr_name = lines[i+1].rsplit('"', 2)[1] if len(tr_name) > 0 and tr_name != fn_name: functions[fn_name][entry.name.lower()] = tr_name with open(translations + entry.name + '/scaddins/messages.po', 'r') as m: lines = m.readlines() for fn_name in fn_names: for i in range(len(lines)): if lines[i].find('scaddins/inc/strings.hrc') >= 0 and lines[i+2].find('msgid "' + fn_name + '"') >= 0: add_suffix = suffix(fn_name) fn_name += add_suffix tr_name = lines[i+3].rsplit('"', 2)[1] if len(tr_name) > 0 and tr_name != fn_name: functions[fn_name][entry.name.lower()] = tr_name + add_suffix names_for_js = [x.replace("?", "\\?") for x in list(fn_names) if len(x)>1] names_for_js.sort(key=len, reverse=True) as_json = json.dumps(names_for_js, indent=4, ensure_ascii=False) as_lua = LuaSpaces().encode(functions) with open('calc_function_names.js', 'w') as f: f.write(as_json) with open('calc_function_name_translations.lua', 'w') as f: f.write(as_lua)
-- Invoke from a wrapper template like so: -- {{#invoke:Calc_fn_name|main}} -- Pass arguments to template like so: -- {{Calc_fn_name|IF|{{PAGELANGUAGE}}}} -- Hopefully in the future we don't have to pass the language argument: -- https://phabricator.wikimedia.org/T161976 local p = {}; local function get_fn_name( frame ) local fn_names = mw.loadData( 'Module:Calc_fn_name/data' ) local fn_name = frame:getParent().args[1] local lang = frame:getParent().args[2] if not lang or lang == '' then return fn_name end local tr_name = fn_names[fn_name][lang] if not tr_name or tr_name == '' then tr_name = fn_name end -- have to escape # chars or they will be rendered as ordered lists! local tr_name_escaped = string.gsub( tr_name, "#", "#" ) return tr_name_escaped end function p.main( frame ) return get_fn_name( frame ) end return p