diff --git a/bridge.lua b/bridge.lua index 31db7e6..a213a97 100644 --- a/bridge.lua +++ b/bridge.lua @@ -1,5 +1,4 @@ -local modpath = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(modpath.."/intllib.lua") +local S = ropes.S if ropes.bridges_enabled then diff --git a/crafts.lua b/crafts.lua index 8e2bae8..9b329a6 100644 --- a/crafts.lua +++ b/crafts.lua @@ -1,6 +1,4 @@ --- internationalization boilerplate -local MP = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(MP.."/intllib.lua") +local S = ropes.S if minetest.get_modpath("farming") then -- this doesn't work reliably due to side effects of https://github.com/minetest/minetest/issues/5518 diff --git a/doc.lua b/doc.lua index 020fb04..226d980 100644 --- a/doc.lua +++ b/doc.lua @@ -4,9 +4,7 @@ if not minetest.get_modpath("doc") then return end --- internationalization boilerplate -local MP = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(MP.."/intllib.lua") +local S = ropes.S ropes.doc.ropesegment_longdesc = S("Rope segments are bundles of fibre twisted into robust cables.") ropes.doc.ropesegment_usage = S("This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.") diff --git a/extendingladder.lua b/extendingladder.lua index 00987c7..beefcd3 100644 --- a/extendingladder.lua +++ b/extendingladder.lua @@ -1,5 +1,4 @@ -local modpath = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(modpath.."/intllib.lua") +local S = ropes.S if ropes.extending_ladder_enabled then diff --git a/i18n.py b/i18n.py new file mode 100644 index 0000000..d33bbb0 --- /dev/null +++ b/i18n.py @@ -0,0 +1,418 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Script to generate the template file and update the translation files. +# Copy the script into the mod or modpack root folder and run it there. +# +# Copyright (C) 2019 Joachim Stolberg, 2020 FaceDeer, 2020 Louis Royer +# LGPLv2.1+ + +from __future__ import print_function +import os, fnmatch, re, shutil, errno +from sys import argv as _argv + +# Running params +params = {"recursive": False, + "help": False, + "mods": False, + "verbose": False, + "folders": [] +} +# Available CLI options +options = {"recursive": ['--recursive', '-r'], + "help": ['--help', '-h'], + "mods": ['--installed-mods'], + "verbose": ['--verbose', '-v'] +} + +# Strings longer than this will have extra space added between +# them in the translation files to make it easier to distinguish their +# beginnings and endings at a glance +doublespace_threshold = 60 + +def set_params_folders(tab: list): + '''Initialize params["folders"] from CLI arguments.''' + # Discarding argument 0 (tool name) + for param in tab[1:]: + stop_param = False + for option in options: + if param in options[option]: + stop_param = True + break + if not stop_param: + params["folders"].append(os.path.abspath(param)) + +def set_params(tab: list): + '''Initialize params from CLI arguments.''' + for option in options: + for option_name in options[option]: + if option_name in tab: + params[option] = True + break + +def print_help(name): + '''Prints some help message.''' + print(f'''SYNOPSIS + {name} [OPTIONS] [PATHS...] +DESCRIPTION + {', '.join(options["help"])} + prints this help message + {', '.join(options["recursive"])} + run on all subfolders of paths given + {', '.join(options["mods"])} + run on locally installed modules + {', '.join(options["verbose"])} + add output information +''') + + +def main(): + '''Main function''' + set_params(_argv) + set_params_folders(_argv) + if params["help"]: + print_help(_argv[0]) + elif params["recursive"] and params["mods"]: + print("Option --installed-mods is incompatible with --recursive") + else: + # Add recursivity message + print("Running ", end='') + if params["recursive"]: + print("recursively ", end='') + # Running + if params["mods"]: + print(f"on all locally installed modules in {os.path.abspath('~/.minetest/mods/')}") + run_all_subfolders("~/.minetest/mods") + elif len(params["folders"]) >= 2: + print("on folder list:", params["folders"]) + for f in params["folders"]: + if params["recursive"]: + run_all_subfolders(f) + else: + update_folder(f) + elif len(params["folders"]) == 1: + print("on folder", params["folders"][0]) + if params["recursive"]: + run_all_subfolders(params["folders"][0]) + else: + update_folder(params["folders"][0]) + else: + print("on folder", os.path.abspath("./")) + if params["recursive"]: + run_all_subfolders(os.path.abspath("./")) + else: + update_folder(os.path.abspath("./")) + +#group 2 will be the string, groups 1 and 3 will be the delimiters (" or ') +#See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote +pattern_lua = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL) +pattern_lua_bracketed = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL) + +# Handles "concatenation" .. " of strings" +pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL) + +pattern_tr = re.compile(r'(.+?[^@])=(.*)') +pattern_name = re.compile(r'^name[ ]*=[ ]*([^ \n]*)') +pattern_tr_filename = re.compile(r'\.tr$') +pattern_po_language_code = re.compile(r'(.*)\.po$') + +#attempt to read the mod's name from the mod.conf file. Returns None on failure +def get_modname(folder): + try: + with open(os.path.join(folder, "mod.conf"), "r", encoding='utf-8') as mod_conf: + for line in mod_conf: + match = pattern_name.match(line) + if match: + return match.group(1) + except FileNotFoundError: + pass + return None + +#If there are already .tr files in /locale, returns a list of their names +def get_existing_tr_files(folder): + out = [] + for root, dirs, files in os.walk(os.path.join(folder, 'locale/')): + for name in files: + if pattern_tr_filename.search(name): + out.append(name) + return out + +# A series of search and replaces that massage a .po file's contents into +# a .tr file's equivalent +def process_po_file(text): + # The first three items are for unused matches + text = re.sub(r'#~ msgid "', "", text) + text = re.sub(r'"\n#~ msgstr ""\n"', "=", text) + text = re.sub(r'"\n#~ msgstr "', "=", text) + # comment lines + text = re.sub(r'#.*\n', "", text) + # converting msg pairs into "=" pairs + text = re.sub(r'msgid "', "", text) + text = re.sub(r'"\nmsgstr ""\n"', "=", text) + text = re.sub(r'"\nmsgstr "', "=", text) + # various line breaks and escape codes + text = re.sub(r'"\n"', "", text) + text = re.sub(r'"\n', "\n", text) + text = re.sub(r'\\"', '"', text) + text = re.sub(r'\\n', '@n', text) + # remove header text + text = re.sub(r'=Project-Id-Version:.*\n', "", text) + # remove double-spaced lines + text = re.sub(r'\n\n', '\n', text) + return text + +# Go through existing .po files and, if a .tr file for that language +# *doesn't* exist, convert it and create it. +# The .tr file that results will subsequently be reprocessed so +# any "no longer used" strings will be preserved. +# Note that "fuzzy" tags will be lost in this process. +def process_po_files(folder, modname): + for root, dirs, files in os.walk(os.path.join(folder, 'locale/')): + for name in files: + code_match = pattern_po_language_code.match(name) + if code_match == None: + continue + language_code = code_match.group(1) + tr_name = modname + "." + language_code + ".tr" + tr_file = os.path.join(root, tr_name) + if os.path.exists(tr_file): + if params["verbose"]: + print(f"{tr_name} already exists, ignoring {name}") + continue + fname = os.path.join(root, name) + with open(fname, "r", encoding='utf-8') as po_file: + if params["verbose"]: + print(f"Importing translations from {name}") + text = process_po_file(po_file.read()) + with open(tr_file, "wt", encoding='utf-8') as tr_out: + tr_out.write(text) + +# from https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python/600612#600612 +# Creates a directory if it doesn't exist, silently does +# nothing if it already exists +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: raise + +# Converts the template dictionary to a text to be written as a file +# dKeyStrings is a dictionary of localized string to source file sets +# dOld is a dictionary of existing translations and comments from +# the previous version of this text +def strings_to_text(dkeyStrings, dOld, mod_name): + lOut = [f"# textdomain: {mod_name}\n"] + + dGroupedBySource = {} + + for key in dkeyStrings: + sourceList = list(dkeyStrings[key]) + sourceList.sort() + sourceString = "\n".join(sourceList) + listForSource = dGroupedBySource.get(sourceString, []) + listForSource.append(key) + dGroupedBySource[sourceString] = listForSource + + lSourceKeys = list(dGroupedBySource.keys()) + lSourceKeys.sort() + for source in lSourceKeys: + localizedStrings = dGroupedBySource[source] + localizedStrings.sort() + lOut.append("") + lOut.append(source) + lOut.append("") + for localizedString in localizedStrings: + val = dOld.get(localizedString, {}) + translation = val.get("translation", "") + comment = val.get("comment") + if len(localizedString) > doublespace_threshold and not lOut[-1] == "": + lOut.append("") + if comment != None: + lOut.append(comment) + lOut.append(f"{localizedString}={translation}") + if len(localizedString) > doublespace_threshold: + lOut.append("") + + + unusedExist = False + for key in dOld: + if key not in dkeyStrings: + val = dOld[key] + translation = val.get("translation") + comment = val.get("comment") + # only keep an unused translation if there was translated + # text or a comment associated with it + if translation != None and (translation != "" or comment): + if not unusedExist: + unusedExist = True + lOut.append("\n\n##### not used anymore #####\n") + if len(key) > doublespace_threshold and not lOut[-1] == "": + lOut.append("") + if comment != None: + lOut.append(comment) + lOut.append(f"{key}={translation}") + if len(key) > doublespace_threshold: + lOut.append("") + return "\n".join(lOut) + '\n' + +# Writes a template.txt file +# dkeyStrings is the dictionary returned by generate_template +def write_template(templ_file, dkeyStrings, mod_name): + # read existing template file to preserve comments + existing_template = import_tr_file(templ_file) + + text = strings_to_text(dkeyStrings, existing_template[0], mod_name) + mkdir_p(os.path.dirname(templ_file)) + with open(templ_file, "wt", encoding='utf-8') as template_file: + template_file.write(text) + + +# Gets all translatable strings from a lua file +def read_lua_file_strings(lua_file): + lOut = [] + with open(lua_file, encoding='utf-8') as text_file: + text = text_file.read() + #TODO remove comments here + + text = re.sub(pattern_concat, "", text) + + strings = [] + for s in pattern_lua.findall(text): + strings.append(s[1]) + for s in pattern_lua_bracketed.findall(text): + strings.append(s) + + for s in strings: + s = re.sub(r'"\.\.\s+"', "", s) + s = re.sub("@[^@=0-9]", "@@", s) + s = s.replace('\\"', '"') + s = s.replace("\\'", "'") + s = s.replace("\n", "@n") + s = s.replace("\\n", "@n") + s = s.replace("=", "@=") + lOut.append(s) + return lOut + +# Gets strings from an existing translation file +# returns both a dictionary of translations +# and the full original source text so that the new text +# can be compared to it for changes. +def import_tr_file(tr_file): + dOut = {} + text = None + if os.path.exists(tr_file): + with open(tr_file, "r", encoding='utf-8') as existing_file : + # save the full text to allow for comparison + # of the old version with the new output + text = existing_file.read() + existing_file.seek(0) + # a running record of the current comment block + # we're inside, to allow preceeding multi-line comments + # to be retained for a translation line + latest_comment_block = None + for line in existing_file.readlines(): + line = line.rstrip('\n') + if line[:3] == "###": + # Reset comment block if we hit a header + latest_comment_block = None + continue + if line[:1] == "#": + # Save the comment we're inside + if not latest_comment_block: + latest_comment_block = line + else: + latest_comment_block = latest_comment_block + "\n" + line + continue + match = pattern_tr.match(line) + if match: + # this line is a translated line + outval = {} + outval["translation"] = match.group(2) + if latest_comment_block: + # if there was a comment, record that. + outval["comment"] = latest_comment_block + latest_comment_block = None + dOut[match.group(1)] = outval + return (dOut, text) + +# Walks all lua files in the mod folder, collects translatable strings, +# and writes it to a template.txt file +# Returns a dictionary of localized strings to source file sets +# that can be used with the strings_to_text function. +def generate_template(folder, mod_name): + dOut = {} + for root, dirs, files in os.walk(folder): + for name in files: + if fnmatch.fnmatch(name, "*.lua"): + fname = os.path.join(root, name) + found = read_lua_file_strings(fname) + if params["verbose"]: + print(f"{fname}: {str(len(found))} translatable strings") + + for s in found: + sources = dOut.get(s, set()) + sources.add(f"### {os.path.basename(fname)} ###") + dOut[s] = sources + + if len(dOut) == 0: + return None + templ_file = os.path.join(folder, "locale/template.txt") + write_template(templ_file, dOut, mod_name) + return dOut + +# Updates an existing .tr file, copying the old one to a ".old" file +# if any changes have happened +# dNew is the data used to generate the template, it has all the +# currently-existing localized strings +def update_tr_file(dNew, mod_name, tr_file): + if params["verbose"]: + print(f"updating {tr_file}") + + tr_import = import_tr_file(tr_file) + dOld = tr_import[0] + textOld = tr_import[1] + + textNew = strings_to_text(dNew, dOld, mod_name) + + if textOld and textOld != textNew: + print(f"{tr_file} has changed.") + shutil.copyfile(tr_file, f"{tr_file}.old") + + with open(tr_file, "w", encoding='utf-8') as new_tr_file: + new_tr_file.write(textNew) + +# Updates translation files for the mod in the given folder +def update_mod(folder): + modname = get_modname(folder) + if modname is not None: + process_po_files(folder, modname) + print(f"Updating translations for {modname}") + data = generate_template(folder, modname) + if data == None: + print(f"No translatable strings found in {modname}") + else: + for tr_file in get_existing_tr_files(folder): + update_tr_file(data, modname, os.path.join(folder, "locale/", tr_file)) + else: + print("Unable to find modname in folder " + folder) + +# Determines if the folder being pointed to is a mod or a mod pack +# and then runs update_mod accordingly +def update_folder(folder): + is_modpack = os.path.exists(os.path.join(folder, "modpack.txt")) or os.path.exists(os.path.join(folder, "modpack.conf")) + if is_modpack: + subfolders = [f.path for f in os.scandir(folder) if f.is_dir()] + for subfolder in subfolders: + update_mod(subfolder + "/") + else: + update_mod(folder) + print("Done.") + +def run_all_subfolders(folder): + for modfolder in [f.path for f in os.scandir(folder) if f.is_dir()]: + update_folder(modfolder + "/") + + +main() diff --git a/init.lua b/init.lua index 8ab5da9..c3c4fe8 100644 --- a/init.lua +++ b/init.lua @@ -3,8 +3,9 @@ ropes = { } -- internationalization boilerplate -local MP = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(MP.."/intllib.lua") +local modname = minetest.get_current_modname() +local MP = minetest.get_modpath(modname) +ropes.S = minetest.get_translator(modname) ropes.ropeLength = tonumber(minetest.settings:get("ropes_rope_length")) or 50 ropes.woodRopeBoxMaxMultiple = tonumber(minetest.settings:get("ropes_wood_rope_box_max_multiple")) or 2 diff --git a/intllib.lua b/intllib.lua deleted file mode 100644 index 6669d72..0000000 --- a/intllib.lua +++ /dev/null @@ -1,45 +0,0 @@ - --- Fallback functions for when `intllib` is not installed. --- Code released under Unlicense . - --- Get the latest version of this file at: --- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua - -local function format(str, ...) - local args = { ... } - local function repl(escape, open, num, close) - if escape == "" then - local replacement = tostring(args[tonumber(num)]) - if open == "" then - replacement = replacement..close - end - return replacement - else - return "@"..open..num..close - end - end - return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) -end - -local gettext, ngettext -if minetest.get_modpath("intllib") then - if intllib.make_gettext_pair then - -- New method using gettext. - gettext, ngettext = intllib.make_gettext_pair() - else - -- Old method using text files. - gettext = intllib.Getter() - end -end - --- Fill in missing functions. - -gettext = gettext or function(msgid, ...) - return format(msgid, ...) -end - -ngettext = ngettext or function(msgid, msgid_plural, n, ...) - return format(n==1 and msgid or msgid_plural, ...) -end - -return gettext, ngettext diff --git a/locale/es.po b/locale/es.po deleted file mode 100644 index 381ca66..0000000 --- a/locale/es.po +++ /dev/null @@ -1,222 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-04-28 16:30-0600\n" -"PO-Revision-Date: 2018-10-27 11:26+0200\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.11\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: bridge.lua:49 -msgid "Wooden Bridge" -msgstr "" - -#: crafts.lua:54 -msgid "Rope Segment" -msgstr "Segmento de cuerda" - -#: doc.lua:11 -msgid "Rope segments are bundles of fibre twisted into robust cables." -msgstr "" -"Los segmentos de cable son haces de fibras trenzadas en cables robustos." - -#: doc.lua:12 -msgid "" -"This craft item is useful for creating rope ladders, or for spooling on " -"wooden spindles to hang and climb upon." -msgstr "" -"Esta objeto es útil para crear escaleras de cuerda, o para enrollar en " -"husillos de madera para colgar y trepar." - -#: doc.lua:14 -msgid "A hanging rope ladder that automatically extends downward." -msgstr "" -"Una escalera de cuerda colgante que se extiende automáticamente hacia abajo." - -#: doc.lua:15 -msgid "" -"After a rope ladder is placed on a vertical wall it will begin extending " -"downward until it reaches its maximum length (@1 meters). If the rope ladder " -"is removed all of the ladder below the point of removal will disappear. A " -"rope ladder can be severed partway down using an axe or similar tool, and " -"the ladder below the point where it is cut will collapse. No rope is " -"actually lost in the process, though, and if the uppermost section of the " -"ladder is removed and replaced the ladder will re-extend to the same maximum " -"length as before." -msgstr "" -"Después de colocar una escalera de cuerda en una pared vertical, comenzará a " -"extenderse hacia abajo hasta que alcance su longitud máxima (@1 metro). Si " -"se retira la escalera de cuerda, desaparecerá toda la escalera por debajo " -"del punto de extracción. Una escalera de cuerda puede ser cortada hasta la " -"mitad usando un hacha o una herramienta similar, y la escalera por debajo " -"del punto donde es cortada colapsará. Sin embargo, no se pierde ninguna " -"cuerda en el proceso, y si la sección superior de la escalera se retira y se " -"reemplaza, la escalera se volverá a extender a la misma longitud máxima que " -"antes." - -#: doc.lua:17 -msgid "" -"Rope boxes have a certain amount of rope contained within them specified in " -"the name of the node, and have a limit to how much rope they can support " -"that depends on the material they're made of. The different lengths can be " -"crafted by combining and splitting up rope boxes in the crafting grid. For " -"example, you can craft a @1m rope box by putting a @2m rope box and a rope " -"segment in the crafting grid, or a @3m rope box and two rope segments in the " -"crafting grid. Two rope segments can be recovered by putting the @1m rope " -"box in the crafting grid by itself." -msgstr "" -"Las cajas de cuerdas tienen una cierta cantidad de cuerda contenida dentro " -"de ellas especificada en el nombre del nodo, y tienen un límite en la " -"cantidad de cuerda que pueden soportar que depende del material del que " -"están hechas. Las diferentes longitudes se pueden realizar combinando y " -"dividiendo las cajas de cuerda en la rejilla de elaboración. Por ejemplo, " -"puedes crear una caja de cuerda de @1m poniendo una caja de cuerda de @2m y " -"un segmento de cuerda en la rejilla de artesanía, o una caja de cuerda de " -"@3m y dos segmentos de cuerda en la rejilla de artesanía. Se pueden " -"recuperar dos segmentos de cable colocando solo la caja de cable de @1m en " -"la rejilla de fabricación." - -#: doc.lua:20 -#: doc.lua:22 -#: ropeboxes.lua:321 -msgid "Wood" -msgstr "madera" - -#: doc.lua:20 -#: doc.lua:26 -#: doc.lua:32 -msgid "rope boxes can hold @1m of rope." -msgstr "Las cajas de cuerdas pueden mantener @1m de cuerda." - -#: doc.lua:22 -#: doc.lua:28 -#: doc.lua:34 -msgid "rope boxes can hold rope lengths from @1m to @2m." -msgstr "Las cajas de cuerda pueden contener longitudes de cuerda de @1m a @2m." - -#: doc.lua:26 -#: doc.lua:28 -#: ropeboxes.lua:338 -msgid "Copper" -msgstr "cobre" - -#: doc.lua:32 -#: doc.lua:34 -#: ropeboxes.lua:355 -msgid "Steel" -msgstr "acero" - -#: doc.lua:37 -msgid "" -"Ropes are hung by placing rope boxes, which automatically lower a rope of " -"fixed length below them. They can be climbed and cut." -msgstr "" -"Las cuerdas se cuelgan colocando cajas de cuerda, que bajan automáticamente " -"una cuerda de longitud fija por debajo de ellas. Se pueden escalar y cortar." - -#: doc.lua:39 -msgid "" -"When a rope box is placed the rope will immediately begin lowering from it " -"at one meter per second. The rope will only descend when its end is in the " -"vicinity of an active player, suspending its journey when no players are " -"nearby, so a long descent may require a player to climb down the rope as it " -"goes. If you are near the bottom end of a rope that's extending you'll be " -"automatically carried down with it. The rope will stop when it encounters " -"and obstruction, but will resume lowering if the obstruction is removed." -msgstr "" -"Cuando se coloca una caja de cuerda, la cuerda comienza a descender " -"inmediatamente a un metro por segundo. La cuerda sólo descenderá cuando su " -"final esté cerca de un jugador activo, suspendiendo su viaje cuando no haya " -"jugadores cerca, por lo que un largo descenso puede requerir que el jugador " -"baje por la cuerda a medida que avanza. Si estás cerca del extremo inferior " -"de una cuerda que se está extendiendo, serás arrastrado automáticamente " -"hacia abajo con ella. La cuerda se detendrá cuando se encuentre con una " -"obstrucción, pero volverá a bajar si se retira la obstrucción." - -#: doc.lua:40 -msgid "" -"A rope can be severed midway using an axe or other similar tool. The section " -"of rope below the cut will collapse and disappear, potentially causing " -"players who were hanging on to it to fall. The remaining rope will not " -"resume descent on its own, but the rope box at the top of the rope " -"\"remembers\" how long the rope was and if it is deconstructed and replaced " -"it will still have the same maximum length of rope as before - no rope is " -"permanently lost when a rope is severed like this." -msgstr "" -"Una cuerda puede ser cortada a mitad de camino usando un hacha u otra " -"herramienta similar. La sección de la cuerda debajo del corte se colapsará y " -"desaparecerá, lo que puede causar que los jugadores que estaban colgados de " -"ella se caigan. El resto de la cuerda no volverá a descender por sí sola, " -"pero la caja de la cuerda en la parte superior de la cuerda \"recuerda\" la " -"longitud de la cuerda y si es deconstruida y reemplazada tendrá la misma " -"longitud máxima de cuerda que antes - ninguna cuerda se pierde " -"permanentemente cuando una cuerda es cortada de esta manera." - -#: doc.lua:43 -msgid "" -"A ladder for climbing. It can reach greater heights when placed against a " -"supporting block." -msgstr "" - -#: doc.lua:44 -msgid "" -"Right-clicking on a ladder with a stack of identical ladder items will " -"automatically add new ladder segments to the top, provided it hasn't " -"extended too far up beyond the last block behind it providing support." -msgstr "" - -#: doc.lua:47 -msgid "A wooden platform with support struts useful for bridging gaps." -msgstr "" - -#: doc.lua:48 -msgid "" -"This behaves like most structural blocks except in one circumstance: when " -"placed on top of a block with buildable space on the side facing away from " -"you, this block will not be built on top but instead will extend out from " -"that far side of the target block. This allows a platform to be easily built " -"that juts out away from the location you're standing on." -msgstr "" - -#: extendingladder.lua:11 -msgid "Wooden Ladder" -msgstr "" - -#: extendingladder.lua:18 -msgid "Steel Ladder" -msgstr "" - -#: extendingladder.lua:57 -msgid "Wooden Extendable Ladder" -msgstr "" - -#: extendingladder.lua:64 -msgid "Steel Extendable Ladder" -msgstr "" - -#: ropeboxes.lua:121 -msgid "@1 Ropebox @2m" -msgstr "Caja de cuerda de @1 de @2m" - -#: ropeboxes.lua:229 -#: ropeboxes.lua:264 -msgid "Rope" -msgstr "Cuerda" - -#: ropeladder.lua:27 -#: ropeladder.lua:89 -#: ropeladder.lua:119 -#: ropeladder.lua:153 -msgid "Rope Ladder" -msgstr "Escalera de cuerda" diff --git a/locale/ropes.es.tr b/locale/ropes.es.tr new file mode 100644 index 0000000..5b6d772 --- /dev/null +++ b/locale/ropes.es.tr @@ -0,0 +1,62 @@ +# textdomain: ropes + + +### bridge.lua ### + +Wooden Bridge= + +### crafts.lua ### + +Rope Segment=Segmento de cuerda + +### doc.lua ### + +A hanging rope ladder that automatically extends downward.=Una escalera de cuerda colgante que se extiende automáticamente hacia abajo. + +A ladder for climbing. It can reach greater heights when placed against a supporting block.= + +A rope can be severed midway using an axe or other similar tool. The section of rope below the cut will collapse and disappear, potentially causing players who were hanging on to it to fall. The remaining rope will not resume descent on its own, but the rope box at the top of the rope "remembers" how long the rope was and if it is deconstructed and replaced it will still have the same maximum length of rope as before - no rope is permanently lost when a rope is severed like this.=Una cuerda puede ser cortada a mitad de camino usando un hacha u otra herramienta similar. La sección de la cuerda debajo del corte se colapsará y desaparecerá, lo que puede causar que los jugadores que estaban colgados de ella se caigan. El resto de la cuerda no volverá a descender por sí sola, pero la caja de la cuerda en la parte superior de la cuerda "recuerda" la longitud de la cuerda y si es deconstruida y reemplazada tendrá la misma longitud máxima de cuerda que antes - ninguna cuerda se pierde permanentemente cuando una cuerda es cortada de esta manera. + +A wooden platform with support struts useful for bridging gaps.= + +After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (@1 meters). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before.=Después de colocar una escalera de cuerda en una pared vertical, comenzará a extenderse hacia abajo hasta que alcance su longitud máxima (@1 metro). Si se retira la escalera de cuerda, desaparecerá toda la escalera por debajo del punto de extracción. Una escalera de cuerda puede ser cortada hasta la mitad usando un hacha o una herramienta similar, y la escalera por debajo del punto donde es cortada colapsará. Sin embargo, no se pierde ninguna cuerda en el proceso, y si la sección superior de la escalera se retira y se reemplaza, la escalera se volverá a extender a la misma longitud máxima que antes. + +Right-clicking on a ladder with a stack of identical ladder items will automatically add new ladder segments to the top, provided it hasn't extended too far up beyond the last block behind it providing support.= + +Rope boxes have a certain amount of rope contained within them specified in the name of the node, and have a limit to how much rope they can support that depends on the material they're made of. The different lengths can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @1m rope box by putting a @2m rope box and a rope segment in the crafting grid, or a @3m rope box and two rope segments in the crafting grid. Two rope segments can be recovered by putting the @1m rope box in the crafting grid by itself.=Las cajas de cuerdas tienen una cierta cantidad de cuerda contenida dentro de ellas especificada en el nombre del nodo, y tienen un límite en la cantidad de cuerda que pueden soportar que depende del material del que están hechas. Las diferentes longitudes se pueden realizar combinando y dividiendo las cajas de cuerda en la rejilla de elaboración. Por ejemplo, puedes crear una caja de cuerda de @1m poniendo una caja de cuerda de @2m y un segmento de cuerda en la rejilla de artesanía, o una caja de cuerda de @3m y dos segmentos de cuerda en la rejilla de artesanía. Se pueden recuperar dos segmentos de cable colocando solo la caja de cable de @1m en la rejilla de fabricación. + +Rope segments are bundles of fibre twisted into robust cables.=Los segmentos de cable son haces de fibras trenzadas en cables robustos. + +Ropes are hung by placing rope boxes, which automatically lower a rope of fixed length below them. They can be climbed and cut.=Las cuerdas se cuelgan colocando cajas de cuerda, que bajan automáticamente una cuerda de longitud fija por debajo de ellas. Se pueden escalar y cortar. + +This behaves like most structural blocks except in one circumstance: when placed on top of a block with buildable space on the side facing away from you, this block will not be built on top but instead will extend out from that far side of the target block. This allows a platform to be easily built that juts out away from the location you're standing on.= + +This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.=Esta objeto es útil para crear escaleras de cuerda, o para enrollar en husillos de madera para colgar y trepar. + +When a rope box is placed the rope will immediately begin lowering from it at one meter per second. The rope will only descend when its end is in the vicinity of an active player, suspending its journey when no players are nearby, so a long descent may require a player to climb down the rope as it goes. If you are near the bottom end of a rope that's extending you'll be automatically carried down with it. The rope will stop when it encounters and obstruction, but will resume lowering if the obstruction is removed.=Cuando se coloca una caja de cuerda, la cuerda comienza a descender inmediatamente a un metro por segundo. La cuerda sólo descenderá cuando su final esté cerca de un jugador activo, suspendiendo su viaje cuando no haya jugadores cerca, por lo que un largo descenso puede requerir que el jugador baje por la cuerda a medida que avanza. Si estás cerca del extremo inferior de una cuerda que se está extendiendo, serás arrastrado automáticamente hacia abajo con ella. La cuerda se detendrá cuando se encuentre con una obstrucción, pero volverá a bajar si se retira la obstrucción. + +rope boxes can hold @1m of rope.=Las cajas de cuerdas pueden mantener @1m de cuerda. +rope boxes can hold rope lengths from @1m to @2m.=Las cajas de cuerda pueden contener longitudes de cuerda de @1m a @2m. + +### doc.lua ### +### ropeboxes.lua ### + +Copper=cobre +Steel=acero +Wood=madera + +### extendingladder.lua ### + +Steel Extendable Ladder= +Steel Ladder= +Wooden Extendable Ladder= +Wooden Ladder= + +### ropeboxes.lua ### + +@1 Ropebox @2m=Caja de cuerda de @1 de @2m +Rope=Cuerda + +### ropeladder.lua ### + +Rope Ladder=Escalera de cuerda diff --git a/locale/template.pot b/locale/template.pot deleted file mode 100644 index 8ccca87..0000000 --- a/locale/template.pot +++ /dev/null @@ -1,180 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-04-28 16:30-0600\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: bridge.lua:49 -msgid "Wooden Bridge" -msgstr "" - -#: crafts.lua:54 -msgid "Rope Segment" -msgstr "" - -#: doc.lua:11 -msgid "Rope segments are bundles of fibre twisted into robust cables." -msgstr "" - -#: doc.lua:12 -msgid "" -"This craft item is useful for creating rope ladders, or for spooling on " -"wooden spindles to hang and climb upon." -msgstr "" - -#: doc.lua:14 -msgid "A hanging rope ladder that automatically extends downward." -msgstr "" - -#: doc.lua:15 -msgid "" -"After a rope ladder is placed on a vertical wall it will begin extending " -"downward until it reaches its maximum length (@1 meters). If the rope ladder " -"is removed all of the ladder below the point of removal will disappear. A " -"rope ladder can be severed partway down using an axe or similar tool, and " -"the ladder below the point where it is cut will collapse. No rope is " -"actually lost in the process, though, and if the uppermost section of the " -"ladder is removed and replaced the ladder will re-extend to the same maximum " -"length as before." -msgstr "" - -#: doc.lua:17 -msgid "" -"Rope boxes have a certain amount of rope contained within them specified in " -"the name of the node, and have a limit to how much rope they can support " -"that depends on the material they're made of. The different lengths can be " -"crafted by combining and splitting up rope boxes in the crafting grid. For " -"example, you can craft a @1m rope box by putting a @2m rope box and a rope " -"segment in the crafting grid, or a @3m rope box and two rope segments in the " -"crafting grid. Two rope segments can be recovered by putting the @1m rope " -"box in the crafting grid by itself." -msgstr "" - -#: doc.lua:20 -#: doc.lua:22 -#: ropeboxes.lua:321 -msgid "Wood" -msgstr "" - -#: doc.lua:20 -#: doc.lua:26 -#: doc.lua:32 -msgid "rope boxes can hold @1m of rope." -msgstr "" - -#: doc.lua:22 -#: doc.lua:28 -#: doc.lua:34 -msgid "rope boxes can hold rope lengths from @1m to @2m." -msgstr "" - -#: doc.lua:26 -#: doc.lua:28 -#: ropeboxes.lua:338 -msgid "Copper" -msgstr "" - -#: doc.lua:32 -#: doc.lua:34 -#: ropeboxes.lua:355 -msgid "Steel" -msgstr "" - -#: doc.lua:37 -msgid "" -"Ropes are hung by placing rope boxes, which automatically lower a rope of " -"fixed length below them. They can be climbed and cut." -msgstr "" - -#: doc.lua:39 -msgid "" -"When a rope box is placed the rope will immediately begin lowering from it " -"at one meter per second. The rope will only descend when its end is in the " -"vicinity of an active player, suspending its journey when no players are " -"nearby, so a long descent may require a player to climb down the rope as it " -"goes. If you are near the bottom end of a rope that's extending you'll be " -"automatically carried down with it. The rope will stop when it encounters " -"and obstruction, but will resume lowering if the obstruction is removed." -msgstr "" - -#: doc.lua:40 -msgid "" -"A rope can be severed midway using an axe or other similar tool. The section " -"of rope below the cut will collapse and disappear, potentially causing " -"players who were hanging on to it to fall. The remaining rope will not " -"resume descent on its own, but the rope box at the top of the rope " -"\"remembers\" how long the rope was and if it is deconstructed and replaced " -"it will still have the same maximum length of rope as before - no rope is " -"permanently lost when a rope is severed like this." -msgstr "" - -#: doc.lua:43 -msgid "" -"A ladder for climbing. It can reach greater heights when placed against a " -"supporting block." -msgstr "" - -#: doc.lua:44 -msgid "" -"Right-clicking on a ladder with a stack of identical ladder items will " -"automatically add new ladder segments to the top, provided it hasn't " -"extended too far up beyond the last block behind it providing support." -msgstr "" - -#: doc.lua:47 -msgid "A wooden platform with support struts useful for bridging gaps." -msgstr "" - -#: doc.lua:48 -msgid "" -"This behaves like most structural blocks except in one circumstance: when " -"placed on top of a block with buildable space on the side facing away from " -"you, this block will not be built on top but instead will extend out from " -"that far side of the target block. This allows a platform to be easily built " -"that juts out away from the location you're standing on." -msgstr "" - -#: extendingladder.lua:11 -msgid "Wooden Ladder" -msgstr "" - -#: extendingladder.lua:18 -msgid "Steel Ladder" -msgstr "" - -#: extendingladder.lua:57 -msgid "Wooden Extendable Ladder" -msgstr "" - -#: extendingladder.lua:64 -msgid "Steel Extendable Ladder" -msgstr "" - -#: ropeboxes.lua:121 -msgid "@1 Ropebox @2m" -msgstr "" - -#: ropeboxes.lua:229 -#: ropeboxes.lua:264 -msgid "Rope" -msgstr "" - -#: ropeladder.lua:27 -#: ropeladder.lua:89 -#: ropeladder.lua:119 -#: ropeladder.lua:153 -msgid "Rope Ladder" -msgstr "" diff --git a/locale/template.txt b/locale/template.txt new file mode 100644 index 0000000..6cdfbc1 --- /dev/null +++ b/locale/template.txt @@ -0,0 +1,61 @@ +# textdomain: ropes + + +### bridge.lua ### + +Wooden Bridge= + +### crafts.lua ### + +Rope Segment= + +### doc.lua ### + +A hanging rope ladder that automatically extends downward.= + +A ladder for climbing. It can reach greater heights when placed against a supporting block.= + +A rope can be severed midway using an axe or other similar tool. The section of rope below the cut will collapse and disappear, potentially causing players who were hanging on to it to fall. The remaining rope will not resume descent on its own, but the rope box at the top of the rope "remembers" how long the rope was and if it is deconstructed and replaced it will still have the same maximum length of rope as before - no rope is permanently lost when a rope is severed like this.= + +A wooden platform with support struts useful for bridging gaps.= + +After a rope ladder is placed on a vertical wall it will begin extending downward until it reaches its maximum length (@1 meters). If the rope ladder is removed all of the ladder below the point of removal will disappear. A rope ladder can be severed partway down using an axe or similar tool, and the ladder below the point where it is cut will collapse. No rope is actually lost in the process, though, and if the uppermost section of the ladder is removed and replaced the ladder will re-extend to the same maximum length as before.= + +Right-clicking on a ladder with a stack of identical ladder items will automatically add new ladder segments to the top, provided it hasn't extended too far up beyond the last block behind it providing support.= + +Rope boxes have a certain amount of rope contained within them specified in the name of the node, and have a limit to how much rope they can support that depends on the material they're made of. The different lengths can be crafted by combining and splitting up rope boxes in the crafting grid. For example, you can craft a @1m rope box by putting a @2m rope box and a rope segment in the crafting grid, or a @3m rope box and two rope segments in the crafting grid. Two rope segments can be recovered by putting the @1m rope box in the crafting grid by itself.= + + +Ropes are hung by placing rope boxes, which automatically lower a rope of fixed length below them. They can be climbed and cut.= + +This behaves like most structural blocks except in one circumstance: when placed on top of a block with buildable space on the side facing away from you, this block will not be built on top but instead will extend out from that far side of the target block. This allows a platform to be easily built that juts out away from the location you're standing on.= + +This craft item is useful for creating rope ladders, or for spooling on wooden spindles to hang and climb upon.= + +When a rope box is placed the rope will immediately begin lowering from it at one meter per second. The rope will only descend when its end is in the vicinity of an active player, suspending its journey when no players are nearby, so a long descent may require a player to climb down the rope as it goes. If you are near the bottom end of a rope that's extending you'll be automatically carried down with it. The rope will stop when it encounters and obstruction, but will resume lowering if the obstruction is removed.= + +rope boxes can hold @1m of rope.= +rope boxes can hold rope lengths from @1m to @2m.= + +### doc.lua ### +### ropeboxes.lua ### + +Copper= +Steel= +Wood= + +### extendingladder.lua ### + +Steel Extendable Ladder= +Steel Ladder= +Wooden Extendable Ladder= +Wooden Ladder= + +### ropeboxes.lua ### + +@1 Ropebox @2m= +Rope= + +### ropeladder.lua ### + +Rope Ladder= diff --git a/locale/update.bat b/locale/update.bat deleted file mode 100644 index e87d44c..0000000 --- a/locale/update.bat +++ /dev/null @@ -1,6 +0,0 @@ -@echo off -setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION -cd .. -set LIST= -for /r %%X in (*.lua) do set LIST=!LIST! %%X -..\intllib\tools\xgettext.bat %LIST% \ No newline at end of file diff --git a/mod.conf b/mod.conf index 7356846..7726e8a 100644 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,4 @@ name = ropes description = Adds rope boxes and ladders depends = default -optional_depends = cottages, doc, farming, hemp, intllib, loot, vines +optional_depends = cottages, doc, farming, hemp, loot, vines diff --git a/ropeboxes.lua b/ropeboxes.lua index a8a75c1..2c82d29 100644 --- a/ropeboxes.lua +++ b/ropeboxes.lua @@ -1,6 +1,5 @@ -- internationalization boilerplate -local MP = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(MP.."/intllib.lua") +local S = ropes.S local function rope_box_tiles(count, tint) return { diff --git a/ropeladder.lua b/ropeladder.lua index 5122e7c..8320ebd 100644 --- a/ropeladder.lua +++ b/ropeladder.lua @@ -2,9 +2,7 @@ if ropes.ropeLadderLength == 0 and not ropes.create_all_definitions then return end --- internationalization boilerplate -local MP = minetest.get_modpath(minetest.get_current_modname()) -local S, NS = dofile(MP.."/intllib.lua") +local S = ropes.S if ropes.ropeLadderLength > 0 then minetest.register_craft({