Codebase list minetest-mod-intllib / c714733
New upstream version 20180811 Julien Puydt 5 years ago
31 changed file(s) with 1534 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 .*
1 _*
2 *~
0
1 read_globals = {
2 "minetest",
3 }
4
5 globals = {
6 "intllib",
7 }
8
9 files["intltest/init.lua"] = {
10 ignore = {
11 "212", -- Unused argument.
12 },
13 }
0
1 This is free and unencumbered software released into the public domain.
2
3 Anyone is free to copy, modify, publish, use, compile, sell, or
4 distribute this software, either in source code form or as a compiled
5 binary, for any purpose, commercial or non-commercial, and by any
6 means.
7
8 In jurisdictions that recognize copyright laws, the author or authors
9 of this software dedicate any and all copyright interest in the
10 software to the public domain. We make this dedication for the benefit
11 of the public at large and to the detriment of our heirs and
12 successors. We intend this dedication to be an overt act of
13 relinquishment in perpetuity of all present and future rights to this
14 software under copyright law.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 OTHER DEALINGS IN THE SOFTWARE.
23
24 For more information, please refer to <http://unlicense.org/>
0
1 # Bilioteca de internacionalización para Minetest
2
3 Por Diego Martínez (kaeza).
4 Lanzada bajo Unlicense. Véase `LICENSE.md` para más detalles.
5
6 Éste mod es un intento por proveer soporte para internacionalización
7 de los mods (algo que a Minetest le falta de momento).
8
9 Si tienes alguna duda/comentario, por favor publica en el
10 [tema del foro][topic]. Por reporte de errores, use el
11 [bugtracker][bugtracker] en Github.
12
13 ## Cómo usar
14
15 Si eres un jugador regular en busca de textos traducidos, simplemente
16 [instala][installing_mods] éste mod como cualquier otro.
17
18 El mod trata de detectar tu idioma, pero ya que no hay una forma portable de
19 hacerlo, prueba varias alternativas:
20
21 * `language` setting in `minetest.conf`.
22 * `LANGUAGE` environment variable.
23 * `LANG` environment variable.
24
25 En cualquier caso, el resultado final debería ser el
26 [Código de idioma ISO 639-1][ISO639-1] del idioma deseado.
27
28 ### Desarrolladores
29
30 Si desarrollas mods y estás buscando añadir soporte de internacionalización
31 a tu mod, ve el fichero `doc/developer.md`.
32
33 ### Traductores
34
35 Si eres un traductor, ve el fichero `doc/translator.md`.
36
37 [topic]: https://forum.minetest.net/viewtopic.php?id=4929
38 [bugtracker]: https://github.com/minetest-mods/intllib/issues
39 [installing_mods]: https://wiki.minetest.net/Installing_mods/es
40 [ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
0
1 # Libreria di internazionalizzazione per Minetest
2
3 Di Diego Martínez (kaeza).
4 Rilasciata sotto licenza Unlicense. Si veda `LICENSE.md` per i dettagli.
5
6 Questo modulo è un tentativo per fornire il supporto di internazionalizzazione
7 per i moduli (cosa che attualmente manca a Minetest).
8
9 Se aveste qualunque commento o suggerimento, per piacere scriveteli nella
10 [discussione sul forum][topic]. Per i rapporti sui bug, usate il
11 [tracciatore di bug][bugtracker] su Github.
12
13 ## Come usarla
14
15 Se siete un* giocatrice/tore che vuole i testi tradotti,
16 [installate][installing_mods] questo modulo come qualunque altro,
17 poi abilitatelo tramite l'interfaccia grafica.
18
19 Il modulo tenta di rilevare la vostra lingua, ma dato che al momento non c'è
20 un metodo portabile per farlo, prova diverse alternative:
21
22 * `language` impostazione in `minetest.conf`.
23 * `LANGUAGE` variabile d'ambiente.
24 * `LANG` variabile d'ambiente.
25 * Se nessuna funziona, usa `en`.
26
27 In ogni caso, il risultato finale dovrebbe essere il
28 [codice di lingua ISO 639-1][ISO639-1] del linguaggio desiderato.
29
30 ### Sviluppatrici/tori di moduli
31
32 Se siete un* sviluppatrice/tore di moduli desideros* di aggiungere il supporto
33 per l'internazionalizzazione al vostro modulo, leggete `doc/developer-it.md`.
34
35 ### Traduttrici/tori
36
37 Se siete un* traduttrice/tore, leggete `doc/translator-it.md`.
38
39 [topic]: https://forum.minetest.net/viewtopic.php?id=4929
40 [bugtracker]: https://github.com/minetest-mods/intllib/issues
41 [installing_mods]: https://wiki.minetest.net/Installing_mods
42 [ISO639-1]: https://it.wikipedia.org/wiki/ISO_639-1
0
1 # Pustaka Pengantarabangsaan untuk Minetest
2
3 Oleh Diego Martínez (kaeza).
4 Diterbitkan bawah Unlicense. Lihat `LICENSE.md` untuk maklumat lanjut.
5
6 Mods ini ialah suatu usaha untuk menyediakan sokongan pengantarabangsaan
7 kepada mods (sesuatu yang Minetest tiada ketika ini).
8
9 Jika anda mempunyai sebarang komen/cadangan, sila tulis ke dalam [topik forum][topik].
10 Untuk melaporkan pepijat, sila gunakan [penjejak pepijat][pepijat] Github.
11
12 ## Bagaimanakah cara untuk menggunakannya?
13
14 Jika anda pemain biasa yang mencari teks terjemahan, hanya [pasangkan][pasang_mods]
15 mods ini seperti mods lain, kemudian bolehkannya melalui GUI.
16
17 Mods ini cuba untuk mengesan bahasa anda, tetapi oleh kerana tiada
18 cara mudah alih untuk melakukannya, ia cuba beberapa cara yang lain:
19
20 * Tetapan `language` di dalam fail `minetest.conf`.
21 * Pembolehubah sekitaran `LANGUAGE`.
22 * Pembolehubah sekitaran `LANG`.
23 * Jika semua di atas gagal, ia gunakan `en`.
24
25 Dalam apa jua keadaan, hasil akhirnya sepatutnya menjadi
26 [Kod Bahasa ISO 639-1][ISO639-1] untuk bahasa yang dikehendaki.
27
28 ### Pembangun mods
29
30 Jika anda seorang pembangun mods yang ingin menambah sokongan
31 pengantarabangsaan kepada mods anda, sila lihat `doc/developer.md`.
32
33 ### Penterjemah
34
35 Jika anda seorang penterjemah, sila lihat `doc/translator.md`.
36
37 [topik]: https://forum.minetest.net/viewtopic.php?id=4929
38 [pepijat]: https://github.com/minetest-mods/intllib/issues
39 [pasang_mods]: https://wiki.minetest.net/Installing_Mods/ms
40 [ISO639-1]: https://ms.wikipedia.org/wiki/Senarai_kod_ISO_639-1
0 # Lib de Internacionalização para Minetest
1
2 Por Diego Martínez (kaeza).
3 Lançado sob Unlicense. Veja `LICENSE.md` para detalhes.
4
5 Este mod é uma tentativa de fornecer suporte de internacionalização para mods
6 (algo que Minetest atualmente carece).
7
8
9 Se você tiver algum comentário/sugestão, favor postar no
10 [tópico do fórum][topico]. Para reportar bugs, use o
11 [rastreador de bugs][bugtracker] no GitHub.
12
13
14 ## Como usar
15
16 Se você é um jogador regular procurando por textos traduzidos,
17 basta instalar este mod como qualquer outro, e então habilite-lo na GUI.
18
19 O mod tenta detectar o seu idioma, mas como não há atualmente nenhuma
20 maneira portátil de fazer isso, ele tenta várias alternativas:
21
22 Para usar este mod, basta [instalá-lo][instalando_mods]
23 e habilita-lo na GUI.
24
25 O modificador tenta detectar o idioma do usuário, mas já que não há atualmente
26 nenhuma maneira portátil para fazer isso, ele tenta várias alternativas, e usa
27 o primeiro encontrado:
28
29 * `language` definido em `minetest.conf`.
30 * Variável de ambiente `LANGUAGE`.
31 * Variável de ambiente `LANG`.
32 * Se todos falharem, usa `en` (inglês).
33
34 Em todo caso, o resultado final deve ser um
35 [Código de Idioma ISO 639-1][ISO639-1] do idioma desejado.
36
37 ### Desenvolvedores de mods
38
39 Se você é um desenvolvedor de mod procurando adicionar suporte de
40 internacionalização ao seu mod, consulte `doc/developer.md`.
41
42 ### Tradutores
43
44 Se você é um tradutor, consulte `doc/translator.md`.
45
46 [topico]: https://forum.minetest.net/viewtopic.php?id=4929
47 [bugtracker]: https://github.com/minetest-mods/intllib/issues
48 [instalando_mods]: http://wiki.minetest.net/Installing_Mods/pt-br
49 [ISO639-1]: https://pt.wikipedia.org/wiki/ISO_639
0
1 # Internationalization Lib for Minetest
2
3 By Diego Martínez (kaeza).
4 Released under Unlicense. See `LICENSE.md` for details.
5
6 This mod is an attempt at providing internationalization support for mods
7 (something Minetest currently lacks).
8
9 Should you have any comments/suggestions, please post them in the
10 [forum topic][topic]. For bug reports, use the [bug tracker][bugtracker]
11 on Github.
12
13 ## How to use
14
15 If you are a regular player looking for translated texts, just
16 [install][installing_mods] this mod like any other one, then enable it
17 in the GUI.
18
19 The mod tries to detect your language, but since there's currently no
20 portable way to do this, it tries several alternatives:
21
22 * `language` setting in `minetest.conf`.
23 * `LANGUAGE` environment variable.
24 * `LANG` environment variable.
25 * If all else fails, uses `en`.
26
27 In any case, the end result should be the [ISO 639-1 Language Code][ISO639-1]
28 of the desired language.
29
30 ### Mod developers
31
32 If you are a mod developer looking to add internationalization support to
33 your mod, see `doc/developer.md`.
34
35 ### Translators
36
37 If you are a translator, see `doc/translator.md`.
38
39 [topic]: https://forum.minetest.net/viewtopic.php?id=4929
40 [bugtracker]: https://github.com/minetest-mods/intllib/issues
41 [installing_mods]: https://wiki.minetest.net/Installing_mods
42 [ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
0 Internationalization library.
1 This mod provides a way to internationalize/localize mods to other languages in an easy way.
2 See the README file for details.
0
1 # Intllib - documentazione per sviluppatrici/tori
2
3 ## Abilitare l'internazionalizzazione
4
5 Per abilitare l'internazionalizzazione del vostro modulo, dovete copiare il file
6 `lib/intllib.lua` nella cartella principale del vostro modulo, poi inserite
7 questo codice standard nei file che necessitano la traduzione:
8
9 -- Load support for intllib.
10 local MP = minetest.get_modpath(minetest.get_current_modname())
11 local S, NS = dofile(MP.."/intllib.lua")
12
13 Dovrete anche aggiungere la dipendenza facoltativa da intllib per il vostro
14 modulo, per farlo aggiungete `intllib?` su una riga vuota nel vostro
15 `depends.txt`. Si noti anche che se intllib non è installata, le funzioni di
16 acquisizione del testo sono fatte in modo da restituire la stringa di testo
17 originale. Questo è stato fatto in modo che non dobbiate spargere tonnellate
18 di `if` (o costrutti simili) per controllare se la libreria è installata.
19
20 Dopo avere messo il codice, dovete marcare le stringhe di testo che necessitano
21 una traduzione. Per ciascuna stringa traducibile nei vostri codici sorgenti,
22 usate la funzione `S` (si veda sopra) per restituire la stringa tradotta.
23 Per esempio:
24
25 minetest.register_node("miomod:mionodo", {
26 -- Stringa semplice:
27 description = S("Il mio fantastico nodo"),
28 -- Stringa con inserti:
29 description = S("Macchina @1", "Blu"),
30 -- ...
31 })
32
33 La funzione `NS` è l'equivalente di `ngettext`. Dovrebbe essere usata quando la
34 stringa da tradurre ha forma singolare e plurale. Per esempio:
35
36 -- Il primo `count` è per consentire a `ngettext` di stabilire quale forma
37 -- usare. Il secondo `count` è per il sostituto effettivo.
38
39 print(NS("Avete un oggetto.", "Avete @1 oggetti.", count, count))
40
41 ## Generare e aggiornare cataloghi
42
43 Questo è il procedimento di base per lavorare con [gettext][gettext]
44
45 Ogni volta che avete nuove stringhe da tradurre, dovreste fare quanto segue:
46
47 cd /percorso/del/modulo
48 /percorso/degli/strumenti/intllib/xgettext.sh file1.lua file2.lua ...
49
50 Lo script creerà una cartella chiamata `locale` se non esiste già, e genererà
51 il file `template.pot` (un modello con tutte le stringhe traducibili). Se avete
52 già delle traduzioni, lo script provvederà al loro aggiornamento con le nuove
53 stringhe.
54
55 Lo script fornisce alcune opzioni al vero `xgettext` che dovrebbero essere
56 sufficienti per la maggior parte dei casi. Se lo desiderate potete specificare
57 altre opzioni:
58
59 xgettext.sh -o file.pot --keyword=blaaaah:4,5 a.lua b.lua ...
60
61 NOTA: C'è anche un file batch di Windows `xgettext.bat` per gli utenti di
62 Windows, ma dovrete installare separatamente gli strumenti di gettext per la
63 riga di comando. Si veda la parte superiore del file per la configurazione.
64
65 [gettext]: https://www.gnu.org/software/gettext/
0
1 # Intllib developer documentation
2
3 ## Enabling internationalization
4
5 In order to enable internationalization for your mod, you will need to copy the
6 file `lib/intllib.lua` into the root directory of your mod, then include this
7 boilerplate code in files needing localization:
8
9 -- Load support for intllib.
10 local MP = minetest.get_modpath(minetest.get_current_modname())
11 local S, NS = dofile(MP.."/intllib.lua")
12
13 You will also need to optionally depend on intllib, to do so add `intllib?`
14 to an empty line in your `depends.txt`. Also note that if intllib is not
15 installed, the getter functions are defined so they return the string
16 unchanged. This is done so you don't have to sprinkle tons of `if`s (or
17 similar constructs) to check if the lib is actually installed.
18
19 Once you have the code in place, you need to mark strings that need
20 translation. For each translatable string in your sources, use the `S`
21 function (see above) to return the translated string. For example:
22
23 minetest.register_node("mymod:mynode", {
24 -- Simple string:
25 description = S("My Fabulous Node"),
26 -- String with insertions:
27 description = S("@1 Car", "Blue"),
28 -- ...
29 })
30
31 The `NS` function is the equivalent of `ngettext`. It should be used when the
32 string to be translated has singular and plural forms. For example:
33
34 -- The first `count` is for `ngettext` to determine which form to use.
35 -- The second `count` is the actual replacement.
36 print(NS("You have one item.", "You have @1 items.", count, count))
37
38 ## Generating and updating catalogs
39
40 This is the basic workflow for working with [gettext][gettext]
41
42 Each time you have new strings to be translated, you should do the following:
43
44 cd /path/to/mod
45 /path/to/intllib/tools/xgettext.sh file1.lua file2.lua ...
46
47 The script will create a directory named `locale` if it doesn't exist yet,
48 and will generate the file `template.pot` (a template with all the translatable
49 strings). If you already have translations, the script will proceed to update
50 all of them with the new strings.
51
52 The script passes some options to the real `xgettext` that should be enough
53 for most cases. You may specify other options if desired:
54
55 xgettext.sh -o file.pot --keyword=blargh:4,5 a.lua b.lua ...
56
57 NOTE: There's also a Windows batch file `xgettext.bat` for Windows users,
58 but you will need to install the gettext command line tools separately. See
59 the top of the file for configuration.
60
61 [gettext]: https://www.gnu.org/software/gettext/
0
1 # Formato del file di traduzione
2
3 *Nota: Questo documento spiega il vecchio formato in stile conf/ini.
4 La nuova interfaccia usa file [gettext][gettext] `.po`.
5 Si veda [Il formato dei file PO][PO-Files] per ulteriori informazioni.*
6
7 Questo è un esempio per un file di traduzione in Italiano (`it.txt`):
8
9 # Un commento.
10 # Un altro commento.
11 Questa riga viene ignorata dato che non ha il segno di uguale.
12 Hello, World! = Ciao, Mondo!
13 String with\nnewlines = Stringa con\na capo
14 String with an \= equals sign = Stringa con un segno di uguaglianza \=
15
16 I file "locale" (o di traduzione) sono file di testo semplice formati da righe
17 nel formato `testo originale = testo tradotto`. Il file deve stare nella
18 sottocartella `locale` del modulo, e il suo nome deve essere lo stesso del
19 [codice di lingua ISO 639-1][ISO639-1] della lingua che volete fornire.
20
21 I file di traduzione dovrebbero usare la codifica UTF-8.
22
23 Le righe che iniziano con un cancelletto sono commenti e vengono ignorate dal
24 lettore. Si noti che i commenti si estendono solo fino al termine della riga;
25 non c'è nessun supporto per i commenti multiriga. Le righe senza un segno di
26 uguale sono anch'esse ignorate.
27
28 I caratteri che sono considerati "speciali" possono essere "escaped" di modo
29 che siano presi letteralmente. Inoltre esistono molte sequenze di escape che
30 possono essere utilizzate:
31
32 * Qualsiasi `#`, `=` può essere escaped di modo da essere preso letteralmente.
33 La sequenza `\#` è utile se il vostro testo sorgente inizia con `#`.
34 * Le sequenze di escape comuni `\n` e `\t`, significano rispettivamente
35 newline (a capo) e tabulazione orizzontale.
36 * La sequenza speciale di escape`\s` rappresenta il carattere di spazio.
37 È utile principalmente per aggiungere spazi prefissi o suffissi ai testi
38 originali o tradotti, perché altrimenti quegli spazi verrebbero rimossi.
39
40 [gettext]: https://www.gnu.org/software/gettext
41 [PO-Files]: https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
42 [ISO639-1]: https://it.wikipedia.org/wiki/ISO_639-1
0
1 # Locale file format
2
3 *Note: This document explains the old conf/ini-like file format.
4 The new interface uses [gettext][gettext] `.po` files.
5 See [The Format of PO Files][PO-Files] for more information.*
6
7 Here's an example for a Spanish locale file (`es.txt`):
8
9 # A comment.
10 # Another comment.
11 This line is ignored since it has no equals sign.
12 Hello, World! = Hola, Mundo!
13 String with\nnewlines = Cadena con\nsaltos de linea
14 String with an \= equals sign = Cadena con un signo de \= igualdad
15
16 Locale (or translation) files are plain text files consisting of lines of the
17 form `source text = translated text`. The file must reside in the mod's `locale`
18 subdirectory, and must be named after the two-letter
19 [ISO 639-1 Language Code][ISO639-1] of the language you want to support.
20
21 The translation files should use the UTF-8 encoding.
22
23 Lines beginning with a pound sign are comments and are effectively ignored
24 by the reader. Note that comments only span until the end of the line;
25 there's no support for multiline comments. Lines without an equals sign are
26 also ignored.
27
28 Characters that are considered "special" can be "escaped" so they are taken
29 literally. There are also several escape sequences that can be used:
30
31 * Any of `#`, `=` can be escaped to take them literally. The `\#`
32 sequence is useful if your source text begins with `#`.
33 * The common escape sequences `\n` and `\t`, meaning newline and
34 horizontal tab respectively.
35 * The special `\s` escape sequence represents the space character. It
36 is mainly useful to add leading or trailing spaces to source or
37 translated texts, as these spaces would be removed otherwise.
38
39 [gettext]: https://www.gnu.org/software/gettext
40 [PO-Files]: https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
41 [ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
0
1 # Intllib - documentazione per traduttrici/tori
2
3 #### Nuova interfaccia
4
5 Usate i vostri strumenti preferiti per modificare i file `.po`.
6
7 #### Vecchia interfaccia
8
9 Per tradurre nella lingua che desiderate un modulo che supporta intllib,
10 copiate il file `locale/template.txt` come `locale/LINGUA.txt` (dove `LINGUA` è
11 il [codice di lingua ISO 639-1][ISO639-1] del vostro linguaggio.
12
13 Aprite il nuovo file nel vostro editor preferito, e traducete ciascuna riga
14 inserendo il testo tradotto dopo il segno di uguale.
15
16 Si veda `localefile-it.md` per ulteriori informazioni sul formato del file.
17
18 [gettext]: https://www.gnu.org/software/gettext/
19 [ISO639-1]: https://it.wikipedia.org/wiki/ISO_639-1
0
1 # Intllib translator documentation
2
3 #### New interface
4
5 Use your favorite tools to edit the `.po` files.
6
7 #### Old interface
8
9 To translate an intllib-supporting mod to your desired language, copy the
10 `locale/template.txt` file to `locale/LANGUAGE.txt` (where `LANGUAGE` is the
11 [ISO 639-1 Language Code][ISO639-1] of your language.
12
13 Open up the new file in your favorite editor, and translate each line putting
14 the translated text after the equals sign.
15
16 See `localefile.md` for more information about the file format.
17
18 [gettext]: https://www.gnu.org/software/gettext/
19 [ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
0
1 local strsub, strrep = string.sub, string.rep
2 local strmatch, strgsub = string.match, string.gsub
3
4 local function trim(str)
5 return strmatch(str, "^%s*(.-)%s*$")
6 end
7
8 local escapes = { n="\n", r="\r", t="\t" }
9
10 local function unescape(str)
11 return (strgsub(str, "(\\+)([nrt]?)", function(bs, c)
12 local bsl = #bs
13 local realbs = strrep("\\", bsl/2)
14 if bsl%2 == 1 then
15 c = escapes[c] or c
16 end
17 return realbs..c
18 end))
19 end
20
21 local function parse_po(str)
22 local state, msgid, msgid_plural, msgstrind
23 local texts = { }
24 local lineno = 0
25 local function perror(msg)
26 return error(msg.." at line "..lineno)
27 end
28 for _, line in ipairs(str:split("\n")) do repeat
29 lineno = lineno + 1
30 line = trim(line)
31
32 if line == "" or strmatch(line, "^#") then
33 state, msgid, msgid_plural = nil, nil, nil
34 break -- continue
35 end
36
37 local mid = strmatch(line, "^%s*msgid%s*\"(.*)\"%s*$")
38 if mid then
39 if state == "id" then
40 return perror("unexpected msgid")
41 end
42 state, msgid = "id", unescape(mid)
43 break -- continue
44 end
45
46 mid = strmatch(line, "^%s*msgid_plural%s*\"(.*)\"%s*$")
47 if mid then
48 if state ~= "id" then
49 return perror("unexpected msgid_plural")
50 end
51 state, msgid_plural = "idp", unescape(mid)
52 break -- continue
53 end
54
55 local ind, mstr = strmatch(line,
56 "^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$")
57 if ind then
58 if not msgid then
59 return perror("missing msgid")
60 elseif ind == "" then
61 msgstrind = 0
62 elseif strmatch(ind, "%[[0-9]+%]") then
63 msgstrind = tonumber(strsub(ind, 2, -2))
64 else
65 return perror("malformed msgstr")
66 end
67 texts[msgid] = texts[msgid] or { }
68 if msgid_plural then
69 texts[msgid_plural] = texts[msgid]
70 end
71 texts[msgid][msgstrind] = unescape(mstr)
72 state = "str"
73 break -- continue
74 end
75
76 mstr = strmatch(line, "^%s*\"(.*)\"%s*$")
77 if mstr then
78 if state == "id" then
79 msgid = msgid..unescape(mstr)
80 break -- continue
81 elseif state == "idp" then
82 msgid_plural = msgid_plural..unescape(mstr)
83 break -- continue
84 elseif state == "str" then
85 local text = texts[msgid][msgstrind]
86 texts[msgid][msgstrind] = text..unescape(mstr)
87 break -- continue
88 end
89 end
90
91 return perror("malformed line")
92
93 -- luacheck: ignore
94 until true end -- end for
95
96 return texts
97 end
98
99 local M = { }
100
101 local function warn(msg)
102 minetest.log("warning", "[intllib] "..msg)
103 end
104
105 -- hax!
106 -- This function converts a C expression to an equivalent Lua expression.
107 -- It handles enough stuff to parse the `Plural-Forms` header correctly.
108 -- Note that it assumes the C expression is valid to begin with.
109 local function compile_plural_forms(str)
110 local plural = strmatch(str, "plural=([^;]+);?$")
111 local function replace_ternary(s)
112 local c, t, f = strmatch(s, "^(.-)%?(.-):(.*)")
113 if c then
114 return ("__if("
115 ..replace_ternary(c)
116 ..","..replace_ternary(t)
117 ..","..replace_ternary(f)
118 ..")")
119 end
120 return s
121 end
122 plural = replace_ternary(plural)
123 plural = strgsub(plural, "&&", " and ")
124 plural = strgsub(plural, "||", " or ")
125 plural = strgsub(plural, "!=", "~=")
126 plural = strgsub(plural, "!", " not ")
127 local f, err = loadstring([[
128 local function __if(c, t, f)
129 if c and c~=0 then return t else return f end
130 end
131 local function __f(n)
132 return (]]..plural..[[)
133 end
134 return (__f(...))
135 ]])
136 if not f then return nil, err end
137 local env = { }
138 env._ENV, env._G = env, env
139 setfenv(f, env)
140 return function(n)
141 local v = f(n)
142 if type(v) == "boolean" then
143 -- Handle things like a plain `n != 1`
144 v = v and 1 or 0
145 end
146 return v
147 end
148 end
149
150 local function parse_headers(str)
151 local headers = { }
152 for _, line in ipairs(str:split("\n")) do
153 local k, v = strmatch(line, "^([^:]+):%s*(.*)")
154 if k then
155 headers[k] = v
156 end
157 end
158 return headers
159 end
160
161 local function load_catalog(filename)
162 local f, data, err
163
164 local function bail(msg)
165 warn(msg..(err and ": " or "")..(err or ""))
166 return nil
167 end
168
169 f, err = io.open(filename, "rb")
170 if not f then
171 return --bail("failed to open catalog")
172 end
173
174 data, err = f:read("*a")
175
176 f:close()
177
178 if not data then
179 return bail("failed to read catalog")
180 end
181
182 data, err = parse_po(data)
183 if not data then
184 return bail("failed to parse catalog")
185 end
186
187 err = nil
188 local hdrs = data[""]
189 if not (hdrs and hdrs[0]) then
190 return bail("catalog has no headers")
191 end
192
193 hdrs = parse_headers(hdrs[0])
194
195 local pf = hdrs["Plural-Forms"]
196 if not pf then
197 -- XXX: Is this right? Gettext assumes this if header not present.
198 pf = "nplurals=2; plural=n != 1"
199 end
200
201 data.plural_index, err = compile_plural_forms(pf)
202 if not data.plural_index then
203 return bail("failed to compile plural forms")
204 end
205
206 --warn("loaded: "..filename)
207
208 return data
209 end
210
211 function M.load_catalogs(path)
212 local langs = intllib.get_detected_languages()
213
214 local cats = { }
215 for _, lang in ipairs(langs) do
216 local cat = load_catalog(path.."/"..lang..".po")
217 if cat then
218 cats[#cats+1] = cat
219 end
220 end
221
222 return cats
223 end
224
225 return M
0
1 -- Old multi-load method compatibility
2 if rawget(_G, "intllib") then return end
3
4 intllib = {
5 getters = {},
6 strings = {},
7 }
8
9
10 local MP = minetest.get_modpath("intllib")
11
12 dofile(MP.."/lib.lua")
13
14
15 local LANG = minetest.settings:get("language")
16 if not (LANG and (LANG ~= "")) then LANG = os.getenv("LANG") end
17 if not (LANG and (LANG ~= "")) then LANG = "en" end
18
19
20 local INS_CHAR = intllib.INSERTION_CHAR
21 local insertion_pattern = "("..INS_CHAR.."?)"..INS_CHAR.."(%(?)(%d+)(%)?)"
22
23 local function do_replacements(str, ...)
24 local args = {...}
25 -- Outer parens discard extra return values
26 return (str:gsub(insertion_pattern, function(escape, open, num, close)
27 if escape == "" then
28 local replacement = tostring(args[tonumber(num)])
29 if open == "" then
30 replacement = replacement..close
31 end
32 return replacement
33 else
34 return INS_CHAR..open..num..close
35 end
36 end))
37 end
38
39 local function make_getter(msgstrs)
40 return function(s, ...)
41 local str
42 if msgstrs then
43 str = msgstrs[s]
44 end
45 if not str or str == "" then
46 str = s
47 end
48 if select("#", ...) == 0 then
49 return str
50 end
51 return do_replacements(str, ...)
52 end
53 end
54
55
56 local function Getter(modname)
57 modname = modname or minetest.get_current_modname()
58 if not intllib.getters[modname] then
59 local msgstr = intllib.get_strings(modname)
60 intllib.getters[modname] = make_getter(msgstr)
61 end
62 return intllib.getters[modname]
63 end
64
65
66 function intllib.Getter(modname)
67 local info = debug and debug.getinfo and debug.getinfo(2)
68 local loc = info and info.short_src..":"..info.currentline
69 minetest.log("deprecated", "intllib.Getter is deprecated."
70 .." Please use intllib.make_gettext_pair instead."
71 ..(info and " (called from "..loc..")" or ""))
72 return Getter(modname)
73 end
74
75
76 local strfind, strsub = string.find, string.sub
77 local langs
78
79 local function split(str, sep)
80 local pos, endp = 1, #str+1
81 return function()
82 if (not pos) or pos > endp then return end
83 local s, e = strfind(str, sep, pos, true)
84 local part = strsub(str, pos, s and s-1)
85 pos = e and e + 1
86 return part
87 end
88 end
89
90 function intllib.get_detected_languages()
91 if langs then return langs end
92
93 langs = { }
94
95 local function addlang(l)
96 local sep
97 langs[#langs+1] = l
98 sep = strfind(l, ".", 1, true)
99 if sep then
100 l = strsub(l, 1, sep-1)
101 langs[#langs+1] = l
102 end
103 sep = strfind(l, "_", 1, true)
104 if sep then
105 langs[#langs+1] = strsub(l, 1, sep-1)
106 end
107 end
108
109 local v
110
111 v = minetest.settings:get("language")
112 if v and v~="" then
113 addlang(v)
114 end
115
116 v = os.getenv("LANGUAGE")
117 if v then
118 for item in split(v, ":") do
119 langs[#langs+1] = item
120 end
121 end
122
123 v = os.getenv("LANG")
124 if v then
125 addlang(v)
126 end
127
128 langs[#langs+1] = "en"
129
130 return langs
131 end
132
133
134 local gettext = dofile(minetest.get_modpath("intllib").."/gettext.lua")
135
136
137 local function catgettext(catalogs, msgid)
138 for _, cat in ipairs(catalogs) do
139 local msgstr = cat and cat[msgid]
140 if msgstr and msgstr~="" then
141 local msg = msgstr[0]
142 return msg~="" and msg or nil
143 end
144 end
145 end
146
147 local function catngettext(catalogs, msgid, msgid_plural, n)
148 n = math.floor(n)
149 for _, cat in ipairs(catalogs) do
150 local msgstr = cat and cat[msgid]
151 if msgstr then
152 local index = cat.plural_index(n)
153 local msg = msgstr[index]
154 return msg~="" and msg or nil
155 end
156 end
157 return n==1 and msgid or msgid_plural
158 end
159
160
161 local gettext_getters = { }
162 function intllib.make_gettext_pair(modname)
163 modname = modname or minetest.get_current_modname()
164 if gettext_getters[modname] then
165 return unpack(gettext_getters[modname])
166 end
167 local localedir = minetest.get_modpath(modname).."/locale"
168 local catalogs = gettext.load_catalogs(localedir)
169 local getter = Getter(modname)
170 local function gettext_func(msgid, ...)
171 local msgstr = (catgettext(catalogs, msgid)
172 or getter(msgid))
173 return do_replacements(msgstr, ...)
174 end
175 local function ngettext_func(msgid, msgid_plural, n, ...)
176 local msgstr = (catngettext(catalogs, msgid, msgid_plural, n)
177 or getter(msgid))
178 return do_replacements(msgstr, ...)
179 end
180 gettext_getters[modname] = { gettext_func, ngettext_func }
181 return gettext_func, ngettext_func
182 end
183
184
185 local function get_locales(code)
186 local ll, cc = code:match("^(..)_(..)")
187 if ll then
188 return { ll.."_"..cc, ll, ll~="en" and "en" or nil }
189 else
190 return { code, code~="en" and "en" or nil }
191 end
192 end
193
194
195 function intllib.get_strings(modname, langcode)
196 langcode = langcode or LANG
197 modname = modname or minetest.get_current_modname()
198 local msgstr = intllib.strings[modname]
199 if not msgstr then
200 local modpath = minetest.get_modpath(modname)
201 msgstr = { }
202 for _, l in ipairs(get_locales(langcode)) do
203 local t = intllib.load_strings(modpath.."/locale/"..l..".txt") or { }
204 for k, v in pairs(t) do
205 msgstr[k] = msgstr[k] or v
206 end
207 end
208 intllib.strings[modname] = msgstr
209 end
210 return msgstr
211 end
212
0 -- Support for the old multi-load method
1 dofile(minetest.get_modpath("intllib").."/init.lua")
2
0
1 # Intllib example
2
3 This is a simple mod showing how to use intllib.
4
5 It defines a test `intltest:test` item whose description is translated
6 according to the user's language.
7
8 Additionally, it demonstrates how to use plural forms by counting the
9 number of times the item has been used.
0
1 -- Load support for intllib.
2 local MP = minetest.get_modpath(minetest.get_current_modname())
3 local S, NS = dofile(MP.."/intllib.lua")
4
5 local use_count = 0
6
7 minetest.log("action", S("Hello, world!"))
8
9 minetest.register_craftitem("intltest:test", {
10 -- Example use of replacements.
11 -- Translators: @1 is color, @2 is object.
12 description = S("Test: @1 @2", S("Blue"), S("Car")),
13
14 inventory_image = "default_sand.png",
15
16 on_use = function(stack, user, pt)
17 use_count = use_count + 1
18 -- Example use of `ngettext` function.
19 -- First `use_count` is `n` for ngettext;
20 -- Second one is actual replacement.
21 -- Translators: @1 is use count.
22 local message = NS("Item has been used @1 time.",
23 "Item has been used @1 times.",
24 use_count, use_count)
25 minetest.chat_send_player(user:get_player_name(), message)
26 end,
27 })
0
1 -- This file should be replaced by `intllib/lib/intllib.lua`.
2 return dofile(minetest.get_modpath("intllib").."/lib/intllib.lua")
0 # I18N Test Mod.
1 # Copyright (C) 2013-2017 Diego Martínez <kaeza@users.sf.net>
2 # This file is distributed under the same license as the intllib mod.
3 # Diego Martínez <kaeza@users.sf.net>, 2013-2017.
4 #
5 msgid ""
6 msgstr ""
7 "Project-Id-Version: I18N Test Mod 0.1.0\n"
8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2017-02-25 20:40-0300\n"
10 "PO-Revision-Date: 2017-01-23 17:36-0300\n"
11 "Last-Translator: Diego Martnez <kaeza@users.sf.net>\n"
12 "Language-Team: Spanish\n"
13 "Language: es\n"
14 "MIME-Version: 1.0\n"
15 "Content-Type: text/plain; charset=UTF-8\n"
16 "Content-Transfer-Encoding: 8bit\n"
17 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
19 #: init.lua
20 msgid "Hello, world!"
21 msgstr "¡Hola, mundo!"
22
23 #. Translators: @1 is color, @2 is object.
24 #: init.lua
25 msgid "Blue"
26 msgstr "Azul"
27
28 #: init.lua
29 msgid "Car"
30 msgstr "Carro"
31
32 #. Translators: @1 is color, @2 is object.
33 #: init.lua
34 msgid "Test: @1 @2"
35 msgstr "Prueba: @2 @1"
36
37 #. Translators: @1 is use count.
38 #: init.lua
39 msgid "Item has been used @1 time."
40 msgid_plural "Item has been used @1 times."
41 msgstr[0] "El objeto ha sido usado @1 vez."
42 msgstr[1] "El objeto ha sido usado @1 veces."
0 # SOME DESCRIPTIVE TITLE.
1 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
2 # This file is distributed under the same license as the PACKAGE package.
3 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
4 #
5 #, fuzzy
6 msgid ""
7 msgstr ""
8 "Project-Id-Version: PACKAGE VERSION\n"
9 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-02-25 20:40-0300\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
14 "Language: \n"
15 "MIME-Version: 1.0\n"
16 "Content-Type: text/plain; charset=CHARSET\n"
17 "Content-Transfer-Encoding: 8bit\n"
18 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
20 #: init.lua
21 msgid "Hello, world!"
22 msgstr ""
23
24 #. Translators: @1 is color, @2 is object.
25 #: init.lua
26 msgid "Blue"
27 msgstr ""
28
29 #: init.lua
30 msgid "Car"
31 msgstr ""
32
33 #. Translators: @1 is color, @2 is object.
34 #: init.lua
35 msgid "Test: @1 @2"
36 msgstr ""
37
38 #. Translators: @1 is use count.
39 #: init.lua
40 msgid "Item has been used @1 time."
41 msgid_plural "Item has been used @1 times."
42 msgstr[0] ""
43 msgstr[1] ""
0
1 -- Fallback functions for when `intllib` is not installed.
2 -- Code released under Unlicense <http://unlicense.org>.
3
4 -- Get the latest version of this file at:
5 -- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
6
7 local function format(str, ...)
8 local args = { ... }
9 local function repl(escape, open, num, close)
10 if escape == "" then
11 local replacement = tostring(args[tonumber(num)])
12 if open == "" then
13 replacement = replacement..close
14 end
15 return replacement
16 else
17 return "@"..open..num..close
18 end
19 end
20 return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
21 end
22
23 local gettext, ngettext
24 if minetest.get_modpath("intllib") then
25 if intllib.make_gettext_pair then
26 -- New method using gettext.
27 gettext, ngettext = intllib.make_gettext_pair()
28 else
29 -- Old method using text files.
30 gettext = intllib.Getter()
31 end
32 end
33
34 -- Fill in missing functions.
35
36 gettext = gettext or function(msgid, ...)
37 return format(msgid, ...)
38 end
39
40 ngettext = ngettext or function(msgid, msgid_plural, n, ...)
41 return format(n==1 and msgid or msgid_plural, ...)
42 end
43
44 return gettext, ngettext
0
1 intllib = intllib or {}
2
3 local INS_CHAR = "@"
4 intllib.INSERTION_CHAR = INS_CHAR
5
6 local escapes = {
7 ["\\"] = "\\",
8 ["n"] = "\n",
9 ["s"] = " ",
10 ["t"] = "\t",
11 ["r"] = "\r",
12 ["f"] = "\f",
13 [INS_CHAR] = INS_CHAR..INS_CHAR,
14 }
15
16 local function unescape(str)
17 local parts = {}
18 local n = 1
19 local function add(s)
20 parts[n] = s
21 n = n + 1
22 end
23
24 local start = 1
25 while true do
26 local pos = str:find("\\", start, true)
27 if pos then
28 add(str:sub(start, pos - 1))
29 else
30 add(str:sub(start))
31 break
32 end
33 local c = str:sub(pos + 1, pos + 1)
34 add(escapes[c] or c)
35 start = pos + 2
36 end
37 return table.concat(parts)
38 end
39
40 local function find_eq(s)
41 for slashes, pos in s:gmatch("([\\]*)=()") do
42 if (slashes:len() % 2) == 0 then
43 return pos - 1
44 end
45 end
46 end
47
48 function intllib.load_strings(filename)
49 local file, err = io.open(filename, "r")
50 if not file then
51 return nil, err
52 end
53 local strings = {}
54 for line in file:lines() do
55 line = line:trim()
56 if line ~= "" and line:sub(1, 1) ~= "#" then
57 local pos = find_eq(line)
58 if pos then
59 local msgid = unescape(line:sub(1, pos - 1):trim())
60 strings[msgid] = unescape(line:sub(pos + 1):trim())
61 end
62 end
63 end
64 file:close()
65 return strings
66 end
0
1 name = intllib
0 #! /usr/bin/env lua
1
2 local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
3
4 local function err(fmt, ...)
5 io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
6 os.exit(1)
7 end
8
9 local output
10 local inputs = { }
11 local lang
12 local author
13
14 local i = 1
15
16 local function usage()
17 print([[
18 Usage: ]]..me..[[ [OPTIONS] FILE...
19
20 Extract translatable strings from the given FILE(s).
21
22 Available options:
23 -h,--help Show this help screen and exit.
24 -o,--output X Set output file (default: stdout).
25 -a,--author X Set author.
26 -l,--lang X Set language name.
27 ]])
28 os.exit(0)
29 end
30
31 while i <= #arg do
32 local a = arg[i]
33 if (a == "-h") or (a == "--help") then
34 usage()
35 elseif (a == "-o") or (a == "--output") then
36 i = i + 1
37 if i > #arg then
38 err("missing required argument to `%s'", a)
39 end
40 output = arg[i]
41 elseif (a == "-a") or (a == "--author") then
42 i = i + 1
43 if i > #arg then
44 err("missing required argument to `%s'", a)
45 end
46 author = arg[i]
47 elseif (a == "-l") or (a == "--lang") then
48 i = i + 1
49 if i > #arg then
50 err("missing required argument to `%s'", a)
51 end
52 lang = arg[i]
53 elseif a:sub(1, 1) ~= "-" then
54 table.insert(inputs, a)
55 else
56 err("unrecognized option `%s'", a)
57 end
58 i = i + 1
59 end
60
61 if #inputs == 0 then
62 err("no input files")
63 end
64
65 local outfile = io.stdout
66
67 local function printf(fmt, ...)
68 outfile:write(fmt:format(...))
69 end
70
71 if output then
72 local e
73 outfile, e = io.open(output, "w")
74 if not outfile then
75 err("error opening file for writing: %s", e)
76 end
77 end
78
79 if author or lang then
80 outfile:write("\n")
81 end
82
83 if lang then
84 printf("# Language: %s\n", lang)
85 end
86
87 if author then
88 printf("# Author: %s\n", author)
89 end
90
91 if author or lang then
92 outfile:write("\n")
93 end
94
95 local escapes = {
96 ["\n"] = "\\n",
97 ["="] = "\\=",
98 ["\\"] = "\\\\",
99 }
100
101 local function escape(s)
102 return s:gsub("[\\\n=]", escapes)
103 end
104
105 local messages = { }
106
107 for _, file in ipairs(inputs) do
108 local infile, e = io.open(file, "r")
109 if infile then
110 for line in infile:lines() do
111 for s in line:gmatch('S%("([^"]*)"') do
112 table.insert(messages, s)
113 end
114 end
115 infile:close()
116 else
117 io.stderr:write(("%s: WARNING: error opening file: %s\n"):format(me, e))
118 end
119 end
120
121 table.sort(messages)
122
123 local last_msg
124
125 for _, msg in ipairs(messages) do
126 if msg ~= last_msg then
127 printf("%s =\n", escape(msg))
128 end
129 last_msg = msg
130 end
131
132 if output then
133 outfile:close()
134 end
135
136 --[[
137 TESTS:
138 S("foo") S("bar")
139 S("bar")
140 S("foo")
141 ]]
0 #! /usr/bin/env lua
1
2 local basedir = ""
3 if arg[0]:find("[/\\]") then
4 basedir = arg[0]:gsub("(.*[/\\]).*$", "%1"):gsub("\\", "/")
5 end
6 if basedir == "" then basedir = "./" end
7
8 -- Required by load_strings()
9 function string.trim(s) -- luacheck: ignore
10 return s:gsub("^%s*(.-)%s*$", "%1")
11 end
12
13 dofile(basedir.."/../lib.lua")
14
15 local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
16
17 local function err(fmt, ...)
18 io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
19 os.exit(1)
20 end
21
22 local output, outfile, template
23 local catalogs = { }
24
25 local function usage()
26 print([[
27 Usage: ]]..me..[[ [OPTIONS] TEMPLATE CATALOG...
28
29 Update a catalog with new strings from a template.
30
31 Available options:
32 -h,--help Show this help screen and exit.
33 -o,--output X Set output file (default: stdout).
34
35 Messages in the template that are not on the catalog are added to the
36 catalog at the end.
37
38 This tool also checks messages that are in the catalog but not in the
39 template, and reports such lines. It's up to the user to remove such
40 lines, if so desired.
41 ]])
42 os.exit(0)
43 end
44
45 local i = 1
46
47 while i <= #arg do
48 local a = arg[i]
49 if (a == "-h") or (a == "--help") then
50 usage()
51 elseif (a == "-o") or (a == "--output") then
52 i = i + 1
53 if i > #arg then
54 err("missing required argument to `%s'", a)
55 end
56 output = arg[i]
57 elseif a:sub(1, 1) ~= "-" then
58 if not template then
59 template = a
60 else
61 table.insert(catalogs, a)
62 end
63 else
64 err("unrecognized option `%s'", a)
65 end
66 i = i + 1
67 end
68
69 if not template then
70 err("no template specified")
71 elseif #catalogs == 0 then
72 err("no catalogs specified")
73 end
74
75 local f, e = io.open(template, "r")
76 if not f then
77 err("error opening template: %s", e)
78 end
79
80 local escapes = { ["\n"] = "\\n", ["="] = "\\=", ["\\"] = "\\\\", }
81 local function escape(s)
82 return s:gsub("[\\\n=]", escapes)
83 end
84
85 if output then
86 outfile, e = io.open(output, "w")
87 if not outfile then
88 err("error opening file for writing: %s", e)
89 end
90 end
91
92 local template_msgs = intllib.load_strings(template)
93
94 for _, file in ipairs(catalogs) do
95 print("Processing: "..file)
96 local catalog_msgs = intllib.load_strings(file)
97 local dirty_lines = { }
98 if catalog_msgs then
99 -- Add new entries from template.
100 for k in pairs(template_msgs) do
101 if not catalog_msgs[k] then
102 print("NEW: "..k)
103 table.insert(dirty_lines, escape(k).." =")
104 end
105 end
106 -- Check for old messages.
107 for k, v in pairs(catalog_msgs) do
108 if not template_msgs[k] then
109 print("OLD: "..k)
110 table.insert(dirty_lines, "OLD: "..escape(k).." = "..escape(v))
111 end
112 end
113 if #dirty_lines > 0 then
114 local outf
115 outf, e = io.open(file, "a+")
116 if outf then
117 outf:write("\n")
118 for _, line in ipairs(dirty_lines) do
119 outf:write(line)
120 outf:write("\n")
121 end
122 outf:close()
123 else
124 io.stderr:write(("%s: WARNING: cannot write: %s\n"):format(me, e))
125 end
126 end
127 else
128 io.stderr:write(("%s: WARNING: could not load catalog\n"):format(me))
129 end
130 end
0 @echo off
1 setlocal
2
3 set me=%~n0
4
5 rem # Uncomment the following line if gettext is not in your PATH.
6 rem # Value must be absolute and end in a backslash.
7 rem set gtprefix=C:\path\to\gettext\bin\
8
9 if "%1" == "" (
10 echo Usage: %me% FILE... 1>&2
11 exit 1
12 )
13
14 set xgettext=%gtprefix%xgettext.exe
15 set msgmerge=%gtprefix%msgmerge.exe
16
17 md locale > nul 2>&1
18 echo Generating template... 1>&2
19 echo %xgettext% --from-code=UTF-8 -kS -kNS:1,2 -k_ -o locale/template.pot %*
20 %xgettext% --from-code=UTF-8 -kS -kNS:1,2 -k_ -o locale/template.pot %*
21 if %ERRORLEVEL% neq 0 goto done
22
23 cd locale
24
25 for %%f in (*.po) do (
26 echo Updating %%f... 1>&2
27 %msgmerge% --update %%f template.pot
28 )
29
30 echo DONE! 1>&2
31
32 :done
0 #! /bin/bash
1
2 me=$(basename "${BASH_SOURCE[0]}");
3
4 if [[ $# -lt 1 ]]; then
5 echo "Usage: $me FILE..." >&2;
6 exit 1;
7 fi
8
9 mkdir -p locale;
10 echo "Generating template..." >&2;
11 xgettext --from-code=UTF-8 \
12 --keyword=S \
13 --keyword=NS:1,2 \
14 --keyword=N_ \
15 --add-comments='Translators:' \
16 --add-location=file \
17 -o locale/template.pot \
18 "$@" \
19 || exit;
20
21 find locale -name '*.po' -type f | while read -r file; do
22 echo "Updating $file..." >&2;
23 msgmerge --update "$file" locale/template.pot;
24 done
25
26 echo "DONE!" >&2;