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).
Expand
#!/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 + 'en-GB/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 + 'en-GB/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
functions['Err:'] = {}
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 + '/sc/messages.po', 'r') as m:
lines = m.readlines()
for i in range(len(lines)):
if lines[i].find('msgid "Err:"') >= 0:
tr_name = lines[i+1].rsplit('"', 2)[1]
if len(tr_name) > 0 and tr_name != 'Err:':
functions['Err:'][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)