AntumDeluge 2017-06-20 22:31:49 -07:00
parent 997a7e7648
commit 1d031f3204
11 changed files with 694 additions and 0 deletions

View File

@ -48,6 +48,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
* [jukebox][] ([WTFPL / CC0][lic.jukebox]) -- version: [e6a507f Git][ver.jukebox] *2016-05-23*
* [trampoline][] ([GPL][lic.gpl3.0]) -- version: [ab1c289 Git][ver.trampoline] *2017-05-26*
* [trash_can][] ([MIT][lic.trash_can]) -- version: [5fd3df7 Git][ver.trash_can] *2016-01-14* ([patched][patch.trash_can])
* [intllib][] ([Unilicense][lic.unilicense]) -- version: [49e965d Git][ver.intllib] ** ([patched][patch.intllib])
* inventory/
* [bags][] ([BSD 3-Clause][lic.bags]) -- version: [f17d829 Git][ver.bags] *2015-10-11* ([patched][patch.bags])
* [inventory_plus][] ([BSD 3-Clause][lic.inventory_plus]) -- version: [fd71e3d Git][ver.inventory_plus] *2016-05-13*
@ -239,6 +240,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[hudbars]: https://forum.minetest.net/viewtopic.php?t=11153
[hudmap]: https://github.com/stujones11/hudmap
[ilights]: https://forum.minetest.net/viewtopic.php?t=12200
[intllib]: https://forum.minetest.net/viewtopic.php?t=4929
[invisibility]: https://forum.minetest.net/viewtopic.php?t=14846
[invisible]: https://forum.minetest.net/viewtopic.php?t=14399
[inventory_plus]: https://forum.minetest.net/viewtopic.php?t=3100
@ -451,6 +453,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[ver.hudbars]: http://repo.or.cz/minetest_hudbars.git/tree/bd0641a
[ver.hudmap]: https://github.com/stujones11/hudmap/tree/09d40f3
[ver.ilights]: https://github.com/minetest-mods/ilights/tree/7060243
[ver.intllib]: https://github.com/minetest-mods/intllib/tree/49e965d
[ver.inventory_plus]: https://github.com/cornernote/minetest-inventory_plus/tree/fd71e3d
[ver.invisibility]: https://github.com/tenplus1/invisibility/tree/bf4156b
[ver.jukebox]: https://github.com/minetest-mods/jukebox/tree/e6a507f
@ -538,6 +541,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[patch.hovercraft]: https://github.com/AntumMT/mtmod-hovercraft/tree/73a6223
[patch.hud]: https://github.com/AntumMT/mtmod-hud/tree/6846e20
[patch.hudbars]: https://github.com/AntumMT/mtmod-hudbars/tree/31926a0
[patch.intllib]: https://github.com/AntumMT/mtmod-intllib/tree/48d1914
[patch.invisibility]: https://github.com/AntumMT/mtmod-invisibility/tree/f045c7c
[patch.mesecons]: https://github.com/AntumMT/mtmp-mesecons/tree/830823a
[patch.minetest_game]: https://github.com/AntumMT/mtgame-minetest/tree/2e390d0

41
mods/intllib/README-es.md Normal file
View File

@ -0,0 +1,41 @@
# Bilioteca de internacionalización para Minetest
Por Diego Martínez (kaeza).
Lanzada bajo Unlicense. Véase `LICENSE.md` para más detalles.
Éste mod es un intento por proveer soporte para internacionalización
de los mods (algo que a Minetest le falta de momento).
Si tienes alguna duda/comentario, por favor publica en el
[tema del foro][topic]. Por reporte de errores, use el
[bugtracker][bugtracker] en Github.
## Cómo usar
Si eres un jugador regular en busca de textos traducidos, simplemente
[instala][installing_mods] éste mod como cualquier otro.
El mod trata de detectar tu idioma, pero ya que no hay una forma portable de
hacerlo, prueba varias alternativas:
* `language` setting in `minetest.conf`.
* `LANGUAGE` environment variable.
* `LANG` environment variable.
En cualquier caso, el resultado final debería ser el
[Código de idioma ISO 639-1][ISO639-1] del idioma deseado.
### Desarrolladores
Si desarrollas mods y estás buscando añadir soporte de internacionalización
a tu mod, ve el fichero `doc/developer.md`.
### Traductores
Si eres un traductor, ve el fichero `doc/translator.md`.
[topic]: https://forum.minetest.net/viewtopic.php?id=4929
[bugtracker]: https://github.com/minetest-mods/intllib/issues
[installing_mods]: https://wiki.minetest.net/Installing_mods/es
[ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

View File

@ -0,0 +1,50 @@
# Lib de Internacionalização para Minetest
Por Diego Martínez (kaeza).
Lançado sob Unlicense. Veja `LICENSE.md` para detalhes.
Este mod é uma tentativa de fornecer suporte de internacionalização para mods
(algo que Minetest atualmente carece).
Se você tiver algum comentário/sugestão, favor postar no
[tópico do fórum][topico]. Para reportar bugs, use o
[rastreador de bugs][bugtracker] no GitHub.
## Como usar
Se você é um jogador regular procurando por textos traduzidos,
basta instalar este mod como qualquer outro, e então habilite-lo na GUI.
O mod tenta detectar o seu idioma, mas como não há atualmente nenhuma
maneira portátil de fazer isso, ele tenta várias alternativas:
Para usar este mod, basta [instalá-lo][instalando_mods]
e habilita-lo na GUI.
O modificador tenta detectar o idioma do usuário, mas já que não há atualmente
nenhuma maneira portátil para fazer isso, ele tenta várias alternativas, e usa
o primeiro encontrado:
* `language` definido em `minetest.conf`.
* Variável de ambiente `LANGUAGE`.
* Variável de ambiente `LANG`.
* Se todos falharem, usa `en` (inglês).
Em todo caso, o resultado final deve ser um
[Código de Idioma ISO 639-1][ISO639-1] do idioma desejado.
### Desenvolvedores de mods
Se você é um desenvolvedor de mod procurando adicionar suporte de
internacionalização ao seu mod, consulte `doc/developer.md`.
### Tradutores
Se você é um tradutor, consulte `doc/translator.md`.
[topico]: https://forum.minetest.net/viewtopic.php?id=4929
[bugtracker]: https://github.com/minetest-mods/intllib/issues
[instalando_mods]: http://wiki.minetest.net/Installing_Mods/pt-br
[ISO639-1]: https://pt.wikipedia.org/wiki/ISO_639

43
mods/intllib/README.md Normal file
View File

@ -0,0 +1,43 @@
# Internationalization Lib for Minetest
By Diego Martínez (kaeza).
Released under Unlicense. See `LICENSE.md` for details.
This mod is an attempt at providing internationalization support for mods
(something Minetest currently lacks).
Should you have any comments/suggestions, please post them in the
[forum topic][topic]. For bug reports, use the [bug tracker][bugtracker]
on Github.
## How to use
If you are a regular player looking for translated texts, just
[install][installing_mods] this mod like any other one, then enable it
in the GUI.
The mod tries to detect your language, but since there's currently no
portable way to do this, it tries several alternatives:
* `language` setting in `minetest.conf`.
* `LANGUAGE` environment variable.
* `LANG` environment variable.
* If all else fails, uses `en`.
In any case, the end result should be the [ISO 639-1 Language Code][ISO639-1]
of the desired language.
### Mod developers
If you are a mod developer looking to add internationalization support to
your mod, see `doc/developer.md`.
### Translators
If you are a translator, see `doc/translator.md`.
[topic]: https://forum.minetest.net/viewtopic.php?id=4929
[bugtracker]: https://github.com/minetest-mods/intllib/issues
[installing_mods]: https://wiki.minetest.net/Installing_mods
[ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

View File

@ -0,0 +1,3 @@
Internationalization library.
This mod provides a way to internationalize/localize mods to other languages in an easy way.
See the README file for details.

226
mods/intllib/gettext.lua Normal file
View File

@ -0,0 +1,226 @@
local strsub, strrep = string.sub, string.rep
local strmatch, strgsub = string.match, string.gsub
local function trim(str)
return strmatch(str, "^%s*(.-)%s*$")
end
local escapes = { n="\n", r="\r", t="\t" }
local function unescape(str)
return (strgsub(str, "(\\+)([nrt]?)", function(bs, c)
local bsl = #bs
local realbs = strrep("\\", bsl/2)
if bsl%2 == 1 then
c = escapes[c] or c
end
return realbs..c
end))
end
local function parse_po(str)
local state, msgid, msgid_plural, msgstrind
local texts = { }
local lineno = 0
local function perror(msg)
return error(msg.." at line "..lineno)
end
for _, line in ipairs(str:split("\n")) do repeat
lineno = lineno + 1
line = trim(line)
if line == "" or strmatch(line, "^#") then
state, msgid, msgid_plural = nil, nil, nil
break -- continue
end
local mid = strmatch(line, "^%s*msgid%s*\"(.*)\"%s*$")
if mid then
if state == "id" then
return perror("unexpected msgid")
end
state, msgid = "id", unescape(mid)
break -- continue
end
mid = strmatch(line, "^%s*msgid_plural%s*\"(.*)\"%s*$")
if mid then
if state ~= "id" then
return perror("unexpected msgid_plural")
end
state, msgid_plural = "idp", unescape(mid)
break -- continue
end
local ind, mstr = strmatch(line,
"^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$")
if ind then
if not msgid then
return perror("missing msgid")
elseif ind == "" then
msgstrind = 0
elseif strmatch(ind, "%[[0-9]+%]") then
msgstrind = tonumber(strsub(ind, 2, -2))
else
return perror("malformed msgstr")
end
texts[msgid] = texts[msgid] or { }
if msgid_plural then
texts[msgid_plural] = texts[msgid]
end
texts[msgid][msgstrind] = unescape(mstr)
state = "str"
break -- continue
end
mstr = strmatch(line, "^%s*\"(.*)\"%s*$")
if mstr then
if state == "id" then
msgid = msgid..unescape(mstr)
break -- continue
elseif state == "idp" then
msgid_plural = msgid_plural..unescape(mstr)
break -- continue
elseif state == "str" then
local text = texts[msgid][msgstrind]
texts[msgid][msgstrind] = text..unescape(mstr)
break -- continue
end
end
return perror("malformed line")
-- luacheck: ignore
until true end -- end for
return texts
end
local M = { }
local function warn(msg)
minetest.log("warning", "[intllib] "..msg)
end
-- hax!
-- This function converts a C expression to an equivalent Lua expression.
-- It handles enough stuff to parse the `Plural-Forms` header correctly.
-- Note that it assumes the C expression is valid to begin with.
local function compile_plural_forms(str)
local plural = strmatch(str, "plural=([^;]+);?$")
local function replace_ternary(s)
local c, t, f = strmatch(s, "^(.-)%?(.-):(.*)")
if c then
return ("__if("
..replace_ternary(c)
..","..replace_ternary(t)
..","..replace_ternary(f)
..")")
end
return s
end
plural = replace_ternary(plural)
plural = strgsub(plural, "&&", " and ")
plural = strgsub(plural, "||", " or ")
plural = strgsub(plural, "!=", "~=")
plural = strgsub(plural, "!", " not ")
local f, err = loadstring([[
local function __if(c, t, f)
if c and c~=0 then return t else return f end
end
local function __f(n)
return (]]..plural..[[)
end
return (__f(...))
]])
if not f then return nil, err end
local env = { }
env._ENV, env._G = env, env
setfenv(f, env)
return function(n)
local v = f(n)
if type(v) == "boolean" then
-- Handle things like a plain `n != 1`
v = v and 1 or 0
end
return v
end
end
local function parse_headers(str)
local headers = { }
for _, line in ipairs(str:split("\n")) do
local k, v = strmatch(line, "^([^:]+):%s*(.*)")
if k then
headers[k] = v
end
end
return headers
end
local function load_catalog(filename)
local f, data, err
local function bail(msg)
warn(msg..(err and ": " or "")..(err or ""))
return nil
end
f, err = io.open(filename, "rb")
if not f then
return --bail("failed to open catalog")
end
data, err = f:read("*a")
f:close()
if not data then
return bail("failed to read catalog")
end
data, err = parse_po(data)
if not data then
return bail("failed to parse catalog")
end
err = nil
local hdrs = data[""]
if not (hdrs and hdrs[0]) then
return bail("catalog has no headers")
end
hdrs = parse_headers(hdrs[0])
local pf = hdrs["Plural-Forms"]
if not pf then
-- XXX: Is this right? Gettext assumes this if header not present.
pf = "nplurals=2; plural=n != 1"
end
data.plural_index, err = compile_plural_forms(pf)
if not data.plural_index then
return bail("failed to compile plural forms")
end
--warn("loaded: "..filename)
return data
end
function M.load_catalogs(path)
local langs = intllib.get_detected_languages()
local cats = { }
for _, lang in ipairs(langs) do
local cat = load_catalog(path.."/"..lang..".po")
if cat then
cats[#cats+1] = cat
end
end
return cats
end
return M

210
mods/intllib/init.lua Normal file
View File

@ -0,0 +1,210 @@
-- Old multi-load method compatibility
if rawget(_G, "intllib") then return end
intllib = {
getters = {},
strings = {},
}
local MP = minetest.get_modpath("intllib")
dofile(MP.."/lib.lua")
local LANG = minetest.settings:get("language")
if not (LANG and (LANG ~= "")) then LANG = os.getenv("LANG") end
if not (LANG and (LANG ~= "")) then LANG = "en" end
local INS_CHAR = intllib.INSERTION_CHAR
local insertion_pattern = "("..INS_CHAR.."?)"..INS_CHAR.."(%(?)(%d+)(%)?)"
local function do_replacements(str, ...)
local args = {...}
-- Outer parens discard extra return values
return (str:gsub(insertion_pattern, function(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return INS_CHAR..open..num..close
end
end))
end
local function make_getter(msgstrs)
return function(s, ...)
local str
if msgstrs then
str = msgstrs[s]
end
if not str or str == "" then
str = s
end
if select("#", ...) == 0 then
return str
end
return do_replacements(str, ...)
end
end
local function Getter(modname)
modname = modname or minetest.get_current_modname()
if not intllib.getters[modname] then
local msgstr = intllib.get_strings(modname)
intllib.getters[modname] = make_getter(msgstr)
end
return intllib.getters[modname]
end
function intllib.Getter(modname)
minetest.log("deprecated", "intllib.Getter is deprecated."
.."Please use intllib.make_gettext_pair instead.")
return Getter(modname)
end
local strfind, strsub = string.find, string.sub
local langs
local function split(str, sep)
local pos, endp = 1, #str+1
return function()
if (not pos) or pos > endp then return end
local s, e = strfind(str, sep, pos, true)
local part = strsub(str, pos, s and s-1)
pos = e and e + 1
return part
end
end
function intllib.get_detected_languages()
if langs then return langs end
langs = { }
local function addlang(l)
local sep
langs[#langs+1] = l
sep = strfind(l, ".", 1, true)
if sep then
l = strsub(l, 1, sep-1)
langs[#langs+1] = l
end
sep = strfind(l, "_", 1, true)
if sep then
langs[#langs+1] = strsub(l, 1, sep-1)
end
end
local v
v = minetest.settings:get("language")
if v and v~="" then
addlang(v)
end
v = os.getenv("LANGUAGE")
if v then
for item in split(v, ":") do
langs[#langs+1] = item
end
end
v = os.getenv("LANG")
if v then
addlang(v)
end
langs[#langs+1] = "en"
return langs
end
local gettext = dofile(minetest.get_modpath("intllib").."/gettext.lua")
local function catgettext(catalogs, msgid)
for _, cat in ipairs(catalogs) do
local msgstr = cat and cat[msgid]
if msgstr and msgstr~="" then
local msg = msgstr[0]
return msg~="" and msg or nil
end
end
end
local function catngettext(catalogs, msgid, msgid_plural, n)
n = math.floor(n)
for _, cat in ipairs(catalogs) do
local msgstr = cat and cat[msgid]
if msgstr then
local index = cat.plural_index(n)
local msg = msgstr[index]
return msg~="" and msg or nil
end
end
return n==1 and msgid or msgid_plural
end
local gettext_getters = { }
function intllib.make_gettext_pair(modname)
modname = modname or minetest.get_current_modname()
if gettext_getters[modname] then
return unpack(gettext_getters[modname])
end
local localedir = minetest.get_modpath(modname).."/locale"
local catalogs = gettext.load_catalogs(localedir)
local getter = Getter(modname)
local function gettext_func(msgid, ...)
local msgstr = (catgettext(catalogs, msgid)
or getter(msgid))
return do_replacements(msgstr, ...)
end
local function ngettext_func(msgid, msgid_plural, n, ...)
local msgstr = (catngettext(catalogs, msgid, msgid_plural, n)
or getter(msgid))
return do_replacements(msgstr, ...)
end
gettext_getters[modname] = { gettext_func, ngettext_func }
return gettext_func, ngettext_func
end
local function get_locales(code)
local ll, cc = code:match("^(..)_(..)")
if ll then
return { ll.."_"..cc, ll, ll~="en" and "en" or nil }
else
return { code, code~="en" and "en" or nil }
end
end
function intllib.get_strings(modname, langcode)
langcode = langcode or LANG
modname = modname or minetest.get_current_modname()
local msgstr = intllib.strings[modname]
if not msgstr then
local modpath = minetest.get_modpath(modname)
msgstr = { }
for _, l in ipairs(get_locales(langcode)) do
local t = intllib.load_strings(modpath.."/locale/"..l..".txt") or { }
for k, v in pairs(t) do
msgstr[k] = msgstr[k] or v
end
end
intllib.strings[modname] = msgstr
end
return msgstr
end

3
mods/intllib/intllib.lua Normal file
View File

@ -0,0 +1,3 @@
-- Support for the old multi-load method
dofile(minetest.get_modpath("intllib").."/init.lua")

67
mods/intllib/lib.lua Normal file
View File

@ -0,0 +1,67 @@
intllib = intllib or {}
local INS_CHAR = "@"
intllib.INSERTION_CHAR = INS_CHAR
local escapes = {
["\\"] = "\\",
["n"] = "\n",
["s"] = " ",
["t"] = "\t",
["r"] = "\r",
["f"] = "\f",
[INS_CHAR] = INS_CHAR..INS_CHAR,
}
local function unescape(str)
local parts = {}
local n = 1
local function add(s)
parts[n] = s
n = n + 1
end
local start = 1
while true do
local pos = str:find("\\", start, true)
if pos then
add(str:sub(start, pos - 1))
else
add(str:sub(start))
break
end
local c = str:sub(pos + 1, pos + 1)
add(escapes[c] or c)
start = pos + 2
end
return table.concat(parts)
end
local function find_eq(s)
for slashes, pos in s:gmatch("([\\]*)=()") do
if (slashes:len() % 2) == 0 then
return pos - 1
end
end
end
function intllib.load_strings(filename)
local file, err = io.open(filename, "r")
if not file then
return nil, err
end
local strings = {}
for line in file:lines() do
line = line:trim()
if line ~= "" and line:sub(1, 1) ~= "#" then
local pos = find_eq(line)
if pos then
local msgid = unescape(line:sub(1, pos - 1):trim())
strings[msgid] = unescape(line:sub(pos + 1):trim())
end
end
end
file:close()
return strings
end

View File

@ -0,0 +1,45 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- 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

2
mods/intllib/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = intllib