22"""
33scripts/check_markup.py
44
5- Verify that Sphinx roles, inline literals, and format placeholders in the
6- English msgid are preserved verbatim in the Persian msgstr. Catches the most
7- common review slip: translating or mangling `:class:`int``-style markup,
8- ``code`` spans, %s/{0} placeholders, or |substitution| refs.
5+ Verify that Sphinx roles, inline literals, and format placeholders match
6+ exactly between the English msgid and the Persian msgstr — nothing missing,
7+ and nothing extra. Catches both the common review slip (translating or
8+ dropping `:class:`int``-style markup, ``code`` spans, %s/{0} placeholders,
9+ |substitution| refs) and the subtler mistake of adding a reference that
10+ doesn't exist in the original (which Sphinx's own build treats as a hard
11+ error under -W, e.g. "inconsistent term references in translated message").
912
1013Requires: pip install polib
1114
1619"""
1720import re
1821import sys
22+ from collections import Counter
1923from pathlib import Path
2024
2125import polib
@@ -36,17 +40,24 @@ def check_file(path: Path) -> int:
3640 if entry .obsolete or not entry .msgid or not entry .msgstr :
3741 continue # obsolete entry, header, or still untranslated
3842 for label , pattern in PATTERNS :
39- expected = pattern .findall (entry .msgid )
40- if not expected :
43+ expected = Counter (pattern .findall (entry .msgid ))
44+ found = Counter (pattern .findall (entry .msgstr ))
45+ if expected == found :
4146 continue
42- missing = [tok for tok in expected if tok not in entry .msgstr ]
47+
48+ missing = list ((expected - found ).elements ())
49+ extra = list ((found - expected ).elements ())
50+ problems += 1
51+ loc = f" ({ entry .occurrences [0 ][0 ]} :{ entry .occurrences [0 ][1 ]} )" if entry .occurrences else ""
52+ tag = " [fuzzy]" if entry .fuzzy else ""
53+ parts = []
4354 if missing :
44- problems += 1
45- loc = f" ( { entry . occurrences [ 0 ][ 0 ] } : { entry . occurrences [ 0 ][ 1 ] } )" if entry . occurrences else ""
46- tag = " [fuzzy]" if entry . fuzzy else ""
47- print (f"{ path } { loc } { tag } : missing { label } : { missing } " )
48- print (f" msgid : { entry .msgid [:100 ]} " )
49- print (f" msgstr: { entry .msgstr [:100 ]} " )
55+ parts . append ( f"missing { label } : { missing } " )
56+ if extra :
57+ parts . append ( f"extra { label } not in source: { extra } " )
58+ print (f"{ path } { loc } { tag } : { '; ' . join ( parts ) } " )
59+ print (f" msgid : { entry .msgid [:100 ]} " )
60+ print (f" msgstr: { entry .msgstr [:100 ]} " )
5061 return problems
5162
5263
0 commit comments