Skip to content
Merged
10 changes: 5 additions & 5 deletions AGENTS.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions docs/concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ this setting vary with?
that varies by **output destination**: the ``spec`` you pass to
``render(spec)``, or a keyword to ``initials()``/``capitalized()``.

"Dean" is a common given name, so it is not in the default titles
vocabulary. But in some data it is more common as a title. The right
"Dean" is a common given name, so the default reads it as a title only
inside a title phrase ("Dean of Students"), and "Dean Martin" keeps
given "Dean". But in some data it is more common as a title. The right
reading is a fact about the domain the names come from: that makes it a
:class:`~nameparser.Lexicon` entry. A CRM that wraps nicknames in
square brackets — ``John [Johnny] Smith`` — instead of quotes is a
Expand Down
41 changes: 31 additions & 10 deletions docs/customize.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ 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`` and
``after_given_titles`` over ``titles``, ``particles_ambiguous`` over ``particles``,
A few fields mark a subset of another — ``given_name_titles``,
``after_given_titles``, ``title_modifiers`` and ``title_styles`` over
``titles``, ``particles_ambiguous`` over ``particles``,
``suffix_acronyms_ambiguous`` over ``suffix_acronyms``,
``conjunctions_ambiguous`` over ``conjunctions``,
``honorific_tails`` and ``suffix_words_ambiguous`` over
Expand All @@ -113,30 +114,48 @@ the marker first. Four of them enforce that — ``particles_ambiguous``,
``suffix_acronyms_ambiguous``, ``honorific_tails`` and
``suffix_words_ambiguous`` raise ``ValueError`` naming the orphans,
because an orphan in each of those does real harm rather than nothing.
The other four are deliberately unchecked because an orphan there is
The others are deliberately unchecked because an orphan there is
inert, an ``agnomens`` entry being read only for a word
``suffix_words_ambiguous`` marks:
``suffix_words_ambiguous`` marks, and a ``title_modifiers`` or
``title_styles`` entry only for a title:
``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`` 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.

``titles_ambiguous`` is the one title field that is no subset of
``titles``: a word in it is a title only inside a title phrase, and a
word in both is a title wherever it stands, which is what listing it in
``titles`` asks. ``title_phrases`` holds the two-word phrases a
``titles_ambiguous`` word may stand in (``"chief justice"``,
``"major general"``), each read only where both words are titles:

.. doctest::

>>> chief = Lexicon.default().remove(title_phrases={"chief justice"})
>>> Parser(lexicon=chief).parse("Chief Justice John Roberts").title
'Chief'

.. _title-detection-off:

Turning title detection off
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The subset rule matters most when clearing a field wholesale. Emptying
``titles`` alone orphans every ``given_name_titles`` entry, so the two
go together:
go together, with ``titles_ambiguous``, whose words are titles inside a
phrase ("Dean of Students") without being in ``titles``:

.. doctest::

>>> d = Lexicon.default()
>>> lean = d.remove(titles=set(d.titles),
... given_name_titles=set(d.given_name_titles))
... given_name_titles=set(d.given_name_titles),
... titles_ambiguous=set(d.titles_ambiguous))
>>> Parser(lexicon=lean).parse("Dean of Students Jane Smith").title
''
>>> Parser(lexicon=lean).parse("Hon Solo").given
'Hon'

Expand Down Expand Up @@ -408,10 +427,12 @@ free:
needs one adds it back with
``Lexicon.default().add(suffix_acronyms={"cha"})``.

The same conservatism is why ``dean`` above isn't in the default
vocabulary in the first place: "Dean" is also a common given name, and
a default that swallowed it as a title would misparse "Dean Martin" for
everyone.
The same conservatism is why ``dean`` above is a title by default only
inside a title phrase ("Dean of Students", "Associate Dean"): "Dean" is
also a common given name, and a default that swallowed it as a title
would misparse "Dean Martin" for everyone. Listing it in ``titles``
makes it a title wherever it stands. The phrase-only titles are
``Lexicon.titles_ambiguous``.

Particles that are also given names
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
36 changes: 36 additions & 0 deletions docs/design/decisions/H9-title-phrase.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/design/decisions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Entry conventions:
- [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)
- [H9 — the title phrase](H9-title-phrase.md)

## Particles & surname prefixes (P)

Expand Down
4 changes: 3 additions & 1 deletion docs/design/decisions/salutation-titles.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ Closes #606 (#662 later added owura and bapak, its bullet below, and #847 cllr).
- A word that addresses or ranks a person and is written in FRONT of the name ships as a title unless it is borne as an ordinary name in the leading position, the position test of vocabulary-collisions' C-i, TITLES having no ambiguous subset to mark a collision in, so the only answers are ship and do not ship — 2026-10-04 #606.
- One exception to C-i, for TITLES alone: a word borne as a name only RARELY as the first word of one ships on the precedent of `graf` (`herra`, `batoni`, `hrabia`, `kreivi` and the rest of the graf class, each with its counts on its title reading's `note`), and no word in the particle or suffix sets, and no later title, takes it without its own counts — 2026-10-04 #606.
- The cost falls on a name that BEGINS with such a word: `Greve Anna` reads title 'Greve', family 'Anna' and `Herra Wijaya` title 'Herra', family 'Wijaya'; a declared `FAMILY_FIRST` does not help (`Hrabia Anna` reads title 'Hrabia' under it); the family comma keeps the word as the family where no name word stands behind it (`Hrabia, Anna` reads given 'Anna', family 'Hrabia', and so does `Hrabia Jr., Anna`), while a name word behind it makes it the title by H6 (`Hrabia Nowak, Anna` reads title 'Hrabia', family 'Nowak'); a name that ends in the word keeps it (`Gladys Knight`, `Knight, Gladys` read family 'Knight'), unless a period follows it (`Gladys Knight.` reads title 'Knight.', family 'Gladys', by H5, accepted rather than prevented) — 2026-10-04 #606.
- Words judged a COMMON leading-position name stay out (`thiru`, `puan`, `pan`, `rodina`, `ông` and its pair `bà`, and `marshal` and `justice`, whose accepted costs their entries state: `Field Marshal Bernard Montgomery` reads title 'Field', given 'Marshal'), and words with no evidence either way are not shipped (`gróf`, `cik`, `paron`, `tikin`, `janab`), each an `excluded` entry in its language's file (`uv run python tools/vocab/query.py --excluded title --issue 606`) — 2026-10-04 #606.
- Words judged a COMMON leading-position name stay out (`thiru`, `puan`, `pan`, `rodina`, and `ông` and its pair `bà`), and words with no evidence either way are not shipped (`gróf`, `cik`, `paron`, `tikin`, `janab`), each an `excluded` entry in its language's file (`uv run python tools/vocab/query.py --excluded title --issue 606`) — 2026-10-04 #606.
- Accents are not folded, so `paní` and `härra` match only their accented spellings (`Paní Nováková` reads title 'Paní', `Pani Anna` reads given 'Pani'); folding the lexicon would turn both into collisions, and whoever proposes it re-argues the entry — 2026-10-04 #606.
- `gravos` was dropped, not excluded, since nothing showed it is the Greek word for Count; `κόμης`, a Greek surname written first in official lists, is neither added nor excluded, and adding it is a decision still to make — 2026-10-04 #606.
- `knt` (Knight, beside `kt`) is a suffix acronym with a `Knt` case mask: `Mary Knt` reads suffix 'Knt' — 2026-10-04 #606.
- `cllr` (Councillor, British, written bare) is a title, on counts under 100 US Census bearers and none found as a name elsewhere — 2026-10-22 #847.
- `owura` (Akan) and `bapak` (Indonesian) are titles, on counts under 100 US Census bearers each and none found on Wikidata, and `malam` (Hausa) and `bay` (Turkish) are excluded, each an `excluded` entry with its counts — 2026-10-17 #662.
- The Italian abbreviated salutations and letter-heading honorifics whose letters after the full stop are the word's own ending ship as titles with `cased` masks: `sig.ra`, `sig.na`, `dott.ssa`, `prof.ssa`, `gent.mo`, `gent.ma`, `gent.le`, `ill.mo`, `ill.ma`, `ch.mo`, `ch.ma`, `preg.mo`, `preg.ma` (`Dott.ssa Anna Bianchi` reads title 'Dott.ssa', given 'Anna'; `SIG.RA MARIA ROSSI` repairs to 'Sig.ra Maria Rossi'); the bare `sig` and `ing` are excluded as given names, their period-marked spellings already titles by H2's shape, except `Ing.` after a full name and a comma, which is the ambiguous credential decisions/suffix-acronym-collisions lists (#848) — 2026-10-22 #840.

Elsewhere: `justice` and `marshal`, excluded here as common leading-position names, are titles only inside a title phrase since 2026-10-25 and 2026-10-26 (`Chief Justice John Roberts` reads title 'Chief Justice' and `Field Marshal Bernard Montgomery` title 'Field Marshal', `Justice Smith` and `Marshal Yanda` the given name) — decisions/H9's 2026-10-25 #752, phase 2i entry; decisions/H9's 2026-10-26 #752, phase 2i (Derek) entry.

## Log

- 2026-10-04 #606 (its family-comma remedy superseded in part by #701, decisions/H6) — SALUTATIONS, OFFICES AND RANKS FOR THE LANGUAGES TITLES HAD NONE FOR: the undated bullets below, through the measurement.
Expand Down
Loading
Loading