init
This commit is contained in:
commit
d4f5319e02
10 changed files with 293 additions and 0 deletions
2
erl/LINGUAS
Normal file
2
erl/LINGUAS
Normal file
|
@ -0,0 +1,2 @@
|
|||
en
|
||||
ru
|
12
erl/en.els
Normal file
12
erl/en.els
Normal file
|
@ -0,0 +1,12 @@
|
|||
Er2 Locale source file
|
||||
|
||||
TRANSLATORS: Plural forms!
|
||||
TRANSLATORS: $plurals are needed
|
||||
"My string"
|
||||
> "\$hehe $plural form"
|
||||
|
||||
"New string"
|
||||
= "New translate"
|
||||
> "New translates"
|
||||
|
||||
"Basic string"
|
13
erl/ru.els
Normal file
13
erl/ru.els
Normal file
|
@ -0,0 +1,13 @@
|
|||
Er2 Locale source file
|
||||
|
||||
TRANSLATORS: Plural forms!
|
||||
TRANSLATORS: $plurals are needed
|
||||
"My string"
|
||||
= "Моя строка"
|
||||
> "\$hehe $plural форма"
|
||||
|
||||
"New string"
|
||||
= "Новый перевод"
|
||||
> "Новые переводы"
|
||||
|
||||
"Basic string" specially not translated
|
20
license
Normal file
20
license
Normal file
|
@ -0,0 +1,20 @@
|
|||
Zlib License
|
||||
|
||||
Copyright (c) 2021 Er2 <er2@dismail.de>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
38
locale.lua
Normal file
38
locale.lua
Normal file
|
@ -0,0 +1,38 @@
|
|||
-- Improved gettext
|
||||
--- Er2 Locale
|
||||
--- (c) Er2 2021 <er2@dismail.de>
|
||||
--- Zlib License
|
||||
local gtext = {
|
||||
dloc = 'en_US', sdloc = 'en',
|
||||
pref = '$'
|
||||
}
|
||||
function gtext:__call(str, t)
|
||||
t = type(t) == 'table' and t or {}
|
||||
t.plural = t.plural or 0
|
||||
local plf = t.plural + 1
|
||||
local tr = self.trans[self.locale or self.floc]
|
||||
if tr and tr[str] and tr[str][plf] then str = tr[str][plf]
|
||||
else
|
||||
tr = self.trans[self.floc]
|
||||
if tr and tr[str] and tr[str][plf] then str = tr[str][plf] end
|
||||
end
|
||||
|
||||
-- Interpolation
|
||||
str = str:gsub('(.?)%'..gtext.pref..'([%w_]+)', function(p, v)
|
||||
if p == '\\' then return gtext.pref..v end
|
||||
return p.. tostring(t[v] or '')
|
||||
end)
|
||||
return str
|
||||
end
|
||||
|
||||
return function(path)
|
||||
local self = setmetatable({
|
||||
floc = gtext.dloc,
|
||||
trans = require(path..'.loc')
|
||||
}, gtext)
|
||||
|
||||
if not self.trans[self.floc] then self.floc = gtext.sdloc end
|
||||
if not self.trans[self.floc] then self.floc = l:match '([^\n]+)' end
|
||||
self.locale = self.floc
|
||||
_, gettext = self, self
|
||||
end
|
36
readme.org
Normal file
36
readme.org
Normal file
|
@ -0,0 +1,36 @@
|
|||
* Er2 Locale
|
||||
|
||||
Originally it was a part of ErTK (under development),
|
||||
but I decide to open source to other repository.
|
||||
|
||||
Currently there is only Lua implementation,
|
||||
but you can port to other language.
|
||||
|
||||
* Syntax
|
||||
|
||||
Localization files is using it's own format (see ~syntax/example.els~).
|
||||
Also you can see at the ~erl~ directory.
|
||||
|
||||
** Editor support
|
||||
|
||||
Syntax highlighting available only in ~micro~ editor
|
||||
(~syntax~ directory)
|
||||
|
||||
* Tools
|
||||
|
||||
Except runtime we have 2 tools:
|
||||
|
||||
- ~compile.lua~ - Compiles els to one (prog. language specific!) file
|
||||
|
||||
- ~po2els.lua~ - If you want to migrate from gettext
|
||||
or if translation program/service cannot export to els yet
|
||||
|
||||
* Example
|
||||
|
||||
#+begin_src lua
|
||||
require('locale') 'erl' -- init and load erl folder
|
||||
_.locale = 'ru' -- set locale will be used, maybe create $LANG detect
|
||||
_("My string") -- basic usage
|
||||
_ "My string" -- without (), lua feature
|
||||
_("My string", {plural = 1}) -- print plural form, maybe create other function for this
|
||||
#+end_src
|
13
syntax/els.yaml
Normal file
13
syntax/els.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
filetype: els
|
||||
|
||||
detect:
|
||||
filename: "\\.els$"
|
||||
header: "Er2 Locale"
|
||||
|
||||
rules:
|
||||
- comment: ".+" # Comment by default
|
||||
- constant.string: "\"([^\"]+)\"$" # Non-critical bug
|
||||
- todo: "(TODO|XXX|FIXME|TRANSLATORS):.+$"
|
||||
- statement: "^[[:space:]]*[=>]"
|
||||
- identifier: "[^\\\\]\\$([A-Za-z0-9)]+)"
|
||||
- special: "\\\\.?"
|
20
syntax/example.els
Normal file
20
syntax/example.els
Normal file
|
@ -0,0 +1,20 @@
|
|||
Er2 Locale source
|
||||
|
||||
Let's create a new string
|
||||
"Just string"
|
||||
Currently it haven't got translation
|
||||
but we can fix it
|
||||
= "No, it's localized string"
|
||||
Spaces is optional
|
||||
Also we can replace this translation
|
||||
= "Power string!"
|
||||
|
||||
This is basic, how about plural forms?
|
||||
> "Power strings!"
|
||||
Spaces is also optional
|
||||
|
||||
Oh, I forgot! We can use interpolation
|
||||
> "\$escaped $plural not escaped variable"
|
||||
To use it, type _("string", {key = value})
|
||||
|
||||
Now you know this localization format!
|
79
tools/compile.lua
Normal file
79
tools/compile.lua
Normal file
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/lua
|
||||
-- els to lua translator
|
||||
--- (c) Er2 2021 <er2@dismail.de>
|
||||
--- Zlib license
|
||||
|
||||
print '[1/4] Enter translation directory (without / at end)'
|
||||
local dir = io.read()
|
||||
|
||||
local loc = {}
|
||||
|
||||
if not io.open(dir..'/LINGUAS') then
|
||||
print '[2/4] Enter languages divided by space'
|
||||
local l = io.read() .. ' '
|
||||
for v in l:gmatch '([%w_]+)%s+' do table.insert(loc, v) end
|
||||
else
|
||||
print '[2/4] Reading LINGUAS'
|
||||
local f = io.open(dir..'/LINGUAS')
|
||||
for v in f:read('*a'):gmatch '([^\n]+)' do table.insert(loc, v) end
|
||||
f:close()
|
||||
end
|
||||
|
||||
print '[3/4] Generating locales'
|
||||
local t = os.time()
|
||||
local lf = io.open(dir..'/loc.lua', 'w')
|
||||
local k, v = 1
|
||||
lf:write 'return{'
|
||||
repeat v = loc[k]
|
||||
local f = io.open(dir..'/'..v..'.els')
|
||||
if f then print(' Generating', v)
|
||||
local tr = f:read '*a'
|
||||
f:close()
|
||||
lf:write(('%s={'):format(v))
|
||||
local trl, s = {}
|
||||
tr = tr..'\n\b'
|
||||
for l in tr:gmatch '([^\n]+)' do
|
||||
local str = l:match '^%s*"(.+)"%s*$'
|
||||
if l == '\b' or (str and str ~= s) then
|
||||
for _, v in pairs(trl) do
|
||||
v = v:gsub('\\(%$[%w_]+)', '\\\\%1')
|
||||
lf:write(('"%s",'):format(v))
|
||||
end
|
||||
if s then lf:write '},' end
|
||||
trl, s = {str}, str
|
||||
if s then
|
||||
print(' |> String', s)
|
||||
lf:write(('["%s"]={'):format(s))
|
||||
end
|
||||
end
|
||||
|
||||
str = l:match '^%s*=%s*"(.+)"%s*$'
|
||||
if str and s then
|
||||
print(' =>', str)
|
||||
trl[1] = str
|
||||
end
|
||||
str = l:match '^%s*>%s*"(.+)"%s*$'
|
||||
if str and s then
|
||||
print(' ||>', str)
|
||||
table.insert(trl, str)
|
||||
end
|
||||
end
|
||||
|
||||
lf:write '},'
|
||||
else
|
||||
print(' 404 Not found', v)
|
||||
table.remove(loc, k)
|
||||
k = k - 1
|
||||
end
|
||||
k = k + 1
|
||||
v = loc[k]
|
||||
until not v
|
||||
lf:write '}'
|
||||
lf:flush()
|
||||
lf:close()
|
||||
print(('%d seconds'):format(os.time() - t))
|
||||
|
||||
print '[4/4] Locale linting'
|
||||
require(dir..'.loc')
|
||||
|
||||
print 'Done!'
|
60
tools/po2els.lua
Normal file
60
tools/po2els.lua
Normal file
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/lua
|
||||
-- po to els translator
|
||||
--- (c) Er2 2021 <er2@dismail.de>
|
||||
--- Zlib license
|
||||
|
||||
print '[1/3] Enter translation directory (without / at end)'
|
||||
local dir = io.read()
|
||||
|
||||
local loc = {}
|
||||
|
||||
if not io.open(dir..'/LINGUAS') then
|
||||
print '[2/3] Enter languages divided by space'
|
||||
local l = io.read() .. ' '
|
||||
for v in l:gmatch '([%w_]+)%s+' do table.insert(loc, v) end
|
||||
else
|
||||
print '[2/3] Reading LINGUAS'
|
||||
local f = io.open(dir..'/LINGUAS')
|
||||
for v in f:read('*a'):gmatch '([^\n]+)' do table.insert(loc, v) end
|
||||
f:close()
|
||||
end
|
||||
|
||||
print '[3/3] Generating els'
|
||||
local t = os.time()
|
||||
local w = 0
|
||||
local k, v = 1
|
||||
repeat v = loc[k]
|
||||
local f = io.open(dir..'/'..v..'.po')
|
||||
if f then print(' Generating', v)
|
||||
local tr = f:read '*a'
|
||||
f:close()
|
||||
f = io.open(dir..'/'..v..'.els', 'w')
|
||||
f:write 'Er2 Locale source file\n'
|
||||
for l in tr:gmatch '[^\n]+' do
|
||||
if l:match '%%%a' then w = w + 1
|
||||
print(' WARN', 'Found printf string, not will be replaced')
|
||||
print(' INFO', l)
|
||||
end
|
||||
l = l
|
||||
:gsub('^%s*".*"%s*$', '')
|
||||
:gsub('^msgid_plural.+', '')
|
||||
:gsub('^msgid%s+"(.*)"', '"%1"')
|
||||
:gsub('^msgstr%s+"(.*)"', ' = "%1"')
|
||||
:gsub('^msgstr%s*%[%s*(%d+)%s*%]%s+(".*")', function(id, str)
|
||||
return (id == '0' and ' = ' or ' > ') .. str end)
|
||||
:gsub('^%s*[=>]?%s*""', '')
|
||||
if #l > 0 then f:write(l, '\n') end
|
||||
end
|
||||
f:flush()
|
||||
f:close()
|
||||
else
|
||||
print(' 404 Not found', v)
|
||||
table.remove(loc, k)
|
||||
k = k - 1
|
||||
end
|
||||
k = k + 1
|
||||
v = loc[k]
|
||||
until not v
|
||||
print(('%d seconds, %d warnings'):format(os.time() - t, w))
|
||||
|
||||
print 'Done!'
|
Loading…
Reference in a new issue