fix: align and shorten tutorial introduction paragraphs

This commit is contained in:
DragonHD
2026-09-20 11:46:04 +08:00
parent 2e214efeb8
commit 72a3d000dd
5 changed files with 58 additions and 6 deletions
+12 -3
View File
@@ -129,7 +129,7 @@ def encode_literal(text: str) -> bytes:
return b'"' + b''.join(ENCODE_ESCAPES.get(b, bytes((b,))) for b in raw) + b'"'
def patch_display_calls(source: bytes, translations: dict[str, str]) -> bytes:
def patch_display_calls(source: bytes, translations: dict[str, str], *, allow_alignment_changes=False) -> bytes:
literals = extract_display_literals(source)
missing = set(translations) - {literal.text for literal in literals}
if missing:
@@ -141,7 +141,14 @@ def patch_display_calls(source: bytes, translations: dict[str, str]) -> bytes:
translated = translations[literal.text]
if not isinstance(translated, str):
raise ValueError('translation must be a string')
if CONTROLS.findall(literal.text) != CONTROLS.findall(translated):
original_controls = CONTROLS.findall(literal.text)
translated_controls = CONTROLS.findall(translated)
if allow_alignment_changes:
# Explicit opt-in: replace paragraph alignment/indent controls only.
# Newline count/order and all other controls remain protected.
original_controls = ['ALIGN' if c in '\a\b\f\v' else c for c in original_controls]
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):
raise ValueError('format sequence changed: %r' % literal.text)
@@ -157,6 +164,7 @@ def main():
parser.add_argument('--source', required=True, type=Path)
parser.add_argument('--mapping', required=True, type=Path)
parser.add_argument('--out', required=True, type=Path)
parser.add_argument('--allow-alignment-changes', action='store_true')
args = parser.parse_args()
if args.source.resolve() == args.out.resolve():
parser.error('output must differ from source')
@@ -164,12 +172,13 @@ def main():
mapping = json.loads(args.mapping.read_text(encoding='utf-8'))
if not isinstance(mapping, dict):
parser.error('mapping must be an object of original text to translated text')
result = patch_display_calls(source, mapping)
result = patch_display_calls(source, mapping, allow_alignment_changes=args.allow_alignment_changes)
changed = [literal for literal in extract_display_literals(source) if literal.text in mapping]
manifest = {'source': str(args.source.resolve()), 'output': str(args.out.resolve()),
'source_sha256': hashlib.sha256(source).hexdigest(),
'output_sha256': hashlib.sha256(result).hexdigest(),
'mapping_count': len(mapping), 'changed_literals': len(changed),
'allow_alignment_changes': args.allow_alignment_changes,
'changes': [{'start': lit.start, 'end': lit.end, 'call': lit.call,
'argument': lit.argument} for lit in changed]}
args.out.parent.mkdir(parents=True, exist_ok=True)