Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/design/decisions/vocabulary-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The vocabulary was a set of base sets plus marker subsets (`particles` and `part
- **Run last.** Check 10 runs after every other check, so a contributor adding a refused word to a language file meets the exclusion's reason (check 6) rather than an order error, the precedence check 6 is placed first for; the first version ran it at the end of loading, ahead of check 6, and the review of #767 found an excluded word appended to en.toml reported as out of order.
- **The same_as path, not the direct target, and the file's own path.** Keyed by the direct target, a spelling of a spelling sorts apart from the word it spells: ar.toml's `ed-` (same_as `el-`, itself same_as `al-`) would follow `ul-`. The path keeps each spelling under its own head inside the root's group, and it follows only the file's own entries, so a word that is a head in one file and a spelling in another does not make one file's order depend on the other (#767's review found the first version, which followed a map taking each word's first file, accepting `jnr` before `jr` in en.toml once de.toml made `jr` a spelling).
- **No same_as loop, over every same_as written.** Check 7 refuses only a same_as naming its own word. Check 10 refuses any longer loop, in every file, `und.toml` included, over every same_as of every reading: no check holds a word to one head across files or kinds, and the first version, which walked one head per word, passed a loop running through a second file's or a second kind's same_as.
- **Codepoint order of the normalized text.** Defined for every script and every machine, and no one language's collation; the cost is that within a script a precomposed accented letter follows `z` (`aḍ-` after `az-`), and that a traditional and a simplified spelling with no `same_as` between them sort apart (`課長`, `课长`).
- **Codepoint order of the normalized text.** Defined for every script and every machine, and no one language's collation; the cost is that within a script a precomposed accented letter follows `z` (`aḍ-` after `az-`), and that a traditional and a simplified spelling with no `same_as` between them sort apart (`課長` and `课长` did, until #790 linked the pairs in `zh.toml`).
- **A refusal sorts under the kind it refuses.** Forty-six language-file entries on 20b595b2 (`senior`, `fils`, the Slavic `ml` and `st`) hold no vocabulary reading, only an exclusion and sometimes the name reading that is its evidence; they sort beside the words they were refused as. (Corrected 2026-10-19 in #750: the figure was dated "2026-10-19", which #750's title refusals made ambiguous the same day, and the next bullet quoted a und.toml comment that #750 moved out.)
- **`und.toml` is exempt.** Its entries keep the Python lists' order, which its vetting comments still point along (a neighbour "above" or "below"); each category's classification moves its words out, into files that are checked.

Expand Down
2 changes: 1 addition & 1 deletion nameparser/vocab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Every file but `und.toml` lists its words in one order, and the build refuses a
2. **Then by the word it is a spelling of**: a reading's `same_as`, or the word's own text when it has none. A head comes first and its spellings follow it, so `jr` is followed by `jnr` and `junior`, and `sr` by `snr`. A spelling that has spellings of its own heads a group inside its head's: in `ar.toml`, `el-` follows the `a…-` spellings of `al-` with its own assimilated forms after it, and `ul-` comes last. Only the file's own entries are followed, so a word that is a head in one file and a spelling in another is placed in each file by that file alone.
3. **Then by the word's text.**

Text is compared by codepoint. The texts are already normalized, so this is the order of the normalized text, whatever the script: Latin before Cyrillic before Arabic, and within a script an accented letter after `z` (`aḍ-` follows `az-` and `aš-`). It is defined for every script and the same on every machine, and it is no one language's collation. A traditional and a simplified spelling with no `same_as` between them sort apart (`課長` and `课长` in `zh.toml`).
Text is compared by codepoint. The texts are already normalized, so this is the order of the normalized text, whatever the script: Latin before Cyrillic before Arabic, and within a script an accented letter after `z` (`aḍ-` follows `az-` and `aš-`). It is defined for every script and the same on every machine, and it is no one language's collation. A traditional and a simplified spelling with no `same_as` between them sort apart. In `zh.toml` each pair is linked with the Simplified spelling as the `same_as` of the Traditional one, so the Traditional form heads the group (`课长` is `same_as = "課長"`): the Traditional form is the base orthography, and the Simplified one is its derived twin.

The build checks the order and never rewrites a file, because a comment above an entry belongs to it and must move with it, which a TOML reader cannot see. When the build says an entry belongs somewhere else, move it with its comment. The order is checked last, so any other refusal (an exclusion's reason, a `same_as` naming no word) is reported first. The same check refuses a `same_as` chain that loops, in every file.

Expand Down
32 changes: 19 additions & 13 deletions nameparser/vocab/zh.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ side = "after"
issue = 707
note = "#707's one ends-with hit, 厄德二世, is the given name Odo with a regnal numeral in its label"

[[word]]
text = "医学博士"
[word.credential]
acronym = false
issue = 671
note = "Doctor of Medicine"
attached = { side = "after", issue = 707 }

[[word]]
text = "博士"
[word.credential]
Expand All @@ -34,6 +26,15 @@ issue = 671
note = "Doctor of Medicine"
attached = { side = "after", issue = 707 }

[[word]]
text = "医学博士"
[word.credential]
same_as = "醫學博士"
acronym = false
issue = 671
note = "Doctor of Medicine"
attached = { side = "after", issue = 707 }

[[word]]
text = "君"
[word.excluded.honorific]
Expand Down Expand Up @@ -78,6 +79,7 @@ attached = { side = "after", issue = 707 }
[[word]]
text = "太平绅士"
[word.professional_honorific]
same_as = "太平紳士"
issue = 671
note = "Justice of the Peace (Hong Kong)"
attached = { side = "after", issue = 707 }
Expand All @@ -99,6 +101,7 @@ attached = { side = "after", issue = 707 }
[[word]]
text = "社长"
[word.professional_honorific]
same_as = "社長"
issue = 671
note = "simplified; 长 never occurs in Japanese text, so the entry touches no Japanese name"
attached = { side = "after", issue = 707 }
Expand All @@ -111,24 +114,26 @@ note = "section chief; a form of address after a name"
attached = { side = "after", issue = 707 }

[[word]]
text = "議員"
text = "课长"
[word.professional_honorific]
same_as = "課長"
issue = 671
note = "legislator"
note = "simplified twin of 課長"
attached = { side = "after", issue = 707 }

[[word]]
text = "议员"
text = "議員"
[word.professional_honorific]
issue = 671
note = "legislator"
attached = { side = "after", issue = 707 }

[[word]]
text = "课长"
text = "议员"
[word.professional_honorific]
same_as = "議員"
issue = 671
note = "simplified twin of 課長"
note = "legislator"
attached = { side = "after", issue = 707 }

[[word]]
Expand All @@ -142,6 +147,7 @@ attached = "長 alone is a borne given name, so 阿部長 can be 阿部 + 長 (#
[[word]]
text = "部长"
[word.professional_honorific]
same_as = "部長"
issue = 671
note = "simplified twin of 部長"
excluded = { attached = "the simplified twin of 部長, declined with it (#707)" }
Loading