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
14 changes: 7 additions & 7 deletions AGENTS.md

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions docs/customize.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,22 @@ Removing works the same way, and drops the word from recognition:
>>> Parser(lexicon=lean).parse("Professor Robert Johns").title
''

A few fields mark a subset of another — ``given_name_titles`` over
``titles``, ``particles_ambiguous`` over ``particles``,
A few fields mark a subset of another — ``given_name_titles`` and
``after_given_titles`` over ``titles``, ``particles_ambiguous`` over ``particles``,
``suffix_acronyms_ambiguous`` over ``suffix_acronyms``,
``conjunctions_ambiguous`` over ``conjunctions``, and
``honorific_tails`` over ``suffix_words``. Entries belong in the base
field too, so add to both and remove from the marker first. Three of
them enforce that — ``particles_ambiguous``, ``suffix_acronyms_ambiguous``
and ``honorific_tails`` raise ``ValueError`` naming the orphans, because
an orphan in each of those does real harm rather than nothing. The
other two are deliberately unchecked because an orphan there is inert:
other three are deliberately unchecked because an orphan there is inert:
``given_name_titles`` matches a title run as one space-joined string, or
by that run's last word, so a legitimate entry like ``"sir and dame"``
is no single word in ``titles``; and a ``conjunctions_ambiguous`` entry
is only ever read for a word that is a conjunction, so
``remove(conjunctions={"e"})`` simply works and the stale marker entry
is never consulted.
is no single word in ``titles``; and a ``conjunctions_ambiguous`` or
``after_given_titles`` entry is only ever read for a word that is a
conjunction or a title, so ``remove(conjunctions={"e"})`` simply works
and the stale marker entry is never consulted.

.. _title-detection-off:

Expand Down
4 changes: 2 additions & 2 deletions docs/design/decisions/H5-trailing-title-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Standing

- After the trailing suffix run, successive period-marked words the title vocabulary lists chain into the title from the end, leaving one name word standing, and join the title field in input order: `John Smith Prof.` → title 'Prof.', family 'Smith'; `John Smith Prof. Dr.` → title 'Prof. Dr.'; `Dr. John Smith Prof.` → title 'Dr. Prof.' — 2026-09-08 #316.
- The back is claimed by vocabulary and the front by shape, so an unlisted abbreviation (`John Smith Xyz.` → family 'Xyz.') and a bare title word (`John Smith Sir`, `Mary Jane King`) are name words there, the walk asking `is_title_piece` and never `is_leading_title` — 2026-09-08 #316.
- The back is claimed by vocabulary and the front by shape, so an unlisted abbreviation (`John Smith Xyz.` → family 'Xyz.') and a bare title word (`John Smith Sir`, `Mary Jane King`) are name words there, the walk asking `is_title_piece` and never `is_leading_title` — 2026-09-08 #316. A listed salutation ending the given part after a family comma is the exception, read as the title bare (decisions/H8).
- No fork is reported; where the doubt is real, the word left standing carries it (H4) — 2026-09-08 #316.
- The given part after a family comma gets the walk: `Smith, John Prof.` → title 'Prof.', given 'John' — 2026-09-08 #316.
- The trailing peel and the title chain are one reading run to a fixed point (`_pieces.tail_reading`), so a trailing title is transparent to the suffix reading (`John Smith Jr. Prof.` → suffix 'Jr.'; `abdul rahman MA Prof.` reads as `abdul rahman MA` does, plus the title), and the bound join takes no piece the chain takes (`Sir abdul Prof.` → given 'abdul') — 2026-09-09 (the /simplify round on the bundle's PR).
Expand All @@ -18,7 +18,7 @@ Open: none in this file.

## Log

- 2026-09-08 (the #316/#489 bundle; closes #316(a)) (A1's scope superseded by review round 2 and its single re-peel by the /simplify round, both below; A1's `John Prof. MA` family 'MA' by #289, decisions/S6, `John MA` reading suffix 'MA'; A2's `Smith, John Prof. MA` middle by #531, decisions/S5; the detail mismatch by #626, decisions/A1; Q3's unconditional H2 in part by #761, decisions/H2, C13 winning after a family comma) — a trailing run of period-marked title words is a title. `John Smith Prof.` read family `Prof.` and lost the surname while `Smith, Prof.` read title `Prof.`; the two comma paths disagreed and #316 is that question. They agree now.
- 2026-09-08 (the #316/#489 bundle; closes #316(a)) (A1's scope superseded by review round 2 and its single re-peel by the /simplify round, both below; A1's `John Prof. MA` family 'MA' by #289, decisions/S6, `John MA` reading suffix 'MA'; A2's `Smith, John Prof. MA` middle by #531, decisions/S5; the detail mismatch by #626, decisions/A1; Q3's unconditional H2 in part by #761, decisions/H2, C13 winning after a family comma; the bare title word's name-word reading in part by 2026-10-24 #835, decisions/H8, for a listed salutation ending the given part after a family comma) — a trailing run of period-marked title words is a title. `John Smith Prof.` read family `Prof.` and lost the surname while `Smith, Prof.` read title `Prof.`; the two comma paths disagreed and #316 is that question. They agree now.
- **The doctrine, stated rather than left to be inferred.** A period-marked word is claimed by SHAPE at the front and by VOCABULARY at the back. At the front an unlisted abbreviation is a title (#H2) and the shape outranks the vocabulary, which is why `Esq. Smith` reads title though `esq` is post-nominal vocabulary. At the back there is no shape rule, so only a listed title word chains into the title and `John Smith Xyz.` keeps family `Xyz.`. A BARE title word at the back is a name word — `John Smith Sir` and `Mary Jane King` are untouched — TITLES holding ordinary surnames being exactly why, which is the Excluded (TITLES) block in decisions/vocabulary-exclusions ("the trailing-position rule that must NOT be adopted"). The asymmetry is honest rather than an oversight: #109 shipped the leading inference on purpose, and no blanket trailing vocabulary rule is safe while king, judge and bishop are titles.
- **Q3 declined: H2 stays unconditional.** #316's open question 2 asked for the symmetric leading rule, `Esq. Smith` → suffix. Declined: it reverses rules/S2's "a suffix never opens the string" for period-marked words for the sake of one word, and the family comma already carries the credential case (`Smith, Esq.` → suffix). Recorded at #H2, where the `Open: #316` hook was.
- **Q2 decided: a RUN, mirroring #H3.** Successive single words that wear the abbreviation shape AND are title vocabulary chain into the title from the end, floor one name piece, so `John Smith Prof. Dr.` reads title `Prof. Dr.` rather than making `Prof.` a name word. Not chosen: one word only, which would have left `Prof.` standing as a name word in exactly the input the rule is about. The title field joins in INPUT order and the rendering needed no change — the title view joins TITLE tokens in token order already, so `Dr. John Smith Prof.` reads title `Dr. Prof.` for free.
Expand Down
22 changes: 22 additions & 0 deletions docs/design/decisions/H8-salutation-ending-the-given-part.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# H8 — a salutation ending the given part

## Standing

- A salutation ending the given part after a family comma, written bare or with a stop at its edge that H5's abbreviation shape does not take (`Mr..`), is the title, read as its period-marked spelling reads in every comma shape and under every name order: `Doe, Jane Mrs` → title 'Mrs', given 'Jane'; `DOE, JOHN Q MR` → title 'MR', middle 'Q' — 2026-10-24 #835.
- Only the salutations marked `after_given` in the vocabulary qualify, and a salutation borne as a given name or a surname is left out by an exclusion carrying its counts, since a middle name may be either (`Doe, John Goodman` keeps middle 'Goodman') — 2026-10-24 #835.
- No other title kind qualifies (`Doe, John King` and `Doe, Jane Dr` keep their middle names), a title/suffix dual stays a suffix (`Doe, Jane Ms`), and the comma-less writing is H5's (`Jane Doe Mrs` keeps family 'Mrs') — 2026-10-24 #835.
- A salutation that is someone's middle name reads as the title after a family comma, an accepted cost (`Doe, Jane Miss`); so does the empty head's one given word moving to the family as the period-marked spelling moves it (`, Jane Mrs` → family 'Jane') — 2026-10-24 #835.
- The rule reads the comma, not a declared order: `Doe Jane Mrs` under FAMILY_FIRST keeps middle 'Mrs', so the family-comma invariant of decisions/two-input-invariants does not hold for a trailing salutation — 2026-10-24 #835.

Open: [#877](https://github.com/derek73/python-nameparser/issues/877) (whether a bare `I` or `V` the salutation leaves ending the given part, read as the suffix by rules/C9, should report `suffix-or-name`).

## Log

- 2026-10-24, #835 — A BARE SALUTATION ENDING A FAMILY COMMA'S GIVEN PART IS THE TITLE. `Doe, Jane Mrs` read middle 'Mrs' while `Doe, Jane Mrs.` (H5) and `Doe, John Jr Mr` (the salutation behind a post-nominal) read title, and `Doe, John Mr Jr` read middle 'Mr'; 1.4.0 and 2.5.0 read the first as middle 'Mrs' too (wheels checked 2026-10-24). The FEC's itemized contributions write `FAMILY, GIVEN MIDDLE SALUTATION` in capitals, the period often left off: on #834's `fec-individuals` corpus (file dated 2026-10-18, measured 2026-10-22, figures in #835) 13,243 names ended in a bare title word read as a middle name, `MR` 8,483 of them.
THE REASON H5's BARE-WORD CLAUSE DOES NOT REACH HERE. H5 keeps a bare title word at the end of a name as a name word because TITLES holds ordinary surnames (`Mary Jane King`). After a family comma the surname's place is marked, so only the middle-name reading is left against the title, and of the title kinds (#750) the salutation is the one that is a form of address and not something a person is named after. So the rule is keyed on that kind, and narrower than the kind: the property marks the salutations not borne as names.
THE VOCABULARY. A behavioral title property, `after_given = true`, allowed on a `salutation` reading only (a build check), compiles into `AFTER_GIVEN_TITLES` and the new `Lexicon.after_given_titles`; v1's `Constants` has no attribute for it, and `_snapshot()` intersects it with the titles, so deleting the title is the v1 knob. Considered and not taken: keying the rule on the `salutation` kind itself, with exclusions for the borne words — it makes a kind compile into a behavior, where every behavior so far is a property (decisions/vocabulary-model).
THE VETTING (`uv run python tools/name_usage.py --json` over every salutation and the romanizations of the non-Latin ones, 2026-10-24). A middle name may be a given name or a surname, so a word borne as either is excluded. Excluded, each with its counts on the word: goodman (US Census 2010 surname 73,136), herr (11,980), herren (4,466), master (2,735; SSA given 476), mister (1,211; SSA 746), señora (SSA given 1,065, as SENORA), signor (999), signore (895), herra (638), paní (403, as PANI), señor (282, as SENOR), härra (237, as HARRA), fru and frú (a Cameroonian surname, about 10,800 bearers by the note on sv.toml's entry, and 132 in the Census), пан (Wikidata family 743), the Bengali মোঃ and মো (they abbreviate Mohammad, which #853 reads as a given name where it leads), श्री/শ্রী (also an element of given names, Sri or Shri; one Wikidata given-name bearer, excluded on the doubt rather than the count) and बाबू (romanized Babu, Census surname 1,496, ranked a given name in India and Sri Lanka by nam_dict, and an element of compound given names such as Ram Babu). A diacritic-free count stands for an accented word, the Census and SSA writing none. A romanization counts for a word in another script only where its bearers write that script: बाबू's do, while the bearers of the romanizations of सौ (Sau, Vietnamese), মি (Mi, Korean and Chinese), κα (Kyria, US given names) and пані (Pani, an Indian surname) do not, so those are kept. Kept with small counts, recorded on each word as a name reading: miss (Census surname 164), heren (123), sra (Census surname 149, SSA given 27), signora (SSA given 90), señorita, bwana and mr (SSA under 10 each), frau (Wikidata family 42), and gospodin (a Bulgarian given name in nam_dict, band 5, kept because a Bulgarian middle name is a patronymic, Gospodinov, rather than the given name itself). The line at roughly 200 US bearers is a judgment, not a measured threshold. ms and sr carry no flag, being title/suffix duals the suffix reading takes first. `hr` was excluded on the FEC read below. Recompute the set: `uv run python tools/vocab/query.py --kind salutation`, and the refusals with `--excluded after_given`.
THE MECHANISM. H5's trailing title chain, in the given part after a family comma, admits a word the vocabulary marks, matched after its edge stops are folded, so a doubled stop (`Mr..`, which is not H5's abbreviation shape) is admitted as the bare word is. Everything H5's chain already does there — transparency to the suffix reading, the floor leaving one name piece, the title joining the field in input order — holds for it unchanged. The group-side predictors of that part (the particle chain's bound and the bound given-name join's decline, which read the part as `tail_reading` reads it) admit the same words, so they cannot disagree with the walk (the Gotcha on group-side predictors in AGENTS.md). Measured: over a grid of nine family-comma heads (an empty head, a nickname-only head, particle and connective surnames, a suffix and a title before the comma), 21 given parts (initials, a bound given name, particles, a title-particle, an ambiguous acronym, numerals V and VI, a post-nominal, a one-case part), seven salutation spellings and six tails (a second comma, a trailing suffix, acronym or period-marked title), under all three name orders, every one of the 23,814 bare rows reads exactly as its period-marked twin reads, fields and ambiguity kinds both, and none of the period-marked rows moved against master `3f8e29b2`.
THE CORPORA (measured 2026-10-24 against master `3f8e29b2`, py3.11). No committed corpus name moved: the snapshot gains only this rule's own examples, and the CLDR, GND and Wikidata agreement views match their records. `snapshot.py --local fec-individuals`, base recorded with `--tree`: 12,381 of 1,893,964 names move, each a salutation leaving the middle name for the title, some with a credential or a generational word behind it: `MR` 9,339, `MRS` 1,908, `MISS` 1,108, `MR..` 24, and two more joining a title already read. Three had read `HR` as the Danish and German abbreviation of Herr, one of them behind a woman's given name: in US data it is more likely two initials run together, so `hr` was excluded on that evidence and those three are not among the moves. 385 of the moves lose a `CONJUNCTION_OR_INITIAL` report (`DOE, JOHN E MR`): with the salutation gone the letter has no name word behind it to connect, which is what P8 asks. In 361 of them the letter stays a middle initial; the other 24 are among the 59 below. `ukec-individuals` does not move.
A CONSEQUENCE NOT DECIDED HERE: 59 of the FEC moves end the given part in a lone `V` or `I` once the salutation is the title (`DOE, JANE I MRS`), which then reads as the generational suffix, as `DOE, JANE I` and `DOE, JANE I MRS.` already read on master (#144's lenient tail test after a family comma). In these names it is a middle initial. The bare spelling now reads as its twins read; whether #144's reading should change is its own question.
THE FAMILY-FIRST WRITING (the design-docs review). A declared FAMILY_FIRST order fixes the surname as a comma does, but the rule reads only the comma: `Doe Jane Mrs` under FAMILY_FIRST keeps middle 'Mrs' (FAMILY_FIRST_GIVEN_LAST: given 'Mrs'). decisions/two-input-invariants pairs those two writings; over the 82 flagged words written without a stop, an apostrophe or a hyphen, each after three family and three given names, they agree on 738 of 738 pairs on master and on none now. Recorded as an Accepted clause of rules/H8 rather than extended: the declared order says where the surname is, not where the given part ends, and the trailing slot of a comma-less name is H5's.
1 change: 1 addition & 0 deletions docs/design/decisions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Entry conventions:
- [H5 — the trailing title run](H5-trailing-title-run.md)
- [H6 — a title before a family comma](H6-title-before-a-family-comma.md)
- [H7 — a joined name unit carrying title vocabulary](H7-joined-name-unit-carrying-title-vocabulary.md)
- [H8 — a salutation ending the given part](H8-salutation-ending-the-given-part.md)

## Particles & surname prefixes (P)

Expand Down
Loading
Loading