cake_mod_delete
|
@ -45,7 +45,6 @@ load_mod_jukebox = true
|
||||||
load_mod_crops = true
|
load_mod_crops = true
|
||||||
load_mod_mysheetmetal = true
|
load_mod_mysheetmetal = true
|
||||||
load_mod_mywoodslopes = true
|
load_mod_mywoodslopes = true
|
||||||
load_mod_cake = true
|
|
||||||
load_mod_throwing = true
|
load_mod_throwing = true
|
||||||
load_mod_letters = true
|
load_mod_letters = true
|
||||||
load_mod_lib_mount = true
|
load_mod_lib_mount = true
|
||||||
|
@ -75,6 +74,7 @@ load_mod_unifieddyes = true
|
||||||
load_mod_font_api = true
|
load_mod_font_api = true
|
||||||
load_mod_display_api = true
|
load_mod_display_api = true
|
||||||
load_mod_basic_materials = true
|
load_mod_basic_materials = true
|
||||||
|
load_mod_intllib = true
|
||||||
" >> /home/minetest/.minetest/worlds/world/world.mt
|
" >> /home/minetest/.minetest/worlds/world/world.mt
|
||||||
|
|
||||||
chown minetest:minetest /home/minetest/ -cR
|
chown minetest:minetest /home/minetest/ -cR
|
||||||
|
|
|
@ -27,7 +27,6 @@ git clone --depth 1 --branch master https://github.com/minetest-mods/stained_gla
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/xban2.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/xban2.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/ropes.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/ropes.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/drinks.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/drinks.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/cake.git
|
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/jukebox.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/jukebox.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/carpets.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/carpets.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/chat2.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/chat2.git
|
||||||
|
@ -50,6 +49,7 @@ git clone --depth 1 --branch master https://github.com/minetest-mods/mymasonhamm
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/mywoodslopes.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/mywoodslopes.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/display_api.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/display_api.git
|
||||||
git clone --depth 1 --branch master https://github.com/minetest-mods/font_api.git
|
git clone --depth 1 --branch master https://github.com/minetest-mods/font_api.git
|
||||||
|
git clone --depth 1 --branch master https://github.com/minetest-mods/intllib.git
|
||||||
git clone --depth 1 --branch master https://gitlab.com/VanessaE/unifieddyes.git
|
git clone --depth 1 --branch master https://gitlab.com/VanessaE/unifieddyes.git
|
||||||
git clone --depth 1 --branch master https://gitlab.com/VanessaE/basic_materials.git
|
git clone --depth 1 --branch master https://gitlab.com/VanessaE/basic_materials.git
|
||||||
rm */.git -rf
|
rm */.git -rf
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2015 MrIbby <siribby@outlook.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
|
@ -1,15 +0,0 @@
|
||||||
# Minetest 5.0+ mod: cake
|
|
||||||
Adds delicious cakes to Minetest!
|
|
||||||
|
|
||||||
## License
|
|
||||||
Copyright (c) 2015 MrIbby <siribby@outlook.com>
|
|
||||||
- Code in licensed under the MIT license, see [LICENSE](LICENSE) for details.
|
|
||||||
|
|
||||||
### Authors and licenses of textures
|
|
||||||
- TenPlus1 (WTFPL):
|
|
||||||
- `cake.png`
|
|
||||||
- `cake_bottom.png`, derivative
|
|
||||||
- `cake_inner.png`, derivative
|
|
||||||
- `cake_side.png`, derivative
|
|
||||||
- `cake_sugar.png`
|
|
||||||
- `cake_top.png`, derivative
|
|
|
@ -1,147 +0,0 @@
|
||||||
local throwable_cake = false
|
|
||||||
|
|
||||||
-- CAKE --
|
|
||||||
|
|
||||||
local S = minetest.get_translator("cake")
|
|
||||||
|
|
||||||
local sizes = {-0.4375, -0.3125, -0.1875, -0.0625, 0.0625, 0.1875, 0.3125}
|
|
||||||
|
|
||||||
for i, size in ipairs(sizes) do
|
|
||||||
local slice = i - 1
|
|
||||||
local name
|
|
||||||
local description
|
|
||||||
local drop
|
|
||||||
local tiles
|
|
||||||
|
|
||||||
if slice == 0 then
|
|
||||||
name = "cake:cake"
|
|
||||||
description = S("Cake")
|
|
||||||
drop = nil
|
|
||||||
tiles = {"cake_top.png", "cake_bottom.png", "cake_side.png"}
|
|
||||||
else
|
|
||||||
name = "cake:cake_"..slice
|
|
||||||
drop = ''
|
|
||||||
tiles = {"cake_top.png", "cake_bottom.png", "cake_side.png", "cake_inner.png", "cake_side.png", "cake_side.png"}
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node(name, {
|
|
||||||
description = description,
|
|
||||||
drop = drop,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
tiles = tiles,
|
|
||||||
inventory_image = "cake.png",
|
|
||||||
wield_image = "cake.png",
|
|
||||||
paramtype = "light",
|
|
||||||
is_ground_content = false,
|
|
||||||
groups = {crumbly=3},
|
|
||||||
--sounds = sounds,
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{size, -0.5, -0.4375, 0.4375, 0, 0.4375},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
on_rightclick = function(pos, node, clicker)
|
|
||||||
clicker:set_hp(clicker:get_hp() + 1)
|
|
||||||
|
|
||||||
if i < #sizes then
|
|
||||||
minetest.swap_node(pos, {name="cake:cake_"..i})
|
|
||||||
else
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if not minetest.get_modpath("food") then
|
|
||||||
minetest.register_craftitem("cake:sugar", {
|
|
||||||
description = S("Sugar"),
|
|
||||||
inventory_image = "cake_sugar.png",
|
|
||||||
groups = {food_sugar=1}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
output = "cake:sugar",
|
|
||||||
recipe = {"default:papyrus"}
|
|
||||||
})
|
|
||||||
else
|
|
||||||
minetest.register_alias("cake:sugar", "food:sugar")
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "shapeless",
|
|
||||||
output = "cake:cake",
|
|
||||||
recipe = {"farming:flour", "group:water_bucket", "group:food_sugar", "group:food_sugar"},
|
|
||||||
replacements = {
|
|
||||||
{"group:water_bucket", "bucket:bucket_empty"},
|
|
||||||
|
|
||||||
-- Not needed >0.4.13
|
|
||||||
{"bucket:bucket_water", "bucket:bucket_empty"},
|
|
||||||
{"bucket:bucket_river_water", "bucket:bucket_empty"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- THROWABLE CAKE --
|
|
||||||
|
|
||||||
minetest.register_entity("cake:cake_entity", {
|
|
||||||
physical = false,
|
|
||||||
timer = 0,
|
|
||||||
textures = {"cake.png"},
|
|
||||||
lastpos = {},
|
|
||||||
collisionbox = {0,0,0,0,0,0},
|
|
||||||
on_step = function(self, dtime)
|
|
||||||
self.timer=self.timer+dtime
|
|
||||||
local pos = self.object:getpos()
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
|
|
||||||
if self.timer>0.2 then
|
|
||||||
local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2)
|
|
||||||
for k, obj in pairs(objs) do
|
|
||||||
if obj:get_luaentity() == nil or obj:get_luaentity().name ~= "cake:cake_entity" and obj:get_luaentity().name ~= "__builtin:item" then
|
|
||||||
obj:set_hp(obj:get_hp() + 7)
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.lastpos.x~=nil then
|
|
||||||
if node.name ~= "air" then
|
|
||||||
minetest.add_item(self.lastpos, 'cake:cake')
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
if throwable_cake then
|
|
||||||
minetest.override_item("cake:cake", {
|
|
||||||
on_use = function(itemstack, player, pointed_thing)
|
|
||||||
if not minetest.settings:get_bool("creative_mode") then
|
|
||||||
itemstack:take_item()
|
|
||||||
end
|
|
||||||
local playerpos = player:getpos()
|
|
||||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, "cake:cake_entity")
|
|
||||||
local dir = player:get_look_dir()
|
|
||||||
obj:setvelocity({x=dir.x*19, y=dir.y*19, z=dir.z*19})
|
|
||||||
obj:setacceleration({x=dir.x*-3, y=-10, z=dir.z*-3})
|
|
||||||
obj:setyaw(player:get_look_yaw()+math.pi)
|
|
||||||
return itemstack
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- CAKE AWARD --
|
|
||||||
if minetest.get_modpath("awards") then
|
|
||||||
awards.register_achievement("award_the_lie", {
|
|
||||||
title = S("The Lie"),
|
|
||||||
description = S("Craft a cake"),
|
|
||||||
icon = "cake.png",
|
|
||||||
trigger = {
|
|
||||||
type = "craft",
|
|
||||||
item = "cake:cake",
|
|
||||||
target = 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Цукар
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Pastís
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Sucre
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Cukr
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Sukker
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Kuchen
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Zucker
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Kuko
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Sukero
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Pastel
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Azúcar
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Kook
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Suhkrud
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Gâteau
|
|
||||||
Craft a cake=Préparez un gâteau
|
|
||||||
Sugar=Sucre
|
|
||||||
The Lie=Le mensonge
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=עוגה
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=סוכר
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Cukor
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Bolu
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Gula
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=ケーキ
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=砂糖
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=sakta
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=케이크
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=설탕
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Cukrus
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Kek
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Gula
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Taart
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Suiker
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Ciasto
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Cukier
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Bolo
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Açúcar
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Prăjitură
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Zahăr
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Пирожное
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Сахар
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Sladkor
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Kaka
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Socker
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Keki
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Sukari
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Pasta
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Şeker
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=Тістечко
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=Цукор
|
|
||||||
The Lie=
|
|
|
@ -1,9 +0,0 @@
|
||||||
# textdomain: cake
|
|
||||||
|
|
||||||
|
|
||||||
### init.lua ###
|
|
||||||
|
|
||||||
Cake=
|
|
||||||
Craft a cake=
|
|
||||||
Sugar=
|
|
||||||
The Lie=
|
|
|
@ -1,4 +0,0 @@
|
||||||
name = cake
|
|
||||||
description = Adds delicious cakes to Minetest!
|
|
||||||
depends = bucket, farming
|
|
||||||
optional_depends = awards, food
|
|
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 235 B |
Before Width: | Height: | Size: 439 B |
Before Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 142 B |
Before Width: | Height: | Size: 351 B |
14
mods/intllib/.luacheckrc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
read_globals = {
|
||||||
|
"minetest",
|
||||||
|
}
|
||||||
|
|
||||||
|
globals = {
|
||||||
|
"intllib",
|
||||||
|
}
|
||||||
|
|
||||||
|
files["intltest/init.lua"] = {
|
||||||
|
ignore = {
|
||||||
|
"212", -- Unused argument.
|
||||||
|
},
|
||||||
|
}
|
25
mods/intllib/LICENSE.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
41
mods/intllib/README-es.md
Normal 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
|
43
mods/intllib/README-it.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
# Libreria di internazionalizzazione per Minetest
|
||||||
|
|
||||||
|
Di Diego Martínez (kaeza).
|
||||||
|
Rilasciata sotto licenza Unlicense. Si veda `LICENSE.md` per i dettagli.
|
||||||
|
|
||||||
|
Questo modulo è un tentativo per fornire il supporto di internazionalizzazione
|
||||||
|
per i moduli (cosa che attualmente manca a Minetest).
|
||||||
|
|
||||||
|
Se aveste qualunque commento o suggerimento, per piacere scriveteli nella
|
||||||
|
[discussione sul forum][topic]. Per i rapporti sui bug, usate il
|
||||||
|
[tracciatore di bug][bugtracker] su Github.
|
||||||
|
|
||||||
|
## Come usarla
|
||||||
|
|
||||||
|
Se siete un* giocatrice/tore che vuole i testi tradotti,
|
||||||
|
[installate][installing_mods] questo modulo come qualunque altro,
|
||||||
|
poi abilitatelo tramite l'interfaccia grafica.
|
||||||
|
|
||||||
|
Il modulo tenta di rilevare la vostra lingua, ma dato che al momento non c'è
|
||||||
|
un metodo portabile per farlo, prova diverse alternative:
|
||||||
|
|
||||||
|
* `language` impostazione in `minetest.conf`.
|
||||||
|
* `LANGUAGE` variabile d'ambiente.
|
||||||
|
* `LANG` variabile d'ambiente.
|
||||||
|
* Se nessuna funziona, usa `en`.
|
||||||
|
|
||||||
|
In ogni caso, il risultato finale dovrebbe essere il
|
||||||
|
[codice di lingua ISO 639-1][ISO639-1] del linguaggio desiderato.
|
||||||
|
|
||||||
|
### Sviluppatrici/tori di moduli
|
||||||
|
|
||||||
|
Se siete un* sviluppatrice/tore di moduli desideros* di aggiungere il supporto
|
||||||
|
per l'internazionalizzazione al vostro modulo, leggete `doc/developer-it.md`.
|
||||||
|
|
||||||
|
### Traduttrici/tori
|
||||||
|
|
||||||
|
Se siete un* traduttrice/tore, leggete `doc/translator-it.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://it.wikipedia.org/wiki/ISO_639-1
|
41
mods/intllib/README-ms.md
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
# Pustaka Pengantarabangsaan untuk Minetest
|
||||||
|
|
||||||
|
Oleh Diego Martínez (kaeza).
|
||||||
|
Diterbitkan bawah Unlicense. Lihat `LICENSE.md` untuk maklumat lanjut.
|
||||||
|
|
||||||
|
Mods ini ialah suatu usaha untuk menyediakan sokongan pengantarabangsaan
|
||||||
|
kepada mods (sesuatu yang Minetest tiada ketika ini).
|
||||||
|
|
||||||
|
Jika anda mempunyai sebarang komen/cadangan, sila tulis ke dalam [topik forum][topik].
|
||||||
|
Untuk melaporkan pepijat, sila gunakan [penjejak pepijat][pepijat] Github.
|
||||||
|
|
||||||
|
## Bagaimanakah cara untuk menggunakannya?
|
||||||
|
|
||||||
|
Jika anda pemain biasa yang mencari teks terjemahan, hanya [pasangkan][pasang_mods]
|
||||||
|
mods ini seperti mods lain, kemudian bolehkannya melalui GUI.
|
||||||
|
|
||||||
|
Mods ini cuba untuk mengesan bahasa anda, tetapi oleh kerana tiada
|
||||||
|
cara mudah alih untuk melakukannya, ia cuba beberapa cara yang lain:
|
||||||
|
|
||||||
|
* Tetapan `language` di dalam fail `minetest.conf`.
|
||||||
|
* Pembolehubah sekitaran `LANGUAGE`.
|
||||||
|
* Pembolehubah sekitaran `LANG`.
|
||||||
|
* Jika semua di atas gagal, ia gunakan `en`.
|
||||||
|
|
||||||
|
Dalam apa jua keadaan, hasil akhirnya sepatutnya menjadi
|
||||||
|
[Kod Bahasa ISO 639-1][ISO639-1] untuk bahasa yang dikehendaki.
|
||||||
|
|
||||||
|
### Pembangun mods
|
||||||
|
|
||||||
|
Jika anda seorang pembangun mods yang ingin menambah sokongan
|
||||||
|
pengantarabangsaan kepada mods anda, sila lihat `doc/developer.md`.
|
||||||
|
|
||||||
|
### Penterjemah
|
||||||
|
|
||||||
|
Jika anda seorang penterjemah, sila lihat `doc/translator.md`.
|
||||||
|
|
||||||
|
[topik]: https://forum.minetest.net/viewtopic.php?id=4929
|
||||||
|
[pepijat]: https://github.com/minetest-mods/intllib/issues
|
||||||
|
[pasang_mods]: https://wiki.minetest.net/Installing_Mods/ms
|
||||||
|
[ISO639-1]: https://ms.wikipedia.org/wiki/Senarai_kod_ISO_639-1
|
50
mods/intllib/README-pt_BR.md
Normal 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
|
51
mods/intllib/README.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
# Internationalization Lib for Minetest
|
||||||
|
|
||||||
|
## DEPRECATED - Use Minetest's new translation API instead!
|
||||||
|
|
||||||
|
You should not use this mod when writing new mods, and you should update mods to no longer depend on this mod.
|
||||||
|
|
||||||
|
Minetest 5.0 has builtin support for client-side translation, accessed by `minetest.get_translator()`
|
||||||
|
|
||||||
|
## Aboud
|
||||||
|
|
||||||
|
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
|
3
mods/intllib/description.txt
Normal 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.
|
66
mods/intllib/doc/developer-it.md
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
# Intllib - documentazione per sviluppatrici/tori
|
||||||
|
|
||||||
|
## Abilitare l'internazionalizzazione
|
||||||
|
|
||||||
|
Per abilitare l'internazionalizzazione del vostro modulo, dovete copiare il file
|
||||||
|
`lib/intllib.lua` nella cartella principale del vostro modulo, poi inserite
|
||||||
|
questo codice standard nei file che necessitano la traduzione:
|
||||||
|
|
||||||
|
-- Load support for intllib.
|
||||||
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
local S, NS = dofile(MP.."/intllib.lua")
|
||||||
|
|
||||||
|
Dovrete anche aggiungere la dipendenza facoltativa da intllib per il vostro
|
||||||
|
modulo, per farlo aggiungete `intllib?` su una riga vuota nel vostro
|
||||||
|
`depends.txt`. Si noti anche che se intllib non è installata, le funzioni di
|
||||||
|
acquisizione del testo sono fatte in modo da restituire la stringa di testo
|
||||||
|
originale. Questo è stato fatto in modo che non dobbiate spargere tonnellate
|
||||||
|
di `if` (o costrutti simili) per controllare se la libreria è installata.
|
||||||
|
|
||||||
|
Dopo avere messo il codice, dovete marcare le stringhe di testo che necessitano
|
||||||
|
una traduzione. Per ciascuna stringa traducibile nei vostri codici sorgenti,
|
||||||
|
usate la funzione `S` (si veda sopra) per restituire la stringa tradotta.
|
||||||
|
Per esempio:
|
||||||
|
|
||||||
|
minetest.register_node("miomod:mionodo", {
|
||||||
|
-- Stringa semplice:
|
||||||
|
description = S("Il mio fantastico nodo"),
|
||||||
|
-- Stringa con inserti:
|
||||||
|
description = S("Macchina @1", "Blu"),
|
||||||
|
-- ...
|
||||||
|
})
|
||||||
|
|
||||||
|
La funzione `NS` è l'equivalente di `ngettext`. Dovrebbe essere usata quando la
|
||||||
|
stringa da tradurre ha forma singolare e plurale. Per esempio:
|
||||||
|
|
||||||
|
-- Il primo `count` è per consentire a `ngettext` di stabilire quale forma
|
||||||
|
-- usare. Il secondo `count` è per il sostituto effettivo.
|
||||||
|
|
||||||
|
print(NS("Avete un oggetto.", "Avete @1 oggetti.", count, count))
|
||||||
|
|
||||||
|
## Generare e aggiornare cataloghi
|
||||||
|
|
||||||
|
Questo è il procedimento di base per lavorare con [gettext][gettext]
|
||||||
|
|
||||||
|
Ogni volta che avete nuove stringhe da tradurre, dovreste fare quanto segue:
|
||||||
|
|
||||||
|
cd /percorso/del/modulo
|
||||||
|
/percorso/degli/strumenti/intllib/xgettext.sh file1.lua file2.lua ...
|
||||||
|
|
||||||
|
Lo script creerà una cartella chiamata `locale` se non esiste già, e genererà
|
||||||
|
il file `template.pot` (un modello con tutte le stringhe traducibili). Se avete
|
||||||
|
già delle traduzioni, lo script provvederà al loro aggiornamento con le nuove
|
||||||
|
stringhe.
|
||||||
|
|
||||||
|
Lo script fornisce alcune opzioni al vero `xgettext` che dovrebbero essere
|
||||||
|
sufficienti per la maggior parte dei casi. Se lo desiderate potete specificare
|
||||||
|
altre opzioni:
|
||||||
|
|
||||||
|
xgettext.sh -o file.pot --keyword=blaaaah:4,5 a.lua b.lua ...
|
||||||
|
|
||||||
|
NOTA: C'è anche un file batch di Windows `xgettext.bat` per gli utenti di
|
||||||
|
Windows, ma dovrete installare separatamente gli strumenti di gettext per la
|
||||||
|
riga di comando. Si veda la parte superiore del file per la configurazione.
|
||||||
|
|
||||||
|
[gettext]: https://www.gnu.org/software/gettext/
|
62
mods/intllib/doc/developer.md
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
# Intllib developer documentation
|
||||||
|
|
||||||
|
## Enabling internationalization
|
||||||
|
|
||||||
|
In order to enable internationalization for your mod, you will need to copy the
|
||||||
|
file `lib/intllib.lua` into the root directory of your mod, then include this
|
||||||
|
boilerplate code in files needing localization:
|
||||||
|
|
||||||
|
-- Load support for intllib.
|
||||||
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
local S, NS = dofile(MP.."/intllib.lua")
|
||||||
|
|
||||||
|
You will also need to optionally depend on intllib, to do so add `intllib?`
|
||||||
|
to an empty line in your `depends.txt`. Also note that if intllib is not
|
||||||
|
installed, the getter functions are defined so they return the string
|
||||||
|
unchanged. This is done so you don't have to sprinkle tons of `if`s (or
|
||||||
|
similar constructs) to check if the lib is actually installed.
|
||||||
|
|
||||||
|
Once you have the code in place, you need to mark strings that need
|
||||||
|
translation. For each translatable string in your sources, use the `S`
|
||||||
|
function (see above) to return the translated string. For example:
|
||||||
|
|
||||||
|
minetest.register_node("mymod:mynode", {
|
||||||
|
-- Simple string:
|
||||||
|
description = S("My Fabulous Node"),
|
||||||
|
-- String with insertions:
|
||||||
|
description = S("@1 Car", "Blue"),
|
||||||
|
-- ...
|
||||||
|
})
|
||||||
|
|
||||||
|
The `NS` function is the equivalent of `ngettext`. It should be used when the
|
||||||
|
string to be translated has singular and plural forms. For example:
|
||||||
|
|
||||||
|
-- The first `count` is for `ngettext` to determine which form to use.
|
||||||
|
-- The second `count` is the actual replacement.
|
||||||
|
print(NS("You have one item.", "You have @1 items.", count, count))
|
||||||
|
|
||||||
|
## Generating and updating catalogs
|
||||||
|
|
||||||
|
This is the basic workflow for working with [gettext][gettext]
|
||||||
|
|
||||||
|
Each time you have new strings to be translated, you should do the following:
|
||||||
|
|
||||||
|
cd /path/to/mod
|
||||||
|
/path/to/intllib/tools/xgettext.sh file1.lua file2.lua ...
|
||||||
|
|
||||||
|
The script will create a directory named `locale` if it doesn't exist yet,
|
||||||
|
and will generate the file `template.pot` (a template with all the translatable
|
||||||
|
strings). If you already have translations, the script will proceed to update
|
||||||
|
all of them with the new strings.
|
||||||
|
|
||||||
|
The script passes some options to the real `xgettext` that should be enough
|
||||||
|
for most cases. You may specify other options if desired:
|
||||||
|
|
||||||
|
xgettext.sh -o file.pot --keyword=blargh:4,5 a.lua b.lua ...
|
||||||
|
|
||||||
|
NOTE: There's also a Windows batch file `xgettext.bat` for Windows users,
|
||||||
|
but you will need to install the gettext command line tools separately. See
|
||||||
|
the top of the file for configuration.
|
||||||
|
|
||||||
|
[gettext]: https://www.gnu.org/software/gettext/
|
43
mods/intllib/doc/localefile-it.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
# Formato del file di traduzione
|
||||||
|
|
||||||
|
*Nota: Questo documento spiega il vecchio formato in stile conf/ini.
|
||||||
|
La nuova interfaccia usa file [gettext][gettext] `.po`.
|
||||||
|
Si veda [Il formato dei file PO][PO-Files] per ulteriori informazioni.*
|
||||||
|
|
||||||
|
Questo è un esempio per un file di traduzione in Italiano (`it.txt`):
|
||||||
|
|
||||||
|
# Un commento.
|
||||||
|
# Un altro commento.
|
||||||
|
Questa riga viene ignorata dato che non ha il segno di uguale.
|
||||||
|
Hello, World! = Ciao, Mondo!
|
||||||
|
String with\nnewlines = Stringa con\na capo
|
||||||
|
String with an \= equals sign = Stringa con un segno di uguaglianza \=
|
||||||
|
|
||||||
|
I file "locale" (o di traduzione) sono file di testo semplice formati da righe
|
||||||
|
nel formato `testo originale = testo tradotto`. Il file deve stare nella
|
||||||
|
sottocartella `locale` del modulo, e il suo nome deve essere lo stesso del
|
||||||
|
[codice di lingua ISO 639-1][ISO639-1] della lingua che volete fornire.
|
||||||
|
|
||||||
|
I file di traduzione dovrebbero usare la codifica UTF-8.
|
||||||
|
|
||||||
|
Le righe che iniziano con un cancelletto sono commenti e vengono ignorate dal
|
||||||
|
lettore. Si noti che i commenti si estendono solo fino al termine della riga;
|
||||||
|
non c'è nessun supporto per i commenti multiriga. Le righe senza un segno di
|
||||||
|
uguale sono anch'esse ignorate.
|
||||||
|
|
||||||
|
I caratteri che sono considerati "speciali" possono essere "escaped" di modo
|
||||||
|
che siano presi letteralmente. Inoltre esistono molte sequenze di escape che
|
||||||
|
possono essere utilizzate:
|
||||||
|
|
||||||
|
* Qualsiasi `#`, `=` può essere escaped di modo da essere preso letteralmente.
|
||||||
|
La sequenza `\#` è utile se il vostro testo sorgente inizia con `#`.
|
||||||
|
* Le sequenze di escape comuni `\n` e `\t`, significano rispettivamente
|
||||||
|
newline (a capo) e tabulazione orizzontale.
|
||||||
|
* La sequenza speciale di escape`\s` rappresenta il carattere di spazio.
|
||||||
|
È utile principalmente per aggiungere spazi prefissi o suffissi ai testi
|
||||||
|
originali o tradotti, perché altrimenti quegli spazi verrebbero rimossi.
|
||||||
|
|
||||||
|
[gettext]: https://www.gnu.org/software/gettext
|
||||||
|
[PO-Files]: https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
|
||||||
|
[ISO639-1]: https://it.wikipedia.org/wiki/ISO_639-1
|
42
mods/intllib/doc/localefile.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
# Locale file format
|
||||||
|
|
||||||
|
*Note: This document explains the old conf/ini-like file format.
|
||||||
|
The new interface uses [gettext][gettext] `.po` files.
|
||||||
|
See [The Format of PO Files][PO-Files] for more information.*
|
||||||
|
|
||||||
|
Here's an example for a Spanish locale file (`es.txt`):
|
||||||
|
|
||||||
|
# A comment.
|
||||||
|
# Another comment.
|
||||||
|
This line is ignored since it has no equals sign.
|
||||||
|
Hello, World! = Hola, Mundo!
|
||||||
|
String with\nnewlines = Cadena con\nsaltos de linea
|
||||||
|
String with an \= equals sign = Cadena con un signo de \= igualdad
|
||||||
|
|
||||||
|
Locale (or translation) files are plain text files consisting of lines of the
|
||||||
|
form `source text = translated text`. The file must reside in the mod's `locale`
|
||||||
|
subdirectory, and must be named after the two-letter
|
||||||
|
[ISO 639-1 Language Code][ISO639-1] of the language you want to support.
|
||||||
|
|
||||||
|
The translation files should use the UTF-8 encoding.
|
||||||
|
|
||||||
|
Lines beginning with a pound sign are comments and are effectively ignored
|
||||||
|
by the reader. Note that comments only span until the end of the line;
|
||||||
|
there's no support for multiline comments. Lines without an equals sign are
|
||||||
|
also ignored.
|
||||||
|
|
||||||
|
Characters that are considered "special" can be "escaped" so they are taken
|
||||||
|
literally. There are also several escape sequences that can be used:
|
||||||
|
|
||||||
|
* Any of `#`, `=` can be escaped to take them literally. The `\#`
|
||||||
|
sequence is useful if your source text begins with `#`.
|
||||||
|
* The common escape sequences `\n` and `\t`, meaning newline and
|
||||||
|
horizontal tab respectively.
|
||||||
|
* The special `\s` escape sequence represents the space character. It
|
||||||
|
is mainly useful to add leading or trailing spaces to source or
|
||||||
|
translated texts, as these spaces would be removed otherwise.
|
||||||
|
|
||||||
|
[gettext]: https://www.gnu.org/software/gettext
|
||||||
|
[PO-Files]: https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
|
||||||
|
[ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
20
mods/intllib/doc/translator-it.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
# Intllib - documentazione per traduttrici/tori
|
||||||
|
|
||||||
|
#### Nuova interfaccia
|
||||||
|
|
||||||
|
Usate i vostri strumenti preferiti per modificare i file `.po`.
|
||||||
|
|
||||||
|
#### Vecchia interfaccia
|
||||||
|
|
||||||
|
Per tradurre nella lingua che desiderate un modulo che supporta intllib,
|
||||||
|
copiate il file `locale/template.txt` come `locale/LINGUA.txt` (dove `LINGUA` è
|
||||||
|
il [codice di lingua ISO 639-1][ISO639-1] del vostro linguaggio.
|
||||||
|
|
||||||
|
Aprite il nuovo file nel vostro editor preferito, e traducete ciascuna riga
|
||||||
|
inserendo il testo tradotto dopo il segno di uguale.
|
||||||
|
|
||||||
|
Si veda `localefile-it.md` per ulteriori informazioni sul formato del file.
|
||||||
|
|
||||||
|
[gettext]: https://www.gnu.org/software/gettext/
|
||||||
|
[ISO639-1]: https://it.wikipedia.org/wiki/ISO_639-1
|
20
mods/intllib/doc/translator.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
# Intllib translator documentation
|
||||||
|
|
||||||
|
#### New interface
|
||||||
|
|
||||||
|
Use your favorite tools to edit the `.po` files.
|
||||||
|
|
||||||
|
#### Old interface
|
||||||
|
|
||||||
|
To translate an intllib-supporting mod to your desired language, copy the
|
||||||
|
`locale/template.txt` file to `locale/LANGUAGE.txt` (where `LANGUAGE` is the
|
||||||
|
[ISO 639-1 Language Code][ISO639-1] of your language.
|
||||||
|
|
||||||
|
Open up the new file in your favorite editor, and translate each line putting
|
||||||
|
the translated text after the equals sign.
|
||||||
|
|
||||||
|
See `localefile.md` for more information about the file format.
|
||||||
|
|
||||||
|
[gettext]: https://www.gnu.org/software/gettext/
|
||||||
|
[ISO639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
226
mods/intllib/gettext.lua
Normal 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
|
213
mods/intllib/init.lua
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
local info = debug and debug.getinfo and debug.getinfo(2)
|
||||||
|
local loc = info and info.short_src..":"..info.currentline
|
||||||
|
minetest.log("deprecated", "intllib.Getter is deprecated."
|
||||||
|
.." Please use intllib.make_gettext_pair instead."
|
||||||
|
..(info and " (called from "..loc..")" or ""))
|
||||||
|
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
|
@ -0,0 +1,3 @@
|
||||||
|
-- Support for the old multi-load method
|
||||||
|
dofile(minetest.get_modpath("intllib").."/init.lua")
|
||||||
|
|
10
mods/intllib/intltest/README.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
# Intllib example
|
||||||
|
|
||||||
|
This is a simple mod showing how to use intllib.
|
||||||
|
|
||||||
|
It defines a test `intltest:test` item whose description is translated
|
||||||
|
according to the user's language.
|
||||||
|
|
||||||
|
Additionally, it demonstrates how to use plural forms by counting the
|
||||||
|
number of times the item has been used.
|
1
mods/intllib/intltest/depends.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
intllib?
|
28
mods/intllib/intltest/init.lua
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
-- Load support for intllib.
|
||||||
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
local S, NS = dofile(MP.."/intllib.lua")
|
||||||
|
|
||||||
|
local use_count = 0
|
||||||
|
|
||||||
|
minetest.log("action", S("Hello, world!"))
|
||||||
|
|
||||||
|
minetest.register_craftitem("intltest:test", {
|
||||||
|
-- Example use of replacements.
|
||||||
|
-- Translators: @1 is color, @2 is object.
|
||||||
|
description = S("Test: @1 @2", S("Blue"), S("Car")),
|
||||||
|
|
||||||
|
inventory_image = "default_sand.png",
|
||||||
|
|
||||||
|
on_use = function(stack, user, pt)
|
||||||
|
use_count = use_count + 1
|
||||||
|
-- Example use of `ngettext` function.
|
||||||
|
-- First `use_count` is `n` for ngettext;
|
||||||
|
-- Second one is actual replacement.
|
||||||
|
-- Translators: @1 is use count.
|
||||||
|
local message = NS("Item has been used @1 time.",
|
||||||
|
"Item has been used @1 times.",
|
||||||
|
use_count, use_count)
|
||||||
|
minetest.chat_send_player(user:get_player_name(), message)
|
||||||
|
end,
|
||||||
|
})
|
3
mods/intllib/intltest/intllib.lua
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
-- This file should be replaced by `intllib/lib/intllib.lua`.
|
||||||
|
return dofile(minetest.get_modpath("intllib").."/lib/intllib.lua")
|
43
mods/intllib/intltest/locale/es.po
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# I18N Test Mod.
|
||||||
|
# Copyright (C) 2013-2017 Diego Martínez <kaeza@users.sf.net>
|
||||||
|
# This file is distributed under the same license as the intllib mod.
|
||||||
|
# Diego Martínez <kaeza@users.sf.net>, 2013-2017.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I18N Test Mod 0.1.0\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-02-25 20:40-0300\n"
|
||||||
|
"PO-Revision-Date: 2017-01-23 17:36-0300\n"
|
||||||
|
"Last-Translator: Diego Martnez <kaeza@users.sf.net>\n"
|
||||||
|
"Language-Team: Spanish\n"
|
||||||
|
"Language: es\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hello, world!"
|
||||||
|
msgstr "¡Hola, mundo!"
|
||||||
|
|
||||||
|
#. Translators: @1 is color, @2 is object.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Blue"
|
||||||
|
msgstr "Azul"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Car"
|
||||||
|
msgstr "Carro"
|
||||||
|
|
||||||
|
#. Translators: @1 is color, @2 is object.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Test: @1 @2"
|
||||||
|
msgstr "Prueba: @2 @1"
|
||||||
|
|
||||||
|
#. Translators: @1 is use count.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Item has been used @1 time."
|
||||||
|
msgid_plural "Item has been used @1 times."
|
||||||
|
msgstr[0] "El objeto ha sido usado @1 vez."
|
||||||
|
msgstr[1] "El objeto ha sido usado @1 veces."
|
44
mods/intllib/intltest/locale/template.pot
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# 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 <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2017-02-25 20:40-0300\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Hello, world!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is color, @2 is object.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Blue"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: init.lua
|
||||||
|
msgid "Car"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is color, @2 is object.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Test: @1 @2"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Translators: @1 is use count.
|
||||||
|
#: init.lua
|
||||||
|
msgid "Item has been used @1 time."
|
||||||
|
msgid_plural "Item has been used @1 times."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
67
mods/intllib/lib.lua
Normal 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
|
45
mods/intllib/lib/intllib.lua
Normal 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
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
name = intllib
|
142
mods/intllib/tools/findtext.lua
Executable file
|
@ -0,0 +1,142 @@
|
||||||
|
#! /usr/bin/env lua
|
||||||
|
|
||||||
|
local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
|
||||||
|
|
||||||
|
local function err(fmt, ...)
|
||||||
|
io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local output
|
||||||
|
local inputs = { }
|
||||||
|
local lang
|
||||||
|
local author
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
|
||||||
|
local function usage()
|
||||||
|
print([[
|
||||||
|
Usage: ]]..me..[[ [OPTIONS] FILE...
|
||||||
|
|
||||||
|
Extract translatable strings from the given FILE(s).
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
-h,--help Show this help screen and exit.
|
||||||
|
-o,--output X Set output file (default: stdout).
|
||||||
|
-a,--author X Set author.
|
||||||
|
-l,--lang X Set language name.
|
||||||
|
]])
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
while i <= #arg do
|
||||||
|
local a = arg[i]
|
||||||
|
if (a == "-h") or (a == "--help") then
|
||||||
|
usage()
|
||||||
|
elseif (a == "-o") or (a == "--output") then
|
||||||
|
i = i + 1
|
||||||
|
if i > #arg then
|
||||||
|
err("missing required argument to `%s'", a)
|
||||||
|
end
|
||||||
|
output = arg[i]
|
||||||
|
elseif (a == "-a") or (a == "--author") then
|
||||||
|
i = i + 1
|
||||||
|
if i > #arg then
|
||||||
|
err("missing required argument to `%s'", a)
|
||||||
|
end
|
||||||
|
author = arg[i]
|
||||||
|
elseif (a == "-l") or (a == "--lang") then
|
||||||
|
i = i + 1
|
||||||
|
if i > #arg then
|
||||||
|
err("missing required argument to `%s'", a)
|
||||||
|
end
|
||||||
|
lang = arg[i]
|
||||||
|
elseif a:sub(1, 1) ~= "-" then
|
||||||
|
table.insert(inputs, a)
|
||||||
|
else
|
||||||
|
err("unrecognized option `%s'", a)
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if #inputs == 0 then
|
||||||
|
err("no input files")
|
||||||
|
end
|
||||||
|
|
||||||
|
local outfile = io.stdout
|
||||||
|
|
||||||
|
local function printf(fmt, ...)
|
||||||
|
outfile:write(fmt:format(...))
|
||||||
|
end
|
||||||
|
|
||||||
|
if output then
|
||||||
|
local e
|
||||||
|
outfile, e = io.open(output, "w")
|
||||||
|
if not outfile then
|
||||||
|
err("error opening file for writing: %s", e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if author or lang then
|
||||||
|
outfile:write("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
if lang then
|
||||||
|
printf("# Language: %s\n", lang)
|
||||||
|
end
|
||||||
|
|
||||||
|
if author then
|
||||||
|
printf("# Author: %s\n", author)
|
||||||
|
end
|
||||||
|
|
||||||
|
if author or lang then
|
||||||
|
outfile:write("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
local escapes = {
|
||||||
|
["\n"] = "\\n",
|
||||||
|
["="] = "\\=",
|
||||||
|
["\\"] = "\\\\",
|
||||||
|
}
|
||||||
|
|
||||||
|
local function escape(s)
|
||||||
|
return s:gsub("[\\\n=]", escapes)
|
||||||
|
end
|
||||||
|
|
||||||
|
local messages = { }
|
||||||
|
|
||||||
|
for _, file in ipairs(inputs) do
|
||||||
|
local infile, e = io.open(file, "r")
|
||||||
|
if infile then
|
||||||
|
for line in infile:lines() do
|
||||||
|
for s in line:gmatch('S%("([^"]*)"') do
|
||||||
|
table.insert(messages, s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
infile:close()
|
||||||
|
else
|
||||||
|
io.stderr:write(("%s: WARNING: error opening file: %s\n"):format(me, e))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(messages)
|
||||||
|
|
||||||
|
local last_msg
|
||||||
|
|
||||||
|
for _, msg in ipairs(messages) do
|
||||||
|
if msg ~= last_msg then
|
||||||
|
printf("%s =\n", escape(msg))
|
||||||
|
end
|
||||||
|
last_msg = msg
|
||||||
|
end
|
||||||
|
|
||||||
|
if output then
|
||||||
|
outfile:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
TESTS:
|
||||||
|
S("foo") S("bar")
|
||||||
|
S("bar")
|
||||||
|
S("foo")
|
||||||
|
]]
|
131
mods/intllib/tools/updatetext.lua
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#! /usr/bin/env lua
|
||||||
|
|
||||||
|
local basedir = ""
|
||||||
|
if arg[0]:find("[/\\]") then
|
||||||
|
basedir = arg[0]:gsub("(.*[/\\]).*$", "%1"):gsub("\\", "/")
|
||||||
|
end
|
||||||
|
if basedir == "" then basedir = "./" end
|
||||||
|
|
||||||
|
-- Required by load_strings()
|
||||||
|
function string.trim(s) -- luacheck: ignore
|
||||||
|
return s:gsub("^%s*(.-)%s*$", "%1")
|
||||||
|
end
|
||||||
|
|
||||||
|
dofile(basedir.."/../lib.lua")
|
||||||
|
|
||||||
|
local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
|
||||||
|
|
||||||
|
local function err(fmt, ...)
|
||||||
|
io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local output, outfile, template
|
||||||
|
local catalogs = { }
|
||||||
|
|
||||||
|
local function usage()
|
||||||
|
print([[
|
||||||
|
Usage: ]]..me..[[ [OPTIONS] TEMPLATE CATALOG...
|
||||||
|
|
||||||
|
Update a catalog with new strings from a template.
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
-h,--help Show this help screen and exit.
|
||||||
|
-o,--output X Set output file (default: stdout).
|
||||||
|
|
||||||
|
Messages in the template that are not on the catalog are added to the
|
||||||
|
catalog at the end.
|
||||||
|
|
||||||
|
This tool also checks messages that are in the catalog but not in the
|
||||||
|
template, and reports such lines. It's up to the user to remove such
|
||||||
|
lines, if so desired.
|
||||||
|
]])
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
|
||||||
|
while i <= #arg do
|
||||||
|
local a = arg[i]
|
||||||
|
if (a == "-h") or (a == "--help") then
|
||||||
|
usage()
|
||||||
|
elseif (a == "-o") or (a == "--output") then
|
||||||
|
i = i + 1
|
||||||
|
if i > #arg then
|
||||||
|
err("missing required argument to `%s'", a)
|
||||||
|
end
|
||||||
|
output = arg[i]
|
||||||
|
elseif a:sub(1, 1) ~= "-" then
|
||||||
|
if not template then
|
||||||
|
template = a
|
||||||
|
else
|
||||||
|
table.insert(catalogs, a)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
err("unrecognized option `%s'", a)
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if not template then
|
||||||
|
err("no template specified")
|
||||||
|
elseif #catalogs == 0 then
|
||||||
|
err("no catalogs specified")
|
||||||
|
end
|
||||||
|
|
||||||
|
local f, e = io.open(template, "r")
|
||||||
|
if not f then
|
||||||
|
err("error opening template: %s", e)
|
||||||
|
end
|
||||||
|
|
||||||
|
local escapes = { ["\n"] = "\\n", ["="] = "\\=", ["\\"] = "\\\\", }
|
||||||
|
local function escape(s)
|
||||||
|
return s:gsub("[\\\n=]", escapes)
|
||||||
|
end
|
||||||
|
|
||||||
|
if output then
|
||||||
|
outfile, e = io.open(output, "w")
|
||||||
|
if not outfile then
|
||||||
|
err("error opening file for writing: %s", e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local template_msgs = intllib.load_strings(template)
|
||||||
|
|
||||||
|
for _, file in ipairs(catalogs) do
|
||||||
|
print("Processing: "..file)
|
||||||
|
local catalog_msgs = intllib.load_strings(file)
|
||||||
|
local dirty_lines = { }
|
||||||
|
if catalog_msgs then
|
||||||
|
-- Add new entries from template.
|
||||||
|
for k in pairs(template_msgs) do
|
||||||
|
if not catalog_msgs[k] then
|
||||||
|
print("NEW: "..k)
|
||||||
|
table.insert(dirty_lines, escape(k).." =")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Check for old messages.
|
||||||
|
for k, v in pairs(catalog_msgs) do
|
||||||
|
if not template_msgs[k] then
|
||||||
|
print("OLD: "..k)
|
||||||
|
table.insert(dirty_lines, "OLD: "..escape(k).." = "..escape(v))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #dirty_lines > 0 then
|
||||||
|
local outf
|
||||||
|
outf, e = io.open(file, "a+")
|
||||||
|
if outf then
|
||||||
|
outf:write("\n")
|
||||||
|
for _, line in ipairs(dirty_lines) do
|
||||||
|
outf:write(line)
|
||||||
|
outf:write("\n")
|
||||||
|
end
|
||||||
|
outf:close()
|
||||||
|
else
|
||||||
|
io.stderr:write(("%s: WARNING: cannot write: %s\n"):format(me, e))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
io.stderr:write(("%s: WARNING: could not load catalog\n"):format(me))
|
||||||
|
end
|
||||||
|
end
|
33
mods/intllib/tools/xgettext.bat
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
set me=%~n0
|
||||||
|
|
||||||
|
rem # Uncomment the following line if gettext is not in your PATH.
|
||||||
|
rem # Value must be absolute and end in a backslash.
|
||||||
|
rem set gtprefix=C:\path\to\gettext\bin\
|
||||||
|
|
||||||
|
if "%1" == "" (
|
||||||
|
echo Usage: %me% FILE... 1>&2
|
||||||
|
exit 1
|
||||||
|
)
|
||||||
|
|
||||||
|
set xgettext=%gtprefix%xgettext.exe
|
||||||
|
set msgmerge=%gtprefix%msgmerge.exe
|
||||||
|
|
||||||
|
md locale > nul 2>&1
|
||||||
|
echo Generating template... 1>&2
|
||||||
|
echo %xgettext% --from-code=UTF-8 -kS -kNS:1,2 -k_ -o locale/template.pot %*
|
||||||
|
%xgettext% --from-code=UTF-8 -kS -kNS:1,2 -k_ -o locale/template.pot %*
|
||||||
|
if %ERRORLEVEL% neq 0 goto done
|
||||||
|
|
||||||
|
cd locale
|
||||||
|
|
||||||
|
for %%f in (*.po) do (
|
||||||
|
echo Updating %%f... 1>&2
|
||||||
|
%msgmerge% --update %%f template.pot
|
||||||
|
)
|
||||||
|
|
||||||
|
echo DONE! 1>&2
|
||||||
|
|
||||||
|
:done
|
27
mods/intllib/tools/xgettext.sh
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
me=$(basename "${BASH_SOURCE[0]}");
|
||||||
|
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
echo "Usage: $me FILE..." >&2;
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p locale;
|
||||||
|
echo "Generating template..." >&2;
|
||||||
|
xgettext --from-code=UTF-8 \
|
||||||
|
--keyword=S \
|
||||||
|
--keyword=NS:1,2 \
|
||||||
|
--keyword=N_ \
|
||||||
|
--add-comments='Translators:' \
|
||||||
|
--add-location=file \
|
||||||
|
-o locale/template.pot \
|
||||||
|
"$@" \
|
||||||
|
|| exit;
|
||||||
|
|
||||||
|
find locale -name '*.po' -type f | while read -r file; do
|
||||||
|
echo "Updating $file..." >&2;
|
||||||
|
msgmerge --update "$file" locale/template.pot;
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "DONE!" >&2;
|