This commit is contained in:
Er2 2021-11-22 21:05:55 +03:00
commit d4f5319e02
10 changed files with 293 additions and 0 deletions

2
erl/LINGUAS Normal file
View File

@ -0,0 +1,2 @@
en
ru

12
erl/en.els Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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!'