summaryrefslogtreecommitdiffstats
path: root/solenv/bin/desktop-translate.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /solenv/bin/desktop-translate.py
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'solenv/bin/desktop-translate.py')
-rw-r--r--solenv/bin/desktop-translate.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/solenv/bin/desktop-translate.py b/solenv/bin/desktop-translate.py
new file mode 100644
index 000000000..639fa89af
--- /dev/null
+++ b/solenv/bin/desktop-translate.py
@@ -0,0 +1,167 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+#
+# Translates multiple .desktop files at once with strings from .ulf
+# files; if you add new translatable .ulf files please add them to
+# l10ntools/source/localize.cxx
+#
+
+import os, sys, argparse, io
+
+def encodeDesktopString(s):
+ # <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html#
+ # value-types> says "The escape sequences \s, \n, \t, \r, and \\ are supported for values of
+ # type string and localestring, meaning ASCII space, newline, tab, carriage return, and
+ # backslash, respectively." <https://specifications.freedesktop.org/desktop-entry-spec/
+ # desktop-entry-spec-1.1.html#basic-format> says "A file is interpreted as a series of lines
+ # that are separated by linefeed characters", so it is apparently necessary to escape at least
+ # linefeed and backslash characters. It is unclear why that spec talks about "linefeed" in
+ # one place and about "newline" ("\n") and "carriage return" ("\r") in another, and how they are
+ # supposed to relate, so just escape any U+000A LINE FEED as "\n" and any U+000D CARRIAGE RETURN
+ # as "\r"; it is unclear exactly which occurrences of U+0020 SPACE and U+0009 CHARACTER
+ # TABULATION would need to be escaped, so they are mostly left unescaped, for readability:
+ s = s.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r');
+ if s.startswith(' '):
+ # <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html#
+ # entries> says "Space before and after the equals sign should be ignored", so escape a
+ # leading U+0020 SPACE as "\s" (while it is not clear whether "space" there means just
+ # U+0020 SPACE or any kind of white space, in which case at least a leading U+0009 CHARACTER
+ # TABULATION should similarly be escaped as "\t"; also, it is unclear whether such
+ # characters should also be escaped at the end):
+ s = '\\s' + s[1:]
+ return s
+
+parser = argparse.ArgumentParser()
+parser.add_argument('-p', dest='productname', default='LibreOffice')
+parser.add_argument('-d', dest='workdir', default='.')
+parser.add_argument('--key', dest='key')
+parser.add_argument('--prefix', dest='prefix', default='')
+parser.add_argument('--ext', dest='ext')
+parser.add_argument('--template-dir', dest='template_dir', default=None)
+parser.add_argument('ifile')
+
+o = parser.parse_args()
+
+if o.template_dir is None:
+ template_dir = '{}/{}'.format(o.workdir, o.prefix)
+else:
+ template_dir = o.template_dir
+
+# hack for unity section
+if o.key == "UnityQuickList":
+ outkey = "Name"
+else:
+ outkey = o.key
+
+
+templates = {}
+
+# open input file
+source = io.open(o.ifile, encoding='utf-8')
+
+template = None
+
+# read ulf file
+for line in source:
+ if line.strip() == '':
+ continue
+ if line[0] == "[":
+ template = line.split(']', 1)[0][1:]
+ entry = {}
+ # For every section in the specified ulf file there should exist
+ # a template file in $workdir ..
+ entry['outfile'] = "{}{}.{}".format(template_dir, template, o.ext)
+ entry['translations'] = {}
+ templates[template] = entry
+ else:
+ # split locale = "value" into 2 strings
+ if ' = ' not in line:
+ continue
+ locale, value = line.split(' = ')
+
+ if locale != line:
+ # replace en-US with en
+ locale = locale.replace('en-US', 'en')
+
+ # use just anything inside the ""
+ assert(value[0] == '"')
+ # Some entries span multiple lines.
+ # An entry will always end on a double quote.
+ while not value.endswith('"\n'):
+ value += source.readline()
+ value = value[1:-2]
+
+ # replace resource placeholder
+ value = value.replace('%PRODUCTNAME', o.productname)
+
+ locale = locale.replace('-', '_')
+
+ templates[template]['translations'][locale] = value
+
+source.close()
+
+processed = 0
+# process templates
+for template in templates:
+ outfilename = templates[template]['outfile']
+
+ # open the template file - ignore sections for which no
+ # templates exist
+ try:
+ template_file = io.open(outfilename, encoding='utf-8')
+ except Exception:
+ # string files processed one by one
+ if o.ext == 'str':
+ continue
+ sys.exit("Warning: No template found for item '{}' : '{}' : '{}': $!\n".format(template, outfile, line))
+ processed += 1
+
+ # open output file
+ tmpfilename = '{}.tmp'.format(outfilename)
+ outfile = io.open(tmpfilename, 'w', encoding='utf-8')
+
+ # emit the template to the output file
+ for line in template_file:
+ keyline = line
+ if keyline.startswith(o.key):
+ keyline = outkey + keyline[len(o.key):]
+ outfile.write(keyline)
+ if o.key in line:
+ translations = templates[template]['translations']
+ for locale in sorted (translations.keys()):
+ value = translations.get(locale, None)
+ # print "locale is $locale\n";
+ # print "value is $value\n";
+ if value:
+ if o.ext == "desktop" or o.ext == "str":
+ if o.ext == "desktop":
+ value = encodeDesktopString(value)
+ outfile.write(u"""{}[{}]={}\n""".format(outkey, locale, value))
+ else:
+ outfile.write(u"""\t[{}]{}={}\n""".format(locale, outkey, value))
+
+ template_file.close()
+
+ outfile.close()
+ if os.path.exists(outfilename):
+ os.unlink(outfilename)
+ os.rename(tmpfilename, outfilename)
+
+if o.ext == 'str' and processed == 0:
+ sys.exit("Warning: No matching templates processed")