fix: align and shorten tutorial introduction paragraphs
This commit is contained in:
+12
-3
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user