feat: complete Chinese tutorial text and layout validation
This commit is contained in:
+21
-1
@@ -20,6 +20,15 @@ FORMAT = re.compile(r'%%|%[-+ #0]*[\d*]*(?:\.[\d*]+)?[hlL]?[diouxXeEfgGcs%]')
|
||||
CONTROLS = re.compile(r'[\a\b\f\n\r\t\v]')
|
||||
|
||||
|
||||
def format_tokens(text):
|
||||
# "speed 0% is ..." is prose, not the printf conversion "% i".
|
||||
# Only exclude a numeric percent whose apparent conversion cuts a word.
|
||||
return [m.group() for m in FORMAT.finditer(text)
|
||||
if not (m.start() > 0 and text[m.start() - 1].isdigit()
|
||||
and m.end() < len(text) and text[m.end()].isascii()
|
||||
and text[m.end()].isalpha() and ' ' in m.group())]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Literal:
|
||||
start: int
|
||||
@@ -121,6 +130,17 @@ def extract_display_literals(source: bytes, encoding: str = 'latin1') -> list[Li
|
||||
if len(arg) == 1 and arg[0].kind == 'string':
|
||||
lit = arg[0]
|
||||
found.append(Literal(lit.start, lit.end, lit.value, token.value, number))
|
||||
elif (len(arg) == 3 and [t.kind for t in arg] == ['string', 'name', 'string']
|
||||
and arg[1].value == 'F'
|
||||
and arg[0].value.startswith('\fTo use a charged spell select it')
|
||||
and arg[0].value.endswith('pressing the ')
|
||||
and arg[2].value.startswith(' KEY marked under it')):
|
||||
# Stock English Tutorial.dsc has unescaped quotes around F in
|
||||
# this specific display argument. Keep the complete text span;
|
||||
# do not generalize to expressions or other malformed strings.
|
||||
found.append(Literal(arg[0].start, arg[2].end,
|
||||
arg[0].value + '"F"' + arg[2].value,
|
||||
token.value, number))
|
||||
return sorted(found, key=lambda literal: literal.start)
|
||||
|
||||
|
||||
@@ -150,7 +170,7 @@ def patch_display_calls(source: bytes, translations: dict[str, str], *, allow_al
|
||||
translated_controls = ['ALIGN' if c in '\a\b\f\v' else c for c in translated_controls]
|
||||
if original_controls != translated_controls:
|
||||
raise ValueError('control sequence changed: %r' % literal.text)
|
||||
if FORMAT.findall(literal.text) != FORMAT.findall(translated):
|
||||
if format_tokens(literal.text) != format_tokens(translated):
|
||||
raise ValueError('format sequence changed: %r' % literal.text)
|
||||
replacements.append((literal.start, literal.end, encode_literal(translated)))
|
||||
result = source
|
||||
|
||||
Reference in New Issue
Block a user