mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-21 21:05:52 +00:00
wmlxgettext: added support for plural forms (used on lua files)
This commit is contained in:
parent
fd1c94b2f8
commit
91c9677b22
@ -100,14 +100,15 @@ def closenode(closetag, mydict, lineno):
|
||||
|
||||
|
||||
def addNodeSentence(sentence, *, ismultiline, lineno, lineno_sub,
|
||||
override, addition):
|
||||
override, addition, plural=None):
|
||||
global nodes
|
||||
if nodes is None:
|
||||
nodes = [pos.WmlNode(fileref=fileref, fileno=fileno,
|
||||
tagname="", autowml=False)]
|
||||
nodes[-1].add_sentence(sentence, ismultiline=ismultiline,
|
||||
lineno=lineno, lineno_sub=lineno_sub,
|
||||
override=override, addition=addition)
|
||||
override=override, addition=addition,
|
||||
plural=plural)
|
||||
|
||||
|
||||
def addWmlInfo(info):
|
||||
|
@ -1,15 +1,33 @@
|
||||
import re
|
||||
|
||||
# remember... I ised PoCommentedStringML instead of PoCommentedStringML... don't know if something remained in other files
|
||||
|
||||
class PoCommentedStringPL:
|
||||
def __init__(self, value, *, ismultiline=False):
|
||||
self.value = value
|
||||
self.ismultiline = ismultiline
|
||||
|
||||
|
||||
|
||||
class PoCommentedString:
|
||||
def __init__(self, sentence, *, orderid, ismultiline,
|
||||
wmlinfos, finfos, addedinfos):
|
||||
wmlinfos, finfos, addedinfos, plural=None):
|
||||
self.sentence = sentence
|
||||
self.wmlinfos = wmlinfos
|
||||
self.addedinfos = addedinfos
|
||||
self.finfos = finfos
|
||||
self.orderid = orderid
|
||||
self.ismultiline = ismultiline
|
||||
self.plural = None
|
||||
if isinstance(plural, PoCommentedStringPL):
|
||||
self.plural = plural
|
||||
|
||||
def set_plural(self, plural_value, *, ismultiline=False):
|
||||
# add_plural is a safe way to add a plural form into a sentence
|
||||
# if plural form is still stored, no plural form is added
|
||||
if self.plural is None:
|
||||
self.plural = PoCommentedStringPL(plural_value, ismultiline)
|
||||
|
||||
def update_orderid(self, orderid):
|
||||
if orderid < self.orderid:
|
||||
self.orderid = orderid
|
||||
@ -22,9 +40,11 @@ class PoCommentedString:
|
||||
self.addedinfos += commented_string.addedinfos
|
||||
self.finfos += commented_string.finfos
|
||||
self.update_orderid(commented_string.orderid)
|
||||
# if commented_string.orderid < self.orderid:
|
||||
# self.orderid = commented_string.orderid
|
||||
# self.sentence = commented_string.sentence
|
||||
# update plural value only if current sentence actually don't have
|
||||
# a plural form and only if the
|
||||
if self.plural is None and isinstance(commented_string.plural,
|
||||
PoCommentedStringPL):
|
||||
self.plural = commented_string.plural
|
||||
|
||||
def write(self, filebuf, fuzzy):
|
||||
if self.wmlinfos is not None:
|
||||
@ -44,13 +64,19 @@ class PoCommentedString:
|
||||
self.sentence = re.sub(r'(\n\r|\r\n|[\n\r])', lf, self.sentence)
|
||||
self.sentence = '""\n' + self.sentence
|
||||
print('msgid', self.sentence, file=filebuf)
|
||||
print('msgstr ""', file=filebuf)
|
||||
|
||||
if self.plural is None:
|
||||
print('msgstr ""', file=filebuf)
|
||||
else:
|
||||
# self.plural must be an instance of PoCommentedStringPL
|
||||
print('msgid_plural', self.plural.value, file=filebuf)
|
||||
print('msgstr[0] ""', file=filebuf)
|
||||
print('msgstr[1] ""', file=filebuf)
|
||||
|
||||
|
||||
# Also nodesentence use PoCommentedStringPL for 'plural' parameter
|
||||
class WmlNodeSentence:
|
||||
def __init__(self, sentence, *, ismultiline, lineno, lineno_sub=0,
|
||||
override=None, addition=None):
|
||||
plural=None, override=None, addition=None):
|
||||
self.sentence = sentence
|
||||
# Say if it is multiline or not.
|
||||
self.ismultiline = ismultiline
|
||||
@ -72,7 +98,18 @@ class WmlNodeSentence:
|
||||
# list will contains custom comment that will be added at the
|
||||
# end of translator's comment list.
|
||||
self.addedinfo = addition
|
||||
if addition is None: self.addedinfo = []
|
||||
if addition is None:
|
||||
self.addedinfo = []
|
||||
# plural forms (if any) will be stored in WmlNodeSentence
|
||||
self.plural = None
|
||||
if isinstance(plural, PoCommentedStringPL):
|
||||
self.plural = plural
|
||||
|
||||
def set_plural(self, plural_value, *, ismultiline=False):
|
||||
# add_plural is a safe way to add a plural form into a sentence
|
||||
# if plural form is still stored, no plural form is added
|
||||
if self.plural is None:
|
||||
self.plural = PoCommentedStringPL(plural_value, ismultiline)
|
||||
|
||||
|
||||
|
||||
@ -86,13 +123,37 @@ class WmlNode:
|
||||
self.autowml = autowml
|
||||
|
||||
def add_sentence(self, sentence, *, ismultiline, lineno,
|
||||
lineno_sub=0, override=None, addition=None):
|
||||
lineno_sub=0, plural=None, override=None, addition=None):
|
||||
if self.sentences is None:
|
||||
self.sentences = []
|
||||
# 'plural' parameter accepted by WmlNode.add_sentence can be:
|
||||
# 1) A string
|
||||
# 2) A tuple of two values (string, bool)
|
||||
# 3) An actual PoCommentedStringPL object
|
||||
# This is why we need to add an extra variable here (plural_value)
|
||||
# wich will store an PoCommentedStringPL object (or will be None)
|
||||
plural_value = None
|
||||
if plural is not None:
|
||||
if isinstance(plural, str):
|
||||
plural_value = PoCommentedStringPL(plural)
|
||||
elif isinstance(plural, tuple) or isinstance(plural, list):
|
||||
if len(plural) == 2:
|
||||
if(isinstance(plural[0], str) and
|
||||
isinstance(plural[1], bool)):
|
||||
plural_value = PoCommentedStringPL(plural[0],
|
||||
plural[1])
|
||||
elif(isinstance(plural[0], bool) and
|
||||
isinstance(plural[1], str)):
|
||||
plural_value = PoCommentedStringPL(plural[1],
|
||||
plural[0])
|
||||
elif isinstance(plural, PoCommentedStringPL):
|
||||
plural_value = plural
|
||||
plural = None
|
||||
self.sentences.append( WmlNodeSentence(sentence,
|
||||
ismultiline=ismultiline,
|
||||
lineno=lineno,
|
||||
lineno_sub=lineno_sub,
|
||||
lineno_sub=lineno_sub,
|
||||
plural=plural_value,
|
||||
override=override,
|
||||
addition=addition) )
|
||||
|
||||
@ -139,7 +200,8 @@ class WmlNode:
|
||||
wmlinfos=[],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=nodesentence.addedinfo)
|
||||
addedinfos=nodesentence.addedinfo,
|
||||
plural=nodesentence.plural )
|
||||
else:
|
||||
return PoCommentedString(nodesentence.sentence,
|
||||
ismultiline=nodesentence.ismultiline,
|
||||
@ -147,7 +209,8 @@ class WmlNode:
|
||||
wmlinfos=[],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=[])
|
||||
addedinfos=[],
|
||||
plural=nodesentence.plural )
|
||||
else: # having a non-empty override
|
||||
if(nodesentence.addedinfo is not None and
|
||||
nodesentence.addedinfo != ""):
|
||||
@ -157,7 +220,8 @@ class WmlNode:
|
||||
wmlinfos=[nodesentence.overrideinfo],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=nodesentence.addedinfo)
|
||||
addedinfos=nodesentence.addedinfo,
|
||||
plural=nodesentence.plural )
|
||||
else:
|
||||
return PoCommentedString(nodesentence.sentence,
|
||||
ismultiline=nodesentence.ismultiline,
|
||||
@ -165,7 +229,8 @@ class WmlNode:
|
||||
wmlinfos=[nodesentence.overrideinfo],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=[])
|
||||
addedinfos=[],
|
||||
plural=nodesentence.plural )
|
||||
# if you don't have override and autowml is true
|
||||
# --> wmlinfos will be always added
|
||||
elif self.autowml == True:
|
||||
@ -177,7 +242,8 @@ class WmlNode:
|
||||
wmlinfos=[self.assemble_wmlinfo()],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=nodesentence.addedinfo)
|
||||
addedinfos=nodesentence.addedinfo,
|
||||
plural=nodesentence.plural )
|
||||
else:
|
||||
return PoCommentedString(nodesentence.sentence,
|
||||
ismultiline=nodesentence.ismultiline,
|
||||
@ -185,7 +251,8 @@ class WmlNode:
|
||||
wmlinfos=[self.assemble_wmlinfo()],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=[])
|
||||
addedinfos=[],
|
||||
plural=nodesentence.plural )
|
||||
# if you don't have override and autowml is false
|
||||
# --> wmlinfos will never added
|
||||
else:
|
||||
@ -197,7 +264,8 @@ class WmlNode:
|
||||
wmlinfos=[],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=nodesentence.addedinfo)
|
||||
addedinfos=nodesentence.addedinfo,
|
||||
plural=nodesentence.plural )
|
||||
else:
|
||||
return PoCommentedString(nodesentence.sentence,
|
||||
ismultiline=nodesentence.ismultiline,
|
||||
@ -205,5 +273,6 @@ class WmlNode:
|
||||
wml_infos=[],
|
||||
finfos=[self.fileref +
|
||||
str(nodesentence.lineno)],
|
||||
addedinfos=[])
|
||||
addedinfos=[],
|
||||
plural=nodesentence.plural )
|
||||
|
||||
|
@ -2,6 +2,7 @@ import re
|
||||
import pywmlx.state.machine
|
||||
from pywmlx.state.state import State
|
||||
from pywmlx.wmlerr import wmlwarn
|
||||
from pywmlx.wmlerr import wmlerr
|
||||
|
||||
|
||||
|
||||
@ -66,7 +67,7 @@ class LuaCheckpoState:
|
||||
class LuaCommentState:
|
||||
def __init__(self):
|
||||
self.regex = re.compile(r'\s*--.+')
|
||||
self.iffail = 'lua_str01'
|
||||
self.iffail = 'lua_str00'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
xline = None
|
||||
@ -74,6 +75,24 @@ class LuaCommentState:
|
||||
|
||||
|
||||
|
||||
class LuaStr00:
|
||||
def __init__(self):
|
||||
self.regex = re.compile(r'.*?_\s*\(')
|
||||
self.iffail = 'lua_str01'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
xline = xline [ match.end(): ]
|
||||
pywmlx.state.machine._pending_luastring = None
|
||||
pywmlx.state.machine._pending_luastring = (
|
||||
pywmlx.state.machine.PendingLuaString(
|
||||
lineno, 'lua_plural', '', False,
|
||||
True, 0, pywmlx.state.machine.PendingPlural()
|
||||
)
|
||||
)
|
||||
return (xline, 'lua_plidle1')
|
||||
|
||||
|
||||
|
||||
class LuaStr01:
|
||||
def __init__(self):
|
||||
rx = r'''(?:[^["']*?)(_?)\s*"((?:\\"|[^"])*)("?)'''
|
||||
@ -237,6 +256,408 @@ class LuaStr30:
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 2. LUA PLURAL
|
||||
#-----------------------------------------------------------------------------
|
||||
# Lua plural will manage _ ("sentence", "plural_form", number) syntax
|
||||
# when _ ( was found on LuaStr00 (fake lua string)
|
||||
# this case will treat also _ ("translatable_string") without plural form.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#.....................
|
||||
# 2.1 Plural Idle States
|
||||
#.....................
|
||||
# Unlike Standard states, here we have multiple idle states, one for every
|
||||
# situations.
|
||||
# In this way we surely add more states, but every state can be easier to
|
||||
# develop, maintain and test, and it is less error-prone
|
||||
#.....................
|
||||
|
||||
# Plural Idle 1:
|
||||
# When argument 1 or 2 is expected
|
||||
# Here we expect " ' or a [ wich will say us what kind of string we will add.
|
||||
class LuaPlIdle1:
|
||||
def __init__(self):
|
||||
self.regex = None
|
||||
self.iffail = None
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
realmatch = re.match(r'\s*(\S)', xline)
|
||||
if realmatch:
|
||||
_nextstate = 'lua_idle'
|
||||
if realmatch.group(1) == '"':
|
||||
_nextstate = 'lua_pl01'
|
||||
elif realmatch.group(1) == "'":
|
||||
_nextstate = 'lua_pl02'
|
||||
elif realmatch.group(1) == '[':
|
||||
_nextstate = 'lua_pl03'
|
||||
elif realmatch.group(1) == ')':
|
||||
if status == 'wait_string':
|
||||
finfo = pywmlx.nodemanip.fileref + ":" + str(lineno)
|
||||
errmsg = ("first argument of function '_ (...)' must be a "
|
||||
"string")
|
||||
wmlerr(finfo, errmsg)
|
||||
else:
|
||||
# if parenthesis is closed rightly after first argument
|
||||
# this is not a plural form. So we set
|
||||
# PendingLuaString.plural to None
|
||||
if status == 'wait_plural':
|
||||
pywmlx.state.machine._pending_luastring.plural = None
|
||||
# when parenthenthesis
|
||||
xline = xline [ realmatch.end(): ]
|
||||
return (xline, 'lua_idle')
|
||||
else:
|
||||
# this should never happen. But if the first value after _ (
|
||||
# does not start with a string marker, than wmlxgettext will
|
||||
# finish with an error
|
||||
finfo = pywmlx.nodemanip.fileref + ":" + str(lineno)
|
||||
errmsg = "first argument of function '_ (...)' must be a string"
|
||||
wmlerr(finfo, errmsg)
|
||||
xline = xline [ realmatch.end(): ]
|
||||
xline = realmatch.group(1) + xline
|
||||
return (xline, _nextstate)
|
||||
|
||||
else:
|
||||
# You can find a new line rigthly after _ (. In this case, we will
|
||||
# continue
|
||||
return (None, 'lua_plidle1')
|
||||
|
||||
|
||||
|
||||
# Plural Idle 2:
|
||||
# Between argument 1 and 2, when a comma is expected
|
||||
class LuaPlIdle2:
|
||||
def __init__(self):
|
||||
self.regex = None
|
||||
self.iffail = None
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
realmatch = re.match(r'\s*,', xline)
|
||||
if realmatch:
|
||||
xline = xline [ realmatch.end(): ]
|
||||
return (xline, 'lua_plidle1')
|
||||
else:
|
||||
pywmlx.state.machine._pending_luastring.plural = None
|
||||
return (xline, 'lua_plidle3')
|
||||
|
||||
|
||||
|
||||
# Plural Idle 3:
|
||||
# Argument 1 and 2 still stored in memory. We wait only for final parenthesis
|
||||
class LuaPlIdle3:
|
||||
def __init__(self):
|
||||
self.regex = None
|
||||
self.iffail = None
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
realmatch = re.match(r'.*?\)', xline)
|
||||
if realmatch:
|
||||
xline = xline [ realmatch.end(): ]
|
||||
return (xline, 'lua_idle')
|
||||
else:
|
||||
return (None, 'lua_plidle3')
|
||||
|
||||
|
||||
|
||||
#.....................
|
||||
# 2.2 Plural States - Actual strings
|
||||
#.....................
|
||||
# Those states works, more or less, like LuaStrXX
|
||||
#.....................
|
||||
|
||||
|
||||
|
||||
class LuaPl01:
|
||||
def __init__(self):
|
||||
rx = r'"((?:\\"|[^"])*)("?)'
|
||||
self.regex = re.compile(rx)
|
||||
# 'lua_bug' is not an actual state. The regexp here should always match.
|
||||
# setting 'iffail' to a non-existing 'lua_bug' state will
|
||||
# allow us to raise an error
|
||||
self.iffail = 'lua_bug'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
if status == 'wait_string':
|
||||
_nextstate = 'lua_plidle2'
|
||||
# we must fix values for luatype (wich is used later by
|
||||
# PendingLuaString.store() )
|
||||
# and ismultiline
|
||||
pywmlx.state.machine._pending_luastring.luatype = 'luastr1'
|
||||
if match.group(2) == '':
|
||||
pywmlx.state.machine._pending_luastring.ismultiline = True
|
||||
_nextstate = 'lua_pl10'
|
||||
xline = None
|
||||
else:
|
||||
xline = xline [ match.end(): ]
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_plural'
|
||||
)
|
||||
# write first line of 'string' on PendingLuaString
|
||||
pywmlx.state.machine._pending_luastring.luastring = match.group(1)
|
||||
return (xline, _nextstate)
|
||||
else:
|
||||
_nextstate = 'lua_plidle3'
|
||||
# we must fix values for plural.pluraltype
|
||||
# and plural.ismultiline
|
||||
pywmlx.state.machine._pending_luastring.plural.pluraltype = 1
|
||||
if match.group(2) == '':
|
||||
pywmlx.state.machine._pending_luastring.plural.ismultiline = True
|
||||
_nextstate = 'lua_pl10'
|
||||
xline = None
|
||||
else:
|
||||
xline = xline [ match.end(): ]
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_close'
|
||||
)
|
||||
# write first line of 'plural' on PendingLuaString
|
||||
pywmlx.state.machine._pending_luastring.plural.string = (
|
||||
match.group(1)
|
||||
)
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
|
||||
class LuaPl02:
|
||||
def __init__(self):
|
||||
rx = r"'((?:\\'|[^'])*)('?)"
|
||||
self.regex = re.compile(rx)
|
||||
# 'lua_bug' is not an actual state. The regexp here should always match.
|
||||
# setting 'iffail' to a non-existing 'lua_bug' state will
|
||||
# allow us to raise an error
|
||||
self.iffail = 'lua_bug'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
if status == 'wait_string':
|
||||
_nextstate = 'lua_plidle2'
|
||||
# we must fix values for luatype (wich is used later by
|
||||
# PendingLuaString.store() )
|
||||
# and ismultiline
|
||||
pywmlx.state.machine._pending_luastring.luatype = 'luastr2'
|
||||
if match.group(2) == '':
|
||||
pywmlx.state.machine._pending_luastring.ismultiline = True
|
||||
_nextstate = 'lua_pl20'
|
||||
xline = None
|
||||
else:
|
||||
xline = xline [ match.end(): ]
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_plural'
|
||||
)
|
||||
# write first line of 'string' on PendingLuaString
|
||||
pywmlx.state.machine._pending_luastring.luastring = match.group(1)
|
||||
return (xline, _nextstate)
|
||||
else:
|
||||
_nextstate = 'lua_plidle3'
|
||||
# we must fix values for plural.pluraltype
|
||||
# and plural.ismultiline
|
||||
pywmlx.state.machine._pending_luastring.plural.pluraltype = 2
|
||||
if match.group(2) == '':
|
||||
pywmlx.state.machine._pending_luastring.plural.ismultiline = True
|
||||
_nextstate = 'lua_pl20'
|
||||
xline = None
|
||||
else:
|
||||
xline = xline [ match.end(): ]
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_close'
|
||||
)
|
||||
# write first line of 'plural' on PendingLuaString
|
||||
pywmlx.state.machine._pending_luastring.plural.string = (
|
||||
match.group(1)
|
||||
)
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
|
||||
class LuaPl03:
|
||||
def __init__(self):
|
||||
rx = r'\[(=*)\[(.*?)]\1]'
|
||||
self.regex = re.compile(rx)
|
||||
self.iffail = 'lua_pl03o'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
xline = xline [ match.end(): ]
|
||||
_nextstate = 'lua_plidle2'
|
||||
if status == 'wait_string':
|
||||
_nextstate = 'lua_plidle2'
|
||||
# we must fix values for luatype (wich is used later by
|
||||
# PendingLuaString.store() )
|
||||
pywmlx.state.machine._pending_luastring.luatype = 'luastr3'
|
||||
# storing string into PendingLuaString
|
||||
pywmlx.state.machine._pending_luastring.luastring = (
|
||||
match.group(2)
|
||||
)
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_plural'
|
||||
)
|
||||
else:
|
||||
_nextstate = 'lua_plidle3'
|
||||
# we must fix values for plural.pluraltype
|
||||
pywmlx.state.machine._pending_luastring.plural.pluraltype = 2
|
||||
# storing plural.string into PendingLuaString
|
||||
pywmlx.state.machine._pending_luastring.plural.string = (
|
||||
match.group(2)
|
||||
)
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_close'
|
||||
)
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
|
||||
class LuaPl03o:
|
||||
def __init__(self):
|
||||
rx = r'\[(=*)\[(.*)'
|
||||
self.regex = re.compile(rx)
|
||||
self.iffail = 'lua_bug'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
xline = None
|
||||
if status == 'wait_string':
|
||||
pywmlx.state.machine._pending_luastring.ismultiline = True
|
||||
pywmlx.state.machine._pending_luastring.luatype = 'luastr3'
|
||||
pywmlx.state.machine._pending_luastring.luastring = (
|
||||
match.group(2)
|
||||
)
|
||||
pywmlx.state.machine._pending_luastring.numequals = (
|
||||
len(match.group(1))
|
||||
)
|
||||
else:
|
||||
pywmlx.state.machine._pending_luastring.plural.ismultiline = True
|
||||
pywmlx.state.machine._pending_luastring.plural.pluraltype = 3
|
||||
pywmlx.state.machine._pending_luastring.plural.string = (
|
||||
match.group(2)
|
||||
)
|
||||
pywmlx.state.machine._pending_luastring.plural.numequals = (
|
||||
len(match.group(1))
|
||||
)
|
||||
return (xline, 'lua_pl30')
|
||||
|
||||
|
||||
|
||||
# well... the regex will always be true on this state, so iffail will never
|
||||
# be executed
|
||||
class LuaPl10:
|
||||
def __init__(self):
|
||||
self.regex = re.compile(r'((?:\\"|[^"])*)("?)')
|
||||
self.iffail = 'lua_pl10'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
_nextstate = 'lua_pl10'
|
||||
if status == 'wait_string':
|
||||
pywmlx.state.machine._pending_luastring.addline( match.group(1) )
|
||||
else:
|
||||
pywmlx.state.machine_pending_luastring.plural.addline(
|
||||
match.group(1)
|
||||
)
|
||||
if match.group(2) == '"':
|
||||
xline = xline [ match.end(): ]
|
||||
if status == 'wait_string':
|
||||
_nextstate = 'lua_plidle2'
|
||||
pywmlx.state.machine_pending_luastring.plural.status = (
|
||||
'wait_plural'
|
||||
)
|
||||
else:
|
||||
_nextstate = 'lua_plidle3'
|
||||
pywmlx.state.machine_pending_luastring.plural.status = (
|
||||
'wait_close'
|
||||
)
|
||||
else:
|
||||
xline = None
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
|
||||
# well... the regex will always be true on this state, so iffail will never
|
||||
# be executed
|
||||
class LuaPl20:
|
||||
def __init__(self):
|
||||
self.regex = re.compile(r"((?:\\'|[^'])*)('?)")
|
||||
self.iffail = 'lua_pl20'
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
_nextstate = 'lua_pl20'
|
||||
if status == 'wait_string':
|
||||
pywmlx.state.machine._pending_luastring.addline( match.group(1) )
|
||||
else:
|
||||
pywmlx.state.machine_pending_luastring.plural.addline(
|
||||
match.group(1)
|
||||
)
|
||||
if match.group(2) == '"':
|
||||
xline = xline [ match.end(): ]
|
||||
if status == 'wait_string':
|
||||
_nextstate = 'lua_plidle2'
|
||||
pywmlx.state.machine_pending_luastring.plural.status = (
|
||||
'wait_plural'
|
||||
)
|
||||
else:
|
||||
_nextstate = 'lua_plidle3'
|
||||
pywmlx.state.machine_pending_luastring.plural.status = (
|
||||
'wait_close'
|
||||
)
|
||||
else:
|
||||
xline = None
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
|
||||
class LuaPl30:
|
||||
def __init__(self):
|
||||
self.regex = None
|
||||
self.iffail = None
|
||||
|
||||
def run(self, xline, lineno, match):
|
||||
status = pywmlx.state.machine._pending_luastring.plural.status
|
||||
numequals = 0
|
||||
if status == 'wait_string':
|
||||
numequals = pywmlx.state.machine._pending_luastring.numequals
|
||||
else:
|
||||
numequals = pywmlx.state.machine._pending_luastring.plural.numequals
|
||||
rx = r'(.*?)]={' + str(numequals) + '}]'
|
||||
realmatch = re.match(rx, xline)
|
||||
_nextstate = 'lua_pl30'
|
||||
if realmatch:
|
||||
xline = xline [ realmatch.end(): ]
|
||||
if status == 'wait_string':
|
||||
pywmlx.state.machine._pending_luastring.addline(
|
||||
realmatch.group(1)
|
||||
)
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_plural'
|
||||
)
|
||||
_nextstate = 'lua_plidle2'
|
||||
else:
|
||||
pywmlx.state.machine._pending_luastring.plural.addline(
|
||||
realmatch.group(1)
|
||||
)
|
||||
pywmlx.state.machine._pending_luastring.plural.status = (
|
||||
'wait_close'
|
||||
)
|
||||
_nextstate = 'lua_plidle3'
|
||||
else:
|
||||
if status == 'wait_string':
|
||||
pywmlx.state.machine._pending_luastring.addline(xline)
|
||||
else:
|
||||
pywmlx.state.machine._pending_luastring.plural.addline(xline)
|
||||
xline = None
|
||||
_nextstate = 'lua_pl30'
|
||||
return (xline, _nextstate)
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 3. LUA FINAL STATES
|
||||
#-----------------------------------------------------------------------------
|
||||
# Now the final states:
|
||||
# LuaGowmlState
|
||||
# LuaFinalState
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class LuaGowmlState:
|
||||
def __init__(self):
|
||||
@ -285,6 +706,7 @@ def setup_luastates():
|
||||
('lua_checkdom', LuaCheckdomState),
|
||||
('lua_checkpo', LuaCheckpoState),
|
||||
('lua_comment', LuaCommentState),
|
||||
('lua_str00', LuaStr00),
|
||||
('lua_str01', LuaStr01),
|
||||
('lua_str02', LuaStr02),
|
||||
('lua_str03', LuaStr03),
|
||||
@ -292,6 +714,16 @@ def setup_luastates():
|
||||
('lua_str10', LuaStr10),
|
||||
('lua_str20', LuaStr20),
|
||||
('lua_str30', LuaStr30),
|
||||
('lua_plidle1', LuaPlIdle1),
|
||||
('lua_plidle2', LuaPlIdle2),
|
||||
('lua_plidle3', LuaPlIdle3),
|
||||
('lua_pl01', LuaPl01),
|
||||
('lua_pl02', LuaPl02),
|
||||
('lua_pl03', LuaPl03),
|
||||
('lua_pl03o', LuaPl03o),
|
||||
('lua_pl10', LuaPl10),
|
||||
('lua_pl20', LuaPl20),
|
||||
('lua_pl30', LuaPl30),
|
||||
('lua_gowml', LuaGowmlState),
|
||||
('lua_final', LuaFinalState)]:
|
||||
st = stateclass()
|
||||
|
@ -5,6 +5,7 @@ from pywmlx.wmlerr import wmlerr
|
||||
from pywmlx.wmlerr import wmlwarn
|
||||
from pywmlx.wmlerr import warnall
|
||||
from pywmlx.postring import PoCommentedString
|
||||
from pywmlx.postring import PoCommentedStringPL
|
||||
from pywmlx.state.state import State
|
||||
from pywmlx.state.lua_states import setup_luastates
|
||||
from pywmlx.state.wml_states import setup_wmlstates
|
||||
@ -20,6 +21,10 @@ import pywmlx.nodemanip
|
||||
|
||||
# True if --warnall option is used
|
||||
_warnall = False
|
||||
# True if -D option is used
|
||||
_debugmode = False
|
||||
# debug output file
|
||||
_fdebug = None
|
||||
# dictionary of pot sentences
|
||||
_dictionary = None
|
||||
# dictionary containing lua and WML states
|
||||
@ -111,30 +116,84 @@ def checksentence(mystring, finfo, *, islua=False):
|
||||
|
||||
|
||||
|
||||
class PendingPlural:
|
||||
def __init__(self):
|
||||
self.string = ''
|
||||
# status values:
|
||||
# 'wait_string' --> rightly after _ ( when we need to know
|
||||
# wich string type we will manage
|
||||
# 'on_string' --> on first argument, when ", ' or [ was found
|
||||
# 'wait_plural' --> after first argument. Search for plural or
|
||||
# close parenthesis
|
||||
# 'on_plural' --> on second argument, when ", ' or [ is found
|
||||
# (after a comma)
|
||||
# 'wait_close' --> expect close parenthesis
|
||||
self.status = 'wait_string'
|
||||
self.pluraltype = 0
|
||||
self.numequals = 0
|
||||
self.ismultiline = False
|
||||
|
||||
def addline(self, value, isfirstline=False):
|
||||
if self.pluraltype != 3:
|
||||
value = re.sub('\\\s*$', '', value)
|
||||
else:
|
||||
value = value.replace('\\', r'\\')
|
||||
if isfirstline:
|
||||
self.string = value
|
||||
else:
|
||||
self.string = self.string + '\n' + value
|
||||
|
||||
def convert(self):
|
||||
if self.pluraltype == 2:
|
||||
self.string = re.sub(r"\\\'", r"'", self.string)
|
||||
if self.pluraltype != 3 and self.pluraltype!=0:
|
||||
self.string = re.sub(r'(?<!\\)"', r'\"', self.string)
|
||||
if self.pluraltype == 3:
|
||||
self.string = self.string.replace('"', r'\"')
|
||||
if self.ismultiline:
|
||||
lf = r'\\n"' + '\n"'
|
||||
self.string = re.sub(r'(\n\r|\r\n|[\n\r])',
|
||||
lf, self.string)
|
||||
self.string = '""\n"' + self.string + '"'
|
||||
if not self.ismultiline:
|
||||
self.string = '"' + self.string + '"'
|
||||
return PoCommentedStringPL(self.string, ismultiline=self.ismultiline)
|
||||
|
||||
|
||||
|
||||
class PendingLuaString:
|
||||
def __init__(self, lineno, luatype, luastring, ismultiline,
|
||||
istranslatable, numequals=0):
|
||||
istranslatable, numequals=0, plural=None):
|
||||
self.lineno = lineno
|
||||
self.luatype = luatype
|
||||
self.luastring = ''
|
||||
self.ismultiline = ismultiline
|
||||
self.istranslatable = istranslatable
|
||||
self.numequals = numequals
|
||||
self.addline(luastring, True)
|
||||
if luatype != 'lua_plural':
|
||||
self.addline(luastring, True)
|
||||
self.plural = plural
|
||||
|
||||
def addline(self, value, isfirstline=False):
|
||||
if self.luatype != 'luastr3':
|
||||
value = re.sub('\\\s*$', '', value)
|
||||
else:
|
||||
value = value.replace('\\', r'\\')
|
||||
# nope
|
||||
if isfirstline:
|
||||
self.luastring = value
|
||||
else:
|
||||
self.luastring = self.luastring + '\n' + value
|
||||
|
||||
# this function is used by store, when translating lua pending plural into
|
||||
# PoCommentedString.plural
|
||||
def storePlural(self):
|
||||
if self.plural is None:
|
||||
return None
|
||||
else:
|
||||
return self.plural.convert()
|
||||
|
||||
def store(self):
|
||||
global _pending_addedinfo
|
||||
global _pending_addedinfo
|
||||
global _pending_overrideinfo
|
||||
global _linenosub
|
||||
if checkdomain() and self.istranslatable:
|
||||
@ -171,7 +230,8 @@ class PendingLuaString:
|
||||
orderid=(fileno, self.lineno, _linenosub),
|
||||
ismultiline=self.ismultiline,
|
||||
wmlinfos=loc_wmlinfos, finfos=[finfo],
|
||||
addedinfos=loc_addedinfos )
|
||||
addedinfos=loc_addedinfos,
|
||||
plural=self.storePlural() )
|
||||
else:
|
||||
loc_posentence.update_with_commented_string(
|
||||
PoCommentedString(
|
||||
@ -179,7 +239,8 @@ class PendingLuaString:
|
||||
orderid=(fileno, self.lineno, _linenosub),
|
||||
ismultiline=self.ismultiline,
|
||||
wmlinfos=loc_wmlinfos, finfos=[finfo],
|
||||
addedinfos=loc_addedinfos
|
||||
addedinfos=loc_addedinfos,
|
||||
plural=self.storePlural()
|
||||
) )
|
||||
# finally PendingLuaString.store() will clear pendinginfos,
|
||||
# in any case (even if the pending string is not translatable)
|
||||
@ -236,15 +297,22 @@ def addstate(name, value):
|
||||
|
||||
|
||||
|
||||
def setup(dictionary, initialdomain, domain, wall):
|
||||
def setup(dictionary, initialdomain, domain, wall, fdebug):
|
||||
global _dictionary
|
||||
global _initialdomain
|
||||
global _domain
|
||||
global _warnall
|
||||
global _debugmode
|
||||
global _fdebug
|
||||
_dictionary = dictionary
|
||||
_initialdomain = initialdomain
|
||||
_domain = domain
|
||||
_warnall = wall
|
||||
_fdebug = fdebug
|
||||
if fdebug is None:
|
||||
_debugmode = False
|
||||
else:
|
||||
_debugmode = True
|
||||
setup_luastates()
|
||||
setup_wmlstates()
|
||||
|
||||
@ -263,6 +331,7 @@ def run(*, filebuf, fileref, fileno, startstate, waitwml=True):
|
||||
_on_luatag = False
|
||||
# cs is "current state"
|
||||
cs = _states.get(startstate)
|
||||
cs_debug = startstate
|
||||
_current_lineno = 0
|
||||
_linenosub = 0
|
||||
_waitwml = waitwml
|
||||
@ -272,35 +341,48 @@ def run(*, filebuf, fileref, fileno, startstate, waitwml=True):
|
||||
for xline in filebuf:
|
||||
xline = xline.strip('\n\r')
|
||||
_current_lineno += 1
|
||||
# on new line, debug file will write another marker
|
||||
if _debugmode:
|
||||
print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',
|
||||
file=_fdebug)
|
||||
while xline is not None:
|
||||
# action number is used to know what function we should run
|
||||
# debug_file0 = open(os.path.realpath('./debug.txt'), 'a')
|
||||
# print("!!!", xline, file=debug_file0)
|
||||
# debug_file0.close()
|
||||
# print debug infos (if debugmode is on)
|
||||
if _debugmode:
|
||||
lno = '%05d' % _current_lineno
|
||||
print('------------------------------------------------------',
|
||||
file=_fdebug)
|
||||
print('LINE', lno, '|', xline, file=_fdebug)
|
||||
# action number is used to know what function we should run
|
||||
action = 0
|
||||
v = None
|
||||
m = None
|
||||
if cs.regex is None:
|
||||
# action = 1 --> execute state.run
|
||||
action = 1
|
||||
action = 1
|
||||
if _debugmode:
|
||||
print('ALWAYS-RUN x', cs_debug, file=_fdebug)
|
||||
else:
|
||||
# m is match
|
||||
m = re.match(cs.regex, xline)
|
||||
if m:
|
||||
# action = 1 --> execute state.run
|
||||
action = 1
|
||||
if _debugmode:
|
||||
print('RUN state \\', cs_debug, file=_fdebug)
|
||||
else:
|
||||
# action = 2 --> change to the state pointed by
|
||||
# state.iffail
|
||||
action = 2
|
||||
if _debugmode:
|
||||
print('FAIL state |', cs_debug, file=_fdebug)
|
||||
if action == 1:
|
||||
# xline, ns: xline --> override xline with new value
|
||||
# ns --> value of next state
|
||||
xline, ns = cs.run(xline, _current_lineno, m)
|
||||
# debug_cs = ns
|
||||
cs_debug = ns
|
||||
cs = _states.get(ns)
|
||||
else:
|
||||
# debug_cs = cs.iffail
|
||||
cs_debug = cs.iffail
|
||||
cs = _states.get(cs.iffail)
|
||||
# debug_file = open(os.path.realpath('./debug.txt'), 'a')
|
||||
# print(debug_cs, file=debug_file)
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
# encoding: utf8
|
||||
#
|
||||
# wmlxgettext -- generate a blank .pot file for official campaigns translations
|
||||
# (build tool for wesnoth core)
|
||||
@ -48,6 +50,11 @@ def commandline(args):
|
||||
[--no-text-colors] [--fuzzy] [--warnall] [-o OUTPUT_FILE]
|
||||
FILE1 FILE2 ... FILEN'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'--version',
|
||||
action='version',
|
||||
version='wmlxgettext 2016.10.03.py3'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-o',
|
||||
default=None,
|
||||
@ -122,6 +129,15 @@ def commandline(args):
|
||||
"If this option is used, EXPLICIT LIST of files will be "
|
||||
"ignored.")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--DMode',
|
||||
action='store_true',
|
||||
dest='debugmode',
|
||||
default=False,
|
||||
help=("DON'T USE THIS OPTION. It is reserved to test how wmlxgettext "
|
||||
"internally works. If this option is enabled, an extra "
|
||||
"file (debug.txt) will be created. ")
|
||||
)
|
||||
parser.add_argument(
|
||||
'filelist',
|
||||
help='List of WML/lua files of your UMC (source files)',
|
||||
@ -139,8 +155,11 @@ def main():
|
||||
startPath = os.path.realpath(os.path.normpath(args.start_path))
|
||||
sentlist = dict()
|
||||
fileno = 0
|
||||
fdebug = None
|
||||
if args.debugmode:
|
||||
fdebug = open('debug.txt', 'w', encoding='utf-8')
|
||||
pywmlx.statemachine.setup(sentlist, args.initdom, args.domain,
|
||||
args.warnall)
|
||||
args.warnall, fdebug)
|
||||
if args.warnall is True and args.outfile is None:
|
||||
pywmlx.wmlwarn('command line warning', 'Writing the output to stdout '
|
||||
'(and then eventually redirect that output to a file) '
|
||||
@ -231,6 +250,8 @@ def main():
|
||||
print('', file=outfile)
|
||||
if args.outfile is not None:
|
||||
outfile.close()
|
||||
if args.debugmode:
|
||||
fdebug.close()
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user