mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-23 21:19:58 +08:00
Move translation scripts to Cura from Uranium
CURA-9814
This commit is contained in:
parent
24cb9e16a8
commit
20778f3d10
103
scripts/translations/createjsoncontext.py
Normal file
103
scripts/translations/createjsoncontext.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright 2014 Burkhard Lück <lueck@hube-lueck.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software
|
||||||
|
and its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name of the author not be used in
|
||||||
|
advertising or publicity pertaining to distribution of the
|
||||||
|
software without specific, written prior permission.
|
||||||
|
|
||||||
|
The author disclaim all warranties with regard to this
|
||||||
|
software, including all implied warranties of merchantability
|
||||||
|
and fitness. In no event shall the author be liable for any
|
||||||
|
special, indirect or consequential damages or any damages
|
||||||
|
whatsoever resulting from loss of use, data or profits, whether
|
||||||
|
in an action of contract, negligence or other tortious action,
|
||||||
|
arising out of or in connection with the use or performance of
|
||||||
|
this software.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# This script generates a POT file from a JSON settings file. It
|
||||||
|
# has been adapted from createjsoncontext.py of KDE's translation
|
||||||
|
# scripts. It extracts the "label" and "description" values of
|
||||||
|
# the JSON file using the structure as used by Uranium settings files.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import os.path
|
||||||
|
import collections
|
||||||
|
|
||||||
|
debugoutput = False #set True to print debug output in scripty's logs
|
||||||
|
|
||||||
|
basedir = sys.argv[-1]
|
||||||
|
pottxt = ""
|
||||||
|
|
||||||
|
def appendMessage(file, setting, field, value):
|
||||||
|
global pottxt
|
||||||
|
pottxt += "#: {0}\nmsgctxt \"{1} {2}\"\nmsgid \"{3}\"\nmsgstr \"\"\n\n".format(file, setting, field, value.replace("\n", "\\n").replace("\"", "\\\""))
|
||||||
|
|
||||||
|
def processSettings(file, settings):
|
||||||
|
for name, value in settings.items():
|
||||||
|
appendMessage(file, name, "label", value["label"])
|
||||||
|
if "description" in value:
|
||||||
|
appendMessage(file, name, "description", value["description"])
|
||||||
|
|
||||||
|
if "warning_description" in value:
|
||||||
|
appendMessage(file, name, "warning_description", value["warning_description"])
|
||||||
|
|
||||||
|
if "error_description" in value:
|
||||||
|
appendMessage(file, name, "error_description", value["error_description"])
|
||||||
|
|
||||||
|
if "options" in value:
|
||||||
|
for item, description in value["options"].items():
|
||||||
|
appendMessage(file, name, "option {0}".format(item), description)
|
||||||
|
|
||||||
|
if "children" in value:
|
||||||
|
processSettings(file, value["children"])
|
||||||
|
|
||||||
|
def potheader():
|
||||||
|
headertxt = "#, fuzzy\n"
|
||||||
|
headertxt += "msgid \"\"\n"
|
||||||
|
headertxt += "msgstr \"\"\n"
|
||||||
|
headertxt += "\"Project-Id-Version: Uranium json setting files\\n\"\n"
|
||||||
|
headertxt += "\"Report-Msgid-Bugs-To: plugins@ultimaker.com\\n\"\n"
|
||||||
|
headertxt += "\"POT-Creation-Date: %s+0000\\n\"\n" %time.strftime("%Y-%m-%d %H:%M")
|
||||||
|
headertxt += "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n"
|
||||||
|
headertxt += "\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n"
|
||||||
|
headertxt += "\"Language-Team: LANGUAGE\\n\"\n"
|
||||||
|
headertxt += "\"MIME-Version: 1.0\\n\"\n"
|
||||||
|
headertxt += "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
|
||||||
|
headertxt += "\"Content-Transfer-Encoding: 8bit\\n\"\n"
|
||||||
|
headertxt += "\n"
|
||||||
|
return headertxt
|
||||||
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("wrong number of args: %s" % sys.argv)
|
||||||
|
print("\nUsage: python %s jsonfilenamelist basedir" % os.path.basename(sys.argv[0]))
|
||||||
|
else:
|
||||||
|
jsonfilename = sys.argv[1]
|
||||||
|
basedir = sys.argv[2]
|
||||||
|
outputfilename = sys.argv[3]
|
||||||
|
|
||||||
|
with open(jsonfilename, "r", encoding = "utf-8") as data_file:
|
||||||
|
error = False
|
||||||
|
|
||||||
|
jsondatadict = json.load(data_file, object_pairs_hook=collections.OrderedDict)
|
||||||
|
if "settings" not in jsondatadict:
|
||||||
|
print("No settings item found, nothing to translate")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
processSettings(jsonfilename.replace(basedir, ""), jsondatadict["settings"])
|
||||||
|
|
||||||
|
if pottxt != "":
|
||||||
|
with open(outputfilename, "w", encoding = "utf-8") as output_file:
|
||||||
|
output_file.write(potheader())
|
||||||
|
output_file.write(pottxt)
|
47
scripts/translations/createkeypair.py
Normal file
47
scripts/translations/createkeypair.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from typing import Optional
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from UM.Trust import TrustBasics
|
||||||
|
|
||||||
|
# Default arguments, if arguments to the script are omitted, these values are used:
|
||||||
|
DEFAULT_PRIVATE_KEY_PATH = "./private_key.pem"
|
||||||
|
DEFAULT_PUBLIC_KEY_PATH = "./public_key.pem"
|
||||||
|
DEFAULT_PASSWORD = ""
|
||||||
|
|
||||||
|
|
||||||
|
def createAndStoreNewKeyPair(private_filename: str, public_filename: str, optional_password: Optional[str]) -> None:
|
||||||
|
"""Creates a new public and private key, and saves them to the provided filenames.
|
||||||
|
|
||||||
|
See also 'Trust.py' in the main library and the related scripts; 'signfile.py', 'signfolder.py' in this folder.
|
||||||
|
|
||||||
|
:param private_filename: Filename to save the private key to.
|
||||||
|
:param public_filename: Filename to save the public key to.
|
||||||
|
:param optional_password: Private keys can have a password (or not).
|
||||||
|
"""
|
||||||
|
|
||||||
|
password = None if optional_password == "" else optional_password
|
||||||
|
private_key, public_key = TrustBasics.generateNewKeyPair()
|
||||||
|
TrustBasics.saveKeyPair(private_key, private_filename, public_filename, password)
|
||||||
|
|
||||||
|
|
||||||
|
def mainfunc():
|
||||||
|
"""Arguments:
|
||||||
|
|
||||||
|
`-k <filename>` or `--private <filename>` will store the generated private key to <filename>
|
||||||
|
`-p <filename>` or `--public <filename>` will store the generated public key to <filename>
|
||||||
|
`-w <password>` or `--password <password>` will give the private key a password (none if omitted, which is default)
|
||||||
|
"""
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("-k", "--private", type = str, default = DEFAULT_PRIVATE_KEY_PATH)
|
||||||
|
parser.add_argument("-p", "--public", type = str, default = DEFAULT_PUBLIC_KEY_PATH)
|
||||||
|
parser.add_argument("-w", "--password", type = str, default = DEFAULT_PASSWORD)
|
||||||
|
args = parser.parse_args()
|
||||||
|
createAndStoreNewKeyPair(args.private, args.public, args.password)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(mainfunc())
|
72
scripts/translations/createplugincontext.py
Normal file
72
scripts/translations/createplugincontext.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright 2014 Burkhard Lück <lueck@hube-lueck.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software
|
||||||
|
and its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name of the author not be used in
|
||||||
|
advertising or publicity pertaining to distribution of the
|
||||||
|
software without specific, written prior permission.
|
||||||
|
|
||||||
|
The author disclaim all warranties with regard to this
|
||||||
|
software, including all implied warranties of merchantability
|
||||||
|
and fitness. In no event shall the author be liable for any
|
||||||
|
special, indirect or consequential damages or any damages
|
||||||
|
whatsoever resulting from loss of use, data or profits, whether
|
||||||
|
in an action of contract, negligence or other tortious action,
|
||||||
|
arising out of or in connection with the use or performance of
|
||||||
|
this software.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# This script generates a POT file from a JSON settings file. It
|
||||||
|
# has been adapted from createjsoncontext.py of KDE's translation
|
||||||
|
# scripts. It extracts the "label" and "description" values of
|
||||||
|
# the JSON file using the structure as used by Uranium settings files.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os.path
|
||||||
|
import collections
|
||||||
|
import json
|
||||||
|
|
||||||
|
debugoutput = False #set True to print debug output in scripty's logs
|
||||||
|
|
||||||
|
basedir = sys.argv[-1]
|
||||||
|
pottxt = ""
|
||||||
|
|
||||||
|
|
||||||
|
def appendMessage(file, field, value):
|
||||||
|
global pottxt
|
||||||
|
pottxt += "#: {0}\nmsgctxt \"{1}\"\nmsgid \"{2}\"\nmsgstr \"\"\n\n".format(file, field, value.replace("\n", "\\n").replace("\"", "\\\""))
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("wrong number of args: %s" % sys.argv)
|
||||||
|
print("\nUsage: python %s jsonfilenamelist basedir" % os.path.basename(sys.argv[0]))
|
||||||
|
else:
|
||||||
|
json_filename = sys.argv[1]
|
||||||
|
basedir = sys.argv[2]
|
||||||
|
output_filename = sys.argv[3]
|
||||||
|
|
||||||
|
with open(json_filename, "r", encoding = "utf-8") as data_file:
|
||||||
|
error = False
|
||||||
|
|
||||||
|
jsondatadict = json.load(data_file, object_pairs_hook=collections.OrderedDict)
|
||||||
|
if "name" not in jsondatadict or ("api" not in jsondatadict and "supported_sdk_versions" not in jsondatadict) or "version" not in jsondatadict:
|
||||||
|
print("The plugin.json file found on %s is invalid, ignoring it" % json_filename)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
file = json_filename.replace(basedir, "")
|
||||||
|
|
||||||
|
if "description" in jsondatadict:
|
||||||
|
appendMessage(file, "description", jsondatadict["description"])
|
||||||
|
if "name" in jsondatadict:
|
||||||
|
appendMessage(file, "name", jsondatadict["name"])
|
||||||
|
|
||||||
|
if pottxt != "":
|
||||||
|
with open(output_filename, "a", encoding = "utf-8") as output_file:
|
||||||
|
output_file.write(pottxt)
|
13
scripts/translations/extract-all
Executable file
13
scripts/translations/extract-all
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Use xgettext to extract all strings from a set of python files.
|
||||||
|
# Argument 1 is the directory to search for python files, argument 2
|
||||||
|
# is the destination file.
|
||||||
|
#
|
||||||
|
# This script will extract strings marked using i18n or i18nc methods.
|
||||||
|
# See UM/i18n.py for the relevant methods.
|
||||||
|
#
|
||||||
|
dir=$1
|
||||||
|
dest=$2
|
||||||
|
xgettext --from-code=UTF-8 --language=python -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o $dest $(find -L "$dir" -name \*.py)
|
||||||
|
xgettext --from-code=UTF-8 --join-existing --language=javascript -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o $dest $(find -L "$dir" -name \*.qml)
|
42
scripts/translations/extract-json
Executable file
42
scripts/translations/extract-json
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Extract strings from a list of JSON files.
|
||||||
|
#
|
||||||
|
# This script will extract strings from all JSON files in the directory
|
||||||
|
# passed as first argument. The second argument is the destination
|
||||||
|
# directory for the extracted message file.
|
||||||
|
#
|
||||||
|
# This script uses createjsoncontext to generate the actual message file
|
||||||
|
# from the JSON file.
|
||||||
|
#
|
||||||
|
# This script is based on handle_json_files.sh from KDE's translation
|
||||||
|
# scripts.
|
||||||
|
# handle_json_files.sh is copyright 2014 Burkhard Lück <lueck@hube-lueck.de>
|
||||||
|
scriptdir=$(dirname $0)
|
||||||
|
|
||||||
|
extract() {
|
||||||
|
basedir=$1
|
||||||
|
dest=$2
|
||||||
|
file=$3
|
||||||
|
|
||||||
|
python3 $scriptdir/createjsoncontext.py $file $basedir json.$$.tmp
|
||||||
|
if test $? -eq 1; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Extracted messages from $file"
|
||||||
|
|
||||||
|
msguniq --to-code=UTF-8 -o json.$$ json.$$.tmp
|
||||||
|
if test -f json.$$; then
|
||||||
|
destfile="$dest/$(basename $file).pot"
|
||||||
|
mv json.$$ $destfile
|
||||||
|
fi
|
||||||
|
rm -f json.$$ json.$$.tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
dir=$1; shift
|
||||||
|
dest=$1; shift
|
||||||
|
|
||||||
|
for file in $(find -L "$dir" -name *.json | grep -v 'tests'); do
|
||||||
|
extract $dir $dest $file
|
||||||
|
done
|
42
scripts/translations/extract-messages
Executable file
42
scripts/translations/extract-messages
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
scriptdir=$(dirname $0)
|
||||||
|
basedir=$1
|
||||||
|
catalogname=$2
|
||||||
|
|
||||||
|
# This script processes the source files using several other scripts to extract strings.
|
||||||
|
# The strings are extracted to $basedir/resources/i18n/ and then post processed. After that
|
||||||
|
# It generates english translation files and testing files that are pre- and sufficed with
|
||||||
|
# xx. These can be used by setting the LANGUAGE environment variable to x-test.
|
||||||
|
#
|
||||||
|
# This script uses extract-tr-strings to extract strings from QML files, extract-json to
|
||||||
|
# extract strings from JSON files and extract-python to extract strings from Python files.
|
||||||
|
#
|
||||||
|
mkdir -p $basedir/resources/i18n
|
||||||
|
$scriptdir/extract-json $basedir/resources/definitions/ $basedir/resources/i18n
|
||||||
|
$scriptdir/extract-all $basedir $basedir/resources/i18n/$catalogname.pot
|
||||||
|
$scriptdir/extract-plugins $basedir/plugins/ $basedir/resources/i18n/$catalogname.pot
|
||||||
|
msgconv --to-code=UTF-8 $basedir/resources/i18n/$catalogname.pot -o $basedir/resources/i18n/$catalogname.pot
|
||||||
|
|
||||||
|
for pot in $basedir/resources/i18n/*.pot; do
|
||||||
|
filename=$(basename $pot)
|
||||||
|
|
||||||
|
dir=$basedir/resources/i18n/en_US
|
||||||
|
mkdir -p $dir
|
||||||
|
po=$dir/${filename/.pot/.po}
|
||||||
|
msginit --no-translator -l en_US -i $pot -o $po
|
||||||
|
|
||||||
|
dir=$basedir/resources/i18n/x-test
|
||||||
|
mkdir -p $dir
|
||||||
|
po=$dir/${filename/.pot/.po}
|
||||||
|
msginit --no-translator -l en_US -i $pot -o $po
|
||||||
|
msgfilter --keep-header -i $po -o $po sed -e "s/.*/xx&xx/"
|
||||||
|
msgfilter -i $po -o $po sed -e "s/Language: en_US/Language: x-test/"
|
||||||
|
|
||||||
|
#Auto-translate the translation files to Pirate.
|
||||||
|
dir=$basedir/resources/i18n/en_7S
|
||||||
|
mkdir -p $dir
|
||||||
|
po=$dir/${filename/.pot/.po}
|
||||||
|
python3 $scriptdir/pirate.py $pot $po
|
||||||
|
echo Created $po.
|
||||||
|
done
|
14
scripts/translations/extract-plugins
Executable file
14
scripts/translations/extract-plugins
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Extract strings from all plugins
|
||||||
|
#
|
||||||
|
|
||||||
|
scriptdir=$(dirname $0)
|
||||||
|
dir=$1; shift
|
||||||
|
dest=$1; shift
|
||||||
|
|
||||||
|
for file in $(find -L "$dir" -name plugin.json | grep -v 'tests'); do
|
||||||
|
python3 $scriptdir/createplugincontext.py $file $dir $dest
|
||||||
|
done
|
||||||
|
|
||||||
|
|
12
scripts/translations/extract-python
Executable file
12
scripts/translations/extract-python
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Use xgettext to extract all strings from a set of python files.
|
||||||
|
# Argument 1 is the directory to search for python files, argument 2
|
||||||
|
# is the destination file.
|
||||||
|
#
|
||||||
|
# This script will extract strings marked using i18n or i18nc methods.
|
||||||
|
# See UM/i18n.py for the relevant methods.
|
||||||
|
#
|
||||||
|
dir=$1
|
||||||
|
dest=$2
|
||||||
|
xgettext --from-code=UTF-8 --language=python -ki18n:1 -ki18nc:1c,2 -o $dest $(find -L "$dir" -name \*.py)
|
73
scripts/translations/extract-tr-strings
Executable file
73
scripts/translations/extract-tr-strings
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# This script extracts strings from a set of files using Qt's translation system.
|
||||||
|
# It then converts the extracted .ts file in a .po file that can be used with
|
||||||
|
# tools that expect Gettext's po file format.
|
||||||
|
#
|
||||||
|
# This script was adapted from extract-tr-strings from KDE's translation scripts.
|
||||||
|
# extract-tr-strings is Copyright 2014 Aurélien Gateau <agateau@kde.org>
|
||||||
|
set -e
|
||||||
|
|
||||||
|
OLD_PWD=$PWD
|
||||||
|
cd $(dirname $0)
|
||||||
|
SCRIPTS_DIR=$PWD
|
||||||
|
cd $OLD_PWD
|
||||||
|
|
||||||
|
LUPDATE=${LUPDATE:-lupdate}
|
||||||
|
LCONVERT=${LCONVERT:-lconvert}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
echo "ERROR: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $(basename $0) [src_files]... -o [pot_file]
|
||||||
|
|
||||||
|
Creates a .pot file for code translated using Qt translation system.
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
src_files=""
|
||||||
|
pot_file=""
|
||||||
|
while [ $# -gt 0 ] ; do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
-o|--output)
|
||||||
|
pot_file="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
die "Unknown option $1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
src_files="$src_files $1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$src_files" ] ; then
|
||||||
|
die "No source files provided"
|
||||||
|
fi
|
||||||
|
if [ -z "$pot_file" ] ; then
|
||||||
|
die "No pot file provided, please provide one with the -o option"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# "Reserve" a name for a temporary .ts file where lupdate can store its output.
|
||||||
|
# The .ts file is created in the directory where Messages.sh is to ensure
|
||||||
|
# lupdate creates file paths relative to this directory.
|
||||||
|
# lupdate fails if we pass it an existing but empty file, so we have to rm the
|
||||||
|
# temporary file we just created. It is not completely safe, but since this
|
||||||
|
# script is always running in a trusted environment we can assume it is OK.
|
||||||
|
tmp_ts=$(mktemp $PWD/extract-tr-strings-XXXXXX.ts)
|
||||||
|
trap "rm -rf $tmp_ts" 0
|
||||||
|
trap "exit 2" 1 2 3 13 15
|
||||||
|
rm $tmp_ts
|
||||||
|
|
||||||
|
$LUPDATE -silent $src_files -ts $tmp_ts
|
||||||
|
$LCONVERT $tmp_ts --sort-contexts --output-format pot -o $pot_file
|
108
scripts/translations/pirate.py
Normal file
108
scripts/translations/pirate.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#Creates the Pirate translation files.
|
||||||
|
|
||||||
|
import sys #To get command line arguments.
|
||||||
|
import pirateofdoom #Contains our translation dictionary.
|
||||||
|
import re #Case insensitive search and replace.
|
||||||
|
import random # Take random translation candidates
|
||||||
|
|
||||||
|
pot_file = sys.argv[1]
|
||||||
|
po_file = sys.argv[2]
|
||||||
|
|
||||||
|
#Translates English to Pirate.
|
||||||
|
def translate(english):
|
||||||
|
english = english.replace("&", "") #Pirates don't take shortcuts.
|
||||||
|
for eng, pir in pirateofdoom.pirate.items():
|
||||||
|
matches = list(re.finditer(r"\b" + eng.lower() + r"\b", english.lower()))
|
||||||
|
matches = [match.start(0) for match in matches]
|
||||||
|
matches = reversed(sorted(matches))
|
||||||
|
for position in matches:
|
||||||
|
#Make sure the case is correct.
|
||||||
|
uppercase = english[position].lower() != english[position]
|
||||||
|
|
||||||
|
if isinstance(pir, list):
|
||||||
|
pir = random.choice(pir)
|
||||||
|
|
||||||
|
first_character = pir[0]
|
||||||
|
rest_characters = pir[1:]
|
||||||
|
if uppercase:
|
||||||
|
first_character = first_character.upper()
|
||||||
|
else:
|
||||||
|
first_character = first_character.lower()
|
||||||
|
pir = first_character + rest_characters
|
||||||
|
|
||||||
|
english = english[:position] + pir + english[position + len(eng):]
|
||||||
|
return english
|
||||||
|
|
||||||
|
translations = {}
|
||||||
|
|
||||||
|
last_id = ""
|
||||||
|
last_id_plural = ""
|
||||||
|
last_ctxt = ""
|
||||||
|
last_str = ""
|
||||||
|
state = "unknown"
|
||||||
|
with open(pot_file, encoding = "utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
if line.startswith("msgctxt"):
|
||||||
|
state = "ctxt"
|
||||||
|
if last_id != "":
|
||||||
|
translations[(last_ctxt, last_id, last_id_plural)] = last_str
|
||||||
|
last_ctxt = ""
|
||||||
|
last_id = ""
|
||||||
|
last_id_plural = ""
|
||||||
|
last_str = ""
|
||||||
|
elif line.startswith("msgid_plural"):
|
||||||
|
state = "idplural"
|
||||||
|
elif line.startswith("msgid"):
|
||||||
|
state = "id"
|
||||||
|
elif line.startswith("msgstr"):
|
||||||
|
state = "str"
|
||||||
|
|
||||||
|
if line.count('"') >= 2: #There's an ID on this line!
|
||||||
|
line = line[line.find('"') + 1:] #Strip everything before the first ".
|
||||||
|
line = line[:line.rfind('"')] #And after the last ".
|
||||||
|
|
||||||
|
if state == "ctxt":
|
||||||
|
last_ctxt += line #What's left is the context.
|
||||||
|
elif state == "idplural":
|
||||||
|
last_id_plural += line #Or the plural ID.
|
||||||
|
elif state == "id":
|
||||||
|
last_id += line #Or the ID.
|
||||||
|
elif state == "str":
|
||||||
|
last_str += line #Or the actual string.
|
||||||
|
|
||||||
|
for key, _ in translations.items():
|
||||||
|
context, english, english_plural = key
|
||||||
|
pirate = translate(english)
|
||||||
|
pirate_plural = translate(english_plural)
|
||||||
|
translations[key] = (pirate, pirate_plural)
|
||||||
|
|
||||||
|
with open(po_file, "w", encoding = "utf-8") as f:
|
||||||
|
f.write("""msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Pirate\\n"
|
||||||
|
"Report-Msgid-Bugs-To: plugins@ultimaker.com\\n"
|
||||||
|
"POT-Creation-Date: 1492\\n"
|
||||||
|
"PO-Revision-Date: 1492\\n"
|
||||||
|
"Last-Translator: Ghostkeeper and Awhiemstra\\n"
|
||||||
|
"Language-Team: Ghostkeeper and Awhiemstra\\n"
|
||||||
|
"Language: Pirate\\n"
|
||||||
|
"Lang-Code: en\\n"
|
||||||
|
"Country-Code: en_7S\\n"
|
||||||
|
"MIME-Version: 1.0\\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\\n"
|
||||||
|
""")
|
||||||
|
for key, value in translations.items():
|
||||||
|
context, english, english_plural = key
|
||||||
|
pirate, pirate_plural = value
|
||||||
|
f.write('msgctxt "{context}"\n'.format(context = context))
|
||||||
|
if english_plural == "": #No plurals in this item.
|
||||||
|
f.write('msgid "{english}"\n'.format(english = english))
|
||||||
|
f.write('msgstr "{pirate}"\n'.format(pirate = pirate))
|
||||||
|
else:
|
||||||
|
f.write('msgid "{english}"\n'.format(english = english))
|
||||||
|
f.write('msgid_plural "{english_plural}"\n'.format(english_plural = english_plural))
|
||||||
|
f.write('msgstr[0] "{pirate}"\n'.format(pirate = pirate))
|
||||||
|
f.write('msgstr[1] "{pirate_plural}"\n'.format(pirate_plural = pirate_plural))
|
||||||
|
f.write("\n") #Empty line.
|
77
scripts/translations/pirateofdoom.py
Normal file
77
scripts/translations/pirateofdoom.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
pirate = {
|
||||||
|
"build plate": "deck",
|
||||||
|
"buildplate": "deck",
|
||||||
|
"quit": "abandon ship",
|
||||||
|
"back": "avast",
|
||||||
|
"nozzle": "muzzle",
|
||||||
|
"nozzles": "muzzles",
|
||||||
|
"extruder": "cannon",
|
||||||
|
"extruders": "cannons",
|
||||||
|
"yes": "aye",
|
||||||
|
"no": "nay",
|
||||||
|
"loading": "haulin'",
|
||||||
|
"you": "ye",
|
||||||
|
"you're": "ye are",
|
||||||
|
"ok": "aye",
|
||||||
|
"machine": "ship",
|
||||||
|
"machines": "ships",
|
||||||
|
"mm/s²": "knots/s",
|
||||||
|
"mm/s": "knots",
|
||||||
|
"printer": "ship",
|
||||||
|
"printers": "ships",
|
||||||
|
"view": "spyglass",
|
||||||
|
"support": "peg legs",
|
||||||
|
"fan": "wind",
|
||||||
|
"file": "treasure",
|
||||||
|
"file(s)": "treasure(s)",
|
||||||
|
"files": "treasures",
|
||||||
|
"profile": "map",
|
||||||
|
"profiles": "maps",
|
||||||
|
"setting": "knob",
|
||||||
|
"settings": "knobs",
|
||||||
|
"shield": "sail",
|
||||||
|
"your": "yer",
|
||||||
|
"the": "th'",
|
||||||
|
"travel": "journey",
|
||||||
|
"wireframe": "ropey",
|
||||||
|
"wire": "rope",
|
||||||
|
"are": "be",
|
||||||
|
"is": "be",
|
||||||
|
"there": "thar",
|
||||||
|
"not": "nay",
|
||||||
|
"delete": "send to Davy Jones' locker",
|
||||||
|
"remove": "send to Davy Jones' locker",
|
||||||
|
"print": "scribble",
|
||||||
|
"printing": "scribblin'",
|
||||||
|
"load": "haul",
|
||||||
|
"connect to": "board",
|
||||||
|
"connecting": "boarding",
|
||||||
|
"collects": "hoards",
|
||||||
|
"prime tower": "buoy",
|
||||||
|
"change log": "captain's log",
|
||||||
|
"my": "me",
|
||||||
|
"removable drive": "life boat",
|
||||||
|
"print core": "scribbler",
|
||||||
|
"printcore": "scribbler",
|
||||||
|
"abort": ["maroon", "abandon"],
|
||||||
|
"aborting": ["marooning", "abandoning"],
|
||||||
|
"aborted": ["marooned", "abandoned"],
|
||||||
|
"connected": ["anchored", "moored"],
|
||||||
|
"developer": "scurvy dog",
|
||||||
|
"wizard": "cap'n",
|
||||||
|
"active leveling": "keelhauling",
|
||||||
|
"download": "plunder",
|
||||||
|
"downloaded": "plundered",
|
||||||
|
"caution hot surface": "fire in the hole!",
|
||||||
|
"type": "sort",
|
||||||
|
"spool": "barrel",
|
||||||
|
"surface": "lacquer",
|
||||||
|
"zigzag": "heave-to",
|
||||||
|
"bottom": "bilge",
|
||||||
|
"top": "deck",
|
||||||
|
"ironing": "deck swabbing",
|
||||||
|
"adhesion": "anchorage",
|
||||||
|
"blob": "barnacle",
|
||||||
|
"blobs": "barnacles",
|
||||||
|
"slice": "set sail",
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user