Skip to content

Commit 8d1af36

Browse files
derek73claude
andauthored
Decline a title word a trailing rule reads, in the bound join (#637, #640) (#643)
P5's bound given-name join took the word after `abdul` even where a trailing rule would read it as a title, so the joined piece was no title word: `Berg, abdul Prof.` read given 'abdul Prof.' (#637) and `John Smith, Jr., abdul Dr. Smith` read suffix 'Jr., abdul Dr. Smith' (#640). The join now declines such a word: after a family comma one H5's trailing run takes from the given part, read as the comma-less name reads it, and in a part past the second comma any title word, which C2 reads. A title word standing in the name still joins (`abdul Sir Smith Berg`, `Berg, abdul Prof. Ali`), as P5 states. Decided (Derek): this narrower clause over declining every title word, which split 3,000 grid joins with no title read; and where the given part's own walk reads the words behind a title otherwise (a numeral VI to X, V before a third part, a title-particle P6 attaches), the join is declined with no title read -- recorded in rules.md#P5 as an Accepted clause rather than narrowed, as #623's disagreement was. Measured against 4455962: 1,044 of 15,552 bound-given grid parses move, each a title into the title field; among corpus names and case texts only the row that pinned the gap. Five gates exit 0. Rows pin both halves, a bare title past the second comma and a run of trailing titles. No frame on a comma-less bound name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 48f97d0 commit 8d1af36

11 files changed

Lines changed: 193 additions & 40 deletions

File tree

‎docs/design/decisions.md‎

Lines changed: 7 additions & 4 deletions
Large diffs are not rendered by default.

‎docs/design/rules.md‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,12 @@ H5. Rationale: a word abbreviated with a period at the END of a name
352352
title absent — and lands in the same field, the run in FRONT of
353353
the joined pair being the run H1 asks about. Said of the
354354
comma-less writing, which is where the chain runs before the
355-
reserve is read. After a family comma the reserve reads no peel
356-
at all (P5), so the join there takes the trailing title word into
357-
the given name and the chain never sees it, where the same
358-
segment writing with an ordinary given name reads the title. A
359-
gap in the segment path rather than a boundary of this rule, and
360-
tracked as part of #316. Pinned by a case row rather than by an
361-
example here, so recording the gap does not make it normative.
355+
reserve is read. After a family comma the reserve reads no peel,
356+
but the join declines a trailing title word the chain takes (P5),
357+
so the title is read there too, save the shapes P5's Accepted
358+
clause records, as the segment written with an ordinary given
359+
name reads it.
360+
"Berg, abdul Prof." → title="Prof."
362361
history: decisions.md#H5 · interacts: H1, H2, H3, H4, M2, P2, P5, P6, S2, C1 · implemented: nameparser/_pipeline/_assign.py, nameparser/_pipeline/_group.py, nameparser/_pipeline/_pieces.py
363362

364363
## Particles & surname prefixes (P)
@@ -723,7 +722,11 @@ P5. Rationale: some given-name words are incomplete alone — "abdul"
723722
them asks the question about a name that will not exist. The join
724723
never absorbs a marker standing as a word of its own — a marker
725724
is not a name word (M2) — nor a word of the unambiguous suffix
726-
vocabulary (S2), wherever position will then place it; a bare
725+
vocabulary (S2), wherever position will then place it, nor a
726+
title word a trailing rule reads as a title: one the trailing
727+
title run (H5) takes from the given part after a family comma,
728+
read as the comma-less name reads it, or any title word in a part
729+
past the second comma (C2); a bare
727730
ambiguous acronym is a name word wherever the peel does not take
728731
it; a marker left as a word that a particle join (P2) has already
729732
taken travels with that join. A title word standing in the name
@@ -772,6 +775,9 @@ P5. Rationale: some given-name words are incomplete alone — "abdul"
772775
"abdul Sir Smith Berg" → given="abdul Sir"
773776
"Berg, abdul van" → given="abdul van"
774777
"Berg, abdul vd" → family="vd Berg"
778+
"Berg, abdul Prof." → given="abdul"
779+
"Berg, abdul Prof. Ali" → given="abdul Prof." · boundary
780+
"John Smith, Jr., abdul Dr. Smith" → title="Dr."
775781
"abdul Jr Smith Berg" → given="abdul"
776782
"abdul Jr Smith Berg" → middle="Jr Smith"
777783
"abdul Ph. D. Smith Berg" → suffix="Ph. D."
@@ -795,7 +801,15 @@ P5. Rationale: some given-name words are incomplete alone — "abdul"
795801
"Sheik abdul salam" family-first → family="abdul salam"
796802
"Sheik abdul salam" family-first → given=""
797803
"Sheik abdul salam" family-first-given-last → family="abdul salam"
798-
history: decisions.md#P5 · interacts: S2, M2, H1, H5, P2, P4, P6 · implemented: nameparser/_pipeline/_group.py, nameparser/_pipeline/_post_rules.py
804+
Accepted: the given part after a family comma reads the words
805+
behind a title by its own walk, and where that walk reads them
806+
otherwise than the comma-less name does, the join is declined and
807+
no title is read — a shape-only numeral (VI to X), or V before a
808+
third comma part, stays a name word there, and a title word that
809+
is also a particle is attached by P6 (`Berg, abdul Prof. VI`
810+
reads middle 'Prof. VI'; `Berg, abdul St.` reads family 'St.
811+
Berg'), each as the same name with an ordinary given word reads.
812+
history: decisions.md#P5 · interacts: C2, S2, M2, H1, H5, P2, P4, P6 · implemented: nameparser/_pipeline/_group.py, nameparser/_pipeline/_post_rules.py
799813

800814
P6. Rationale: a particle ending the name has nothing to link
801815
forward to, so it is not doing a particle's work there. What it
@@ -2114,7 +2128,7 @@ C2. Rationale: text beyond the recognized comma parts should be
21142128
reports on outside a tail:
21152129
the_chain_reports_the_acronym_it_takes and
21162130
titled_particle_chain_survives_a_title_that_is_also_a_particle.
2117-
history: decisions.md#C1, decisions.md#S2 · interacts: C1, H5, P2, S2, S3 · implemented: nameparser/_pipeline/_segment.py, nameparser/_pipeline/_assign.py, nameparser/_pipeline/_group.py
2131+
history: decisions.md#C1, decisions.md#S2 · interacts: C1, H5, P2, P5, S2, S3 · implemented: nameparser/_pipeline/_segment.py, nameparser/_pipeline/_assign.py, nameparser/_pipeline/_group.py
21182132

21192133
## Name order (O)
21202134

‎docs/release_log.rst‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Release Log
2222

2323
- **Fix a credential run after a comma losing the name in front of it when two surname particles stand side by side in the run.** ``HumanName("John Smith, PhD DO DO")`` gives first ``John``, last ``Smith``, suffix ``PhD DO DO``, where 2.2 and 2.3 gave first ``PhD``, last ``DO DO John Smith`` and 2.0 and 2.1 gave title ``PhD``, first ``DO DO`` -- 1.4.0's reading, restored. ``DO``, ``MC`` and ``VD`` are credentials and surname particles at once, and two particles next to each other had joined into one particle run that took the credentials apart; the part after the comma is now read as credentials before any particle can join it. ``John Smith, PhD vd DO`` gives suffix ``PhD vd DO`` the same way, and ``John Smith, MD DO DO`` gives suffix ``MD DO DO`` where 2.3 gave title ``MD``, first ``DO``, middle ``DO``. A single ``DO`` is still left to its capitals (``John Smith, PhD DO`` gives suffix ``PhD DO``), and with one name word before the comma a part of credentials is all suffixes (``Smith, PhD DO DO`` gives last ``Smith``, suffix ``PhD DO DO``, and ``Smith, MA DO DO`` last ``Smith``, suffix ``MA DO DO``, where 2.3 gave first ``PhD`` and first ``MA``, last ``DO DO Smith``). See the #562 entry under ``C1`` in ``docs/design/decisions.md`` (closes #562)
2424

25-
- **Fix a trailing title being taken into a surname that begins with a particle.** ``HumanName("John van der Berg Prof.")`` gives title ``Prof.``, last ``van der Berg``, where every release from 1.4.0 through 2.3.0 gave last ``van der Berg Prof.``. The suffixes and titles at the end of a name are now read before the surname's particles join the words after them, so the particles no longer take a title in. The given part behind a family comma reads the same way: ``HumanName("Smith, John van der Berg Prof.")`` gives title ``Prof.``, middle ``van der Berg``, and ``Smith, Jan van Prof.`` gives title ``Prof.``, last ``van Smith``, as ``Smith, Jan van`` gives last ``van Smith``, where 1.4.0 through 2.3.0 gave middle ``van der Berg Prof.`` and ``van Prof.``. The same reading order brings back 1.4.0's ``HumanName("abdul J. V")``: first ``abdul J.``, last ``V``, where 2.2 and 2.3 gave first ``abdul``, middle ``J.``. See the #614 entry under ``S2`` and the #623 entry under ``H5`` in ``docs/design/decisions.md`` (closes #614, #623)
25+
- **Fix a trailing title being taken into a surname that begins with a particle.** ``HumanName("John van der Berg Prof.")`` gives title ``Prof.``, last ``van der Berg``, where every release from 1.4.0 through 2.3.0 gave last ``van der Berg Prof.``. The suffixes and titles at the end of a name are now read before the surname's particles join the words after them, so the particles no longer take a title in. The given part behind a family comma reads the same way: ``HumanName("Smith, John van der Berg Prof.")`` gives title ``Prof.``, middle ``van der Berg``, and ``Smith, Jan van Prof.`` gives title ``Prof.``, last ``van Smith``, as ``Smith, Jan van`` gives last ``van Smith``, where 1.4.0 through 2.3.0 gave middle ``van der Berg Prof.`` and ``van Prof.``. The same reading order brings back 1.4.0's ``HumanName("abdul J. V")``: first ``abdul J.``, last ``V``, where 2.2 and 2.3 gave first ``abdul``, middle ``J.``. A bound given name behind a family comma no longer takes a trailing title into it: ``HumanName("Berg, abdul Prof.")`` gives title ``Prof.``, first ``abdul``, where 1.4.0, 2.2.0 and 2.3.0 gave first ``abdul Prof.`` and 2.0.0 and 2.1.0 middle ``Prof.``. See the #614 entry under ``S2``, the #623 entry under ``H5`` and the #637 entry under ``P5`` in ``docs/design/decisions.md`` (closes #614, #623, #637)
2626

2727
- **New Policy field unlisted_dotted_suffixes, on by default: a dotted acronym nobody has listed is read by position.** ``HumanName("John Smith X.Y.Z.")`` gives suffix ``X.Y.Z.`` where every release gave last ``X.Y.Z.``, while ``Jack X.Y.Z.`` keeps its surname, the same words-to-spare rule a listed acronym takes -- and both readings are reported. After a comma the count is of the words before it, and two dotted single letters are the exception: they are how a person's initials are written, and two words before a comma may be one surname, so ``García Márquez, G.J.`` keeps first ``G.J.`` and last ``García Márquez`` and reports the fork, unless an unambiguous post-nominal in front of the initials that is not also a title, or another unlisted dotted word beside them, says otherwise (``John Smith, PhD X.Y.`` gives suffix ``PhD X.Y.``, while ``García Márquez, Ms G.J.`` keeps title ``Ms``, first ``G.J.``). Three letters or more read by the count, so ``John Smith, X.Y.Z.`` gives suffix ``X.Y.Z.`` -- and so does ``García Márquez, G.J.R.``, the accepted cost of the line, since initials are conventionally written apart (``García Márquez, G. J. R.``), as separate words this rule does not read (#563). Case is irrelevant here: the periods are the signal, so ``john smith x.y.z.`` reads the same way. Words the vocabulary does know are untouched (``M.A.``, ``Ph.D.``, ``A.B.C.``), a single trailing period is still not this shape (``John Smith Xyz.`` keeps last ``Xyz.``), and a dotted run at the FRONT of a name is untouched (``J.R.R. Tolkien``). One accident retires with it: a dotted word whose only vocabulary matches were SINGLE ASCII CHARACTERS -- the roman numerals the suffix list holds, and the lone digit ``2`` -- was reading as a generational suffix, so ``Jack X.Y.I.`` gives last ``X.Y.I.`` again, as 1.4.0 read it, while ``Msc.Ed.``, ``JD.CPA`` and ``Lt.Gov.`` are unchanged. The digit is why a dotted VERSION STRING moves with them and moves SILENTLY: ``John Smith 1.4.2`` gives last ``1.4.2`` where 2.3 gave suffix ``1.4.2``, and ``John Smith, 1.4.2`` gives first ``1.4.2``, last ``John Smith``. Such a token reports nothing at any policy -- it is no acronym either, the shape reading wanting every chunk alphabetic -- and a version string read as a credential was the same accident this retirement removes. That retirement is NOT behind this switch and stands either way -- setting it to ``False`` reads an unlisted dotted word as name material by position instead (``John Smith X.Y.Z.`` keeps last ``X.Y.Z.``), the pre-2.4 reading for THAT half alone. See the ``S2`` and ``suffix-acronym-collisions`` entries of ``docs/design/decisions.md`` (closes #516)
2828

@@ -44,7 +44,7 @@ Release Log
4444

4545
- **Fix a comma part read as credentials being taken apart again by a later join.** ``HumanName("John Smith, Ph. D. and Mary Jones")`` gives first ``John``, last ``Smith``, suffix ``Ph. D. and Mary Jones``, where 2.3.0 gave first ``Ph. D. and Mary``, middle ``Jones``, last ``John Smith``, and ``parse()`` reports each name word the part took: the parser now decides once, after every word is recognized, whether the part after a comma holds the credentials, and nothing joins across that decision afterwards. Titles joined by ``and`` stay one title (``John Smith, Mr. and Mrs.`` keeps title ``Mr. and Mrs.``). A surname joined by ``y`` counts as its words, as #575 already counted it in front of a credential: ``Ortega y Gasset, Dr.`` gives title ``Dr.``, first ``Ortega``, middle ``y``, last ``Gasset``, where 2.3.0 gave last ``Ortega y Gasset``. And a surname with a suffix in it before the comma is the surname, as ``Smith Jr., John`` always read it: ``Smith Jr., Esq.`` gives last ``Smith``, suffix ``Jr., Esq.``, where 2.3.0 gave first ``Smith``, and ``Smith Jr., V`` gives first ``V``, last ``Smith``, suffix ``Jr.``, where 2.3.0 gave first ``Smith``, suffix ``Jr., V``. See the #613 entry under ``C1`` in ``docs/design/decisions.md`` (closes #613)
4646

47-
- **Change a title word in a part after a second comma to read as a title.** ``HumanName("Eric H. Holder, Jr., Attorney General")`` gives title ``Attorney General``, suffix ``Jr.``, where 1.4.0 through 2.3.0 gave suffix ``Jr., Attorney General``, and the part no longer reports ``comma-structure``. A word that is also a suffix stays a suffix (``John Smith, MD, Ms``). A title joined by a connective is read as a title, but its part keeps the report (``Secretary of State``). Since the part's words can land in two fields, the report no longer names one: ``parse("John Smith, Jr., Dr. Bart")`` reports its last part as "beyond the recognized comma structures; read best-effort", where 2.3.0 said "consumed as suffix best-effort". A title word behind a surname particle run there reads as a title too: ``HumanName("John Smith, Jr., van der Berg Prof.")`` gives title ``Prof.``, suffix ``Jr., van der Berg``, where 1.4.0 through 2.3.0 gave suffix ``Jr., van der Berg Prof.``. (#603, closes #629, #636)
47+
- **Change a title word in a part after a second comma to read as a title.** ``HumanName("Eric H. Holder, Jr., Attorney General")`` gives title ``Attorney General``, suffix ``Jr.``, where 1.4.0 through 2.3.0 gave suffix ``Jr., Attorney General``, and the part no longer reports ``comma-structure``. A word that is also a suffix stays a suffix (``John Smith, MD, Ms``). A title joined by a connective is read as a title, but its part keeps the report (``Secretary of State``). Since the part's words can land in two fields, the report no longer names one: ``parse("John Smith, Jr., Dr. Bart")`` reports its last part as "beyond the recognized comma structures; read best-effort", where 2.3.0 said "consumed as suffix best-effort". A title word behind a surname particle run there reads as a title too: ``HumanName("John Smith, Jr., van der Berg Prof.")`` gives title ``Prof.``, suffix ``Jr., van der Berg``, where 1.4.0 through 2.3.0 gave suffix ``Jr., van der Berg Prof.``. A bound given name there no longer takes a title word into it: ``HumanName("John Smith, Jr., abdul Dr. Smith")`` gives title ``Dr.``, suffix ``Jr., abdul Smith``. (#603, closes #629, #636, #640)
4848

4949
- **Add the Catalan and Polish surname link.** ``parse("Josep Carod i Rovira")`` gives family ``Carod i Rovira``, where every release from 1.4.0 through 2.3.0 gave middle ``Carod i`` with family ``Rovira``; ``Josep Lluis Carod i Rovira`` gives middle ``Lluis`` with that same family; and ``Carod i Rovira, Josep`` gives it too, where they read family ``Carod Rovira`` and took the link into ``suffix`` as a generation marker. ``i`` is connective vocabulary now, the way ``y`` already was, and a connective counts as a name word wherever the three-word carve-out counts them -- whatever else the vocabulary says the word is, which matters here because ``i`` is also the roman numeral. A connective that is also generational vocabulary joins only where a name word stands on each side of it, so ``John Quincy Smith i`` keeps suffix ``i``, ``Josep Lluis Carod i III`` keeps suffix ``i III``, and the two-word ``Carod i`` keeps its generation reading. Written wholly in one case the letter reads as an initial and says so: ``JOSEP CAROD I ROVIRA`` and ``josep carod i rovira`` keep the fields they had and gain a ``conjunction-or-initial`` report, which a one-case name gains wherever a bare ``i`` or ``I`` stands among the name's own words -- a letter inside a maiden clause is read by the clause's rules and stays silent, as ``e`` already was -- and in an all-lower name that reading can move a field, each such name now reading as its all-caps twin already did (``parse("john smith i jr")`` gives middle ``smith``, family ``i`` and suffix ``jr`` where it gave family ``smith`` and suffix ``i jr``). Case repair follows the reading: a lower-case ``i`` the parse read as the generation is still title-cased by ``capitalize(force=True)`` (``Carod i`` gives ``Carod I``, as every release did), while one standing among the name words keeps its lower case as ``y`` always has (``Carod i Rovira`` gives ``Carod i Rovira``, where ``Carod I Rovira`` was the pre-2.4 answer). A link inside a maiden clause stays in the birth name, which no release read that way: ``HumanName("Jane Doe nee Puig i Soler")`` gives maiden ``Puig i Soler`` with last ``Doe``, where 2.0 through 2.3 ended the birth name at the link and gave maiden ``Puig`` with middle ``Doe i``, last ``Soler`` -- and the same words would have joined into last ``Doe i Soler`` under the change above, carrying a word of the birth name into the current surname. ``Jane Doe née Kowalska i Nowak`` moves with it, as does the all-lower ``jane doe nee puig i soler``; the ``y`` spelling always read this way and is untouched. The link still has to be joining: ``Jane Doe nee Puig i`` keeps maiden ``Puig`` with suffix ``i``, and ``Jane Doe nee Puig i III`` suffix ``i III``. A caller with Catalan or Polish data removes the entry from ``conjunctions_ambiguous`` and gets the join in the one-case names too; a caller who wants none of this removes ``i`` from ``conjunctions``, which restores every prior FIELD and every prior report, with two readings it does not restore and cannot: a letter the two vocabularies disagree about being an initial reads as one here and as the generation there, and case repair leaves a connective the parse placed among the NAME words in lower case where the off switch title-cases it -- ``parse("Dr. John i Smith").capitalized(force=True)`` keeps ``i`` where the off switch gives ``Dr. John I Smith``, and ``Carod i Rovira`` and ``Josep i Rovira`` are the same shape. Those two are the whole of what the switch does not undo, and ``tests/v2/test_properties.py`` states them as its invariants' only exemptions. A delimiter the caller declares through ``Policy(extra_suffix_delimiters=...)`` parts a trailing suffix part as a comma does (see the suffix-delimiter entry below), so no link joins across one: under ``(" - ",)``, ``Smith, John, PhD - i Soler`` keeps suffix ``PhD, i Soler``, as 2.3.0 read it. The default policy declares no such delimiter. See the ``P3`` and ``M2`` entries of ``docs/design/decisions.md`` (closes #397, closes #538)
5050

0 commit comments

Comments
 (0)