You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Transcribed foreign names in Chinese (威廉·莎士比亚) parse reversed or not at all #298
Chinese has no dedicated script for foreign names. Where Japanese writes transcriptions in katakana, Chinese writes them in ordinary Han characters — 威廉·莎士比亚 is William Shakespeare — and marks the boundary between name parts with the 间隔号, an interpunct written as U+00B7 (·), U+30FB (・), or U+FF65 (・) depending on the input method. Transcribed names keep their source order: 威廉 (William) is the given name. The interpunct is the only orthographic signal that distinguishes a transcription from a native Han name.
The 2.1 CJK defaults get these names wrong in two different ways, depending on which codepoint the dot happens to be:
>>> parse("威廉・莎士比亚").family # U+30FB — splits, then reversed
'威廉'
>>> parse("威廉·莎士比亚").given # U+00B7 — not a separator at all
'威廉·莎士比亚'
U+30FB / U+FF65 (added as separators in Japanese name segmentation via optional dependency (nameparser[ja]) #272 for katakana names like マイケル・ジャクソン): the name splits into two wholly-Han tokens, script_orders licenses them family-first, and the parts come out reversed. The katakana case is protected because pure katakana is deliberately excluded from the order license; a Han transcription has no such exemption.
U+00B7: not a separator, and it falls outside every script range, so the token is never licensed and the whole string lands in given unsplit.
Two halves to a fix, and the second is the important one:
Order suppression. A name whose tokens were divided by an interpunct is a transcription and should keep source order — the dot plays the same role for Han that pure katakana plays in the ja rule, so this extends the existing "the orthography itself settles the convention" principle rather than adding a heuristic. The implementation cost is that separators are erased during tokenization; the "this boundary was a name dot" fact has to survive to where the order decision is made.
U+00B7 as a separator, guarded. U+00B7 is also the Catalan punt volat, interior to legitimate names (Gal·la), so it can only separate when flanked by CJK on both sides. Separator classification is currently per-character and context-free; this adds the first context-sensitive rule.
Out of scope: the space-separated form. parse("威廉 莎士比亚") also reads family-first today, but nothing distinguishes it by script from a native name like 毛 泽东, and family-first is right for the overwhelmingly more common native case. That limitation should be documented, not fixed.
Design amendment recorded during implementation (PR #305): the fix is codepoint-scoped, which reframes one of this issue's two examples.
The issue called the U+30FB form (威廉・莎士比亚 → family 威廉) "confidently wrong." Implementation surfaced that the same shape carries the opposite convention in Japanese typography: 高橋・一郎 is roster formatting, 姓・名, and 2.1's family-first reading of it (deliberately pinned during #272) is correct. A blanket "dot = transcription" rule would fix the Chinese example by misreading standard Japanese formatting.
Resolution: each dot is read by its own typography's standard — U+00B7, the canonical 间隔号 of the GB punctuation standard, is the transcription marker (divides between classified-script characters, keeps source order, suppresses segmentation); U+30FB/U+FF65 remain pure separators with the script license reading their pieces (kanji pair → family-first roster; katakana → positional). This stays inside the project's doctrine: the orthography itself settles the convention, no language guessing.
Consequence, pinned as a chosen limitation beside the spaced form: a Chinese transcription typed with the Japanese dot (威廉・莎士比亚) reads by the convention of the codepoint it was typed with. Only the Chinese dot rescues a transcription.
Activity
derek73 commentedon Jul 30, 2026
Design amendment recorded during implementation (PR #305): the fix is codepoint-scoped, which reframes one of this issue's two examples.
The issue called the U+30FB form (
威廉・莎士比亚→ family威廉) "confidently wrong." Implementation surfaced that the same shape carries the opposite convention in Japanese typography:高橋・一郎is roster formatting, 姓・名, and 2.1's family-first reading of it (deliberately pinned during #272) is correct. A blanket "dot = transcription" rule would fix the Chinese example by misreading standard Japanese formatting.Resolution: each dot is read by its own typography's standard — U+00B7, the canonical 间隔号 of the GB punctuation standard, is the transcription marker (divides between classified-script characters, keeps source order, suppresses segmentation); U+30FB/U+FF65 remain pure separators with the script license reading their pieces (kanji pair → family-first roster; katakana → positional). This stays inside the project's doctrine: the orthography itself settles the convention, no language guessing.
Consequence, pinned as a chosen limitation beside the spaced form: a Chinese transcription typed with the Japanese dot (
威廉・莎士比亚) reads by the convention of the codepoint it was typed with. Only the Chinese dot rescues a transcription.Retighten the differential rule; pin the review-found gaps (#298)
Declare each ledger's span-bearing rules instead of counting them
Correct four claims the last round got wrong
docs(rules): coherence-review fixes -- the final cross-entry pass
Divide on the 间隔号 and record its offsets (derek73#298)
间隔号-divided names keep source order (derek73#298)
间隔号-divided names skip segmentation (derek73#298)
Pin the interpunct behavior: case rows, corpus, differential guards (d…
Document the interpunct transcription reading (derek73#298)
Polish: the CJK rule slug owns derek73#298; generator docstring tense
Close the review's findings on the gate and the 2.0 ledger
fix(derek73#322): the lookup fold reads every full stop and composes NFC
tooling(differential): re-measure four exemption arguments that were …
docs(design): the contest check covers nesting, not every overlap
tooling(differential): the six 2.x contests get their winners
docs(design): the derek73#501 adjudication