renpy/launcher/game/translations.rpy

435 lines
12 KiB
Plaintext
Raw Normal View History

2023-01-18 22:13:55 +00:00
# Copyright 2004-2022 Tom Rothamel <pytom@bishoujo.us>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
init python:
import re
import tempfile
if persistent.translate_language is None:
persistent.translate_language = "english"
if persistent.generate_empty_strings is None:
persistent.generate_empty_strings = True
if persistent.replace_translations is None:
persistent.replace_translations = False
if persistent.reverse_languages is None:
persistent.reverse_languages = False
def CheckLanguage():
return SensitiveIf(re.match(r'^\w+$', persistent.translate_language))
strings_json = None
def get_strings_json():
global strings_json
if strings_json is not None:
return strings_json
try:
tempdir = os.path.join(config.basedir, "tmp")
try:
os.makedirs(os.path.join(config.basedir, "tmp"))
except Exception:
pass
write_test = os.path.join(tempdir, "writetest.txt")
if os.path.exists(write_test):
os.unlink(write_test)
with open(write_test, "w"):
pass
os.unlink(write_test)
except Exception:
tempdir = tempfile.mkdtemp()
strings_json = os.path.join(tempdir, "strings.json")
return strings_json
screen translate:
default tt = Tooltip(None)
$ state = AndroidState()
frame:
style_group "l"
style "l_root"
window:
has vbox
label _("Translations: [project.current.display_name!q]")
add HALF_SPACER
hbox:
# Left side.
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
frame:
style "l_indent"
has vbox
text _("Language:")
add HALF_SPACER
frame style "l_indent":
input style "l_default":
value FieldInputValue(persistent, "translate_language")
size 24
color INPUT_COLOR
allow interface.TRANSLATE_LETTERS
# Left side.
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
frame:
style "l_indent"
has vbox
text _("The language to work with. This should only contain lower-case ASCII characters and underscores.")
add SPACER
hbox:
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
add SEPARATOR2
add HALF_SPACER
frame:
style "l_indent"
has vbox
textbutton _("Generate Translations"):
text_size 24
action [ CheckLanguage(), Jump("generate_translations") ]
add HALF_SPACER
textbutton _("Generate empty strings for translations") style "l_checkbox" action ToggleField(persistent, "generate_empty_strings")
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
add SEPARATOR2
frame:
style "l_indent"
top_padding 10
has vbox
text _("Generates or updates translation files. The files will be placed in game/tl/[persistent.translate_language!q].")
add SPACER
hbox:
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
add SEPARATOR2
add HALF_SPACER
frame:
style "l_indent"
has vbox
textbutton _("Extract String Translations"):
action [ CheckLanguage(), Jump("extract_strings") ]
textbutton _("Merge String Translations"):
action [ CheckLanguage(), Jump("merge_strings") ]
add HALF_SPACER
textbutton _("Replace existing translations") style "l_checkbox" action ToggleField(persistent, "replace_translations")
textbutton _("Reverse languages") style "l_checkbox" action ToggleField(persistent, "reverse_languages")
add HALF_SPACER
textbutton _("Update Default Interface Translations"):
action [ Jump("update_renpy_strings") ]
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
add SEPARATOR2
frame:
style "l_indent"
top_padding 10
has vbox
text _("The extract command allows you to extract string translations from an existing project into a temporary file.\n\nThe merge command merges extracted translations into another project.")
textbutton _("Return") action Jump("front_page") style "l_left_button"
label translate:
call screen translate
# Common code to create the new translations in the current game.
label generate_translations_common:
python:
language = persistent.translate_language
args = [ "translate", language ]
if language == "rot13":
args.append("--rot13")
elif language == "piglatin":
args.append("--piglatin")
elif persistent.generate_empty_strings:
args.append("--empty")
interface.processing(_("Ren'Py is generating translations...."))
project.current.launch(args, wait=True)
project.current.update_dump(force=True)
return
# Code to generate translations by themselves.
label generate_translations:
call generate_translations_common
python:
interface.info(_("Ren'Py has finished generating [language] translations."))
jump front_page
label extract_strings:
python:
language = persistent.translate_language
args = [ "extract_strings", language, get_strings_json() ]
interface.processing(_("Ren'Py is extracting string translations..."))
project.current.launch(args, wait=True)
interface.info(_("Ren'Py has finished extracting [language] string translations."))
jump front_page
label merge_strings:
call generate_translations_common
python:
language = persistent.translate_language
args = [ "merge_strings", language, get_strings_json() ]
if persistent.replace_translations:
args.append("--replace")
if persistent.reverse_languages:
args.append("--reverse")
interface.processing(_("Ren'Py is merging string translations..."))
project.current.launch(args, wait=True)
interface.info(_("Ren'Py has finished merging [language] string translations."))
jump front_page
label update_renpy_strings_common:
python:
language = _preferences.language
interface.processing(_("Updating default interface translations..."))
renpy.translation.extract.extract_strings_core(language, get_strings_json())
args = [ "translate", "None", "--common-only", "--strings-only", "--max-priority", "399", "--no-todo" ]
project.current.launch(args, wait=True)
args = [ "merge_strings", "None", get_strings_json() ]
project.current.launch(args, wait=True)
return
label update_renpy_strings:
call update_renpy_strings_common
jump front_page
screen extract_dialogue:
frame:
style_group "l"
style "l_root"
window:
has vbox
label _("Extract Dialogue: [project.current.display_name!q]")
add HALF_SPACER
frame:
style "l_indent"
xfill True
has vbox
add SEPARATOR2
frame:
style "l_indent"
has vbox
text _("Format:")
add HALF_SPACER
frame:
style "l_indent"
has vbox
textbutton _("Tab-delimited Spreadsheet (dialogue.tab)") action SetField(persistent, "dialogue_format", "tab")
textbutton _("Dialogue Text Only (dialogue.txt)") action SetField(persistent, "dialogue_format", "txt")
add SPACER
add SEPARATOR2
frame:
style "l_indent"
has vbox
text _("Options:")
add HALF_SPACER
textbutton _("Strip text tags from the dialogue.") action ToggleField(persistent, "dialogue_notags") style "l_checkbox"
textbutton _("Escape quotes and other special characters.") action ToggleField(persistent, "dialogue_escape") style "l_checkbox"
textbutton _("Extract all translatable strings, not just dialogue.") action ToggleField(persistent, "dialogue_strings") style "l_checkbox"
add SPACER
add SEPARATOR2
frame:
style "l_indent"
has vbox
text _("Language (or None for the default language):")
input style "l_default":
value FieldInputValue(persistent, "extract_language")
size 24
color INPUT_COLOR
allow interface.TRANSLATE_LETTERS
textbutton _("Cancel") action Jump("front_page") style "l_left_button"
textbutton _("Continue") action Jump("start_extract_dialogue") style "l_right_button"
label extract_dialogue:
$persistent.extract_language = persistent.extract_language or "None"
call screen extract_dialogue
label start_extract_dialogue:
python:
language = persistent.extract_language
args = [ "dialogue", language]
if persistent.dialogue_format == "txt":
args.append("--text")
if persistent.dialogue_strings:
args.append("--strings")
if persistent.dialogue_notags:
args.append("--notags")
if persistent.dialogue_escape:
args.append("--escape")
interface.processing(_("Ren'Py is extracting dialogue...."))
project.current.launch(args, wait=True)
project.current.update_dump(force=True)
interface.info(_("Ren'Py has finished extracting dialogue. The extracted dialogue can be found in dialogue.[persistent.dialogue_format] in the base directory."))
jump front_page