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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Empty nickname closer strings are dropped with empty openers, so invalid delimiter config degrades to a no-op instead of an unclosable span.
- Uniform-uppercase detection on comma input splits on commas as well as whitespace, so comma-dense rows do not force a full-string Unicode letters scan.
- Comma-separated non-empty segments count toward the parser's 65,536-token ceiling.
- Credential-only comma tails no longer reinterpret given names such as `Della` and `Van` as surname particles.
- Credential-only comma tails no longer reinterpret a given name that Western parsing preserves: `Della Smith, MD` and `Van Smith, MD` retain `Della` and `Van` as given names. A following surname particle can still cause first-name loss, as in `Della van Berg, MD`; see the README ambiguity notes.
- A quoted nickname whose closing quote immediately precedes a structural comma stays intact.
- Connector-heavy salutation input is validated in linear time, and title-only connector chains no longer create a phantom joint partner.
- Joint honorifics retain a terminal title-colliding shared surname (`Mr. and Mrs. Lord`) while still rejecting multi-word and connector-led title-only chains.
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,15 @@ that case. Use an explicit given-name segment, for example
`Hidalgo Castillo, Maria, MD`, or post-process feeds where the left side is a
surname-only field.

In default Western-order parsing, a given name that is also a surname particle
can be absorbed into a following particle surname. If `Della` is the given name, `Della van Berg` is parsed
incorrectly: `getFirstname()` is empty and `getLastname()` is `della van Berg`.
`Della Smith` does keep `Della` as the given name; the additional particle is
what triggers the surname-chain heuristic. A nickname or credential does not
fix this (`Della (Bob) van Berg` and `Della van Berg, MD` have the same missing
first name). When you know the boundary, use `van Berg, Della` or
`van Berg, Della, MD` to preserve the intended given name and surname.

An anglicised Irish surname with the fada dropped is undecidable the same way.
`Eamon O Cuiv` and `John F Kennedy` have identical structure and casing, so a
bare `O` between spaces stays a middle initial. The fada form `Ó` resolves as a particle, and the joined
Expand Down
5 changes: 3 additions & 2 deletions src/Mapper/LastnameMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ protected function isFollowedByLastnamePart(array $parts, int $index): bool

/**
* Prefer a firstname over a lone prefix unless surname-only context or an
* adjacent prefix (ignoring nicknames) resolves the ambiguity.
* adjacent prefix (ignoring nicknames) selects the surname interpretation.
* This heuristic can absorb a given name such as Della in Della van Berg.
*
* @param PartArray $parts
*/
Expand All @@ -250,7 +251,7 @@ protected function isApplicablePrefix(array $parts, int $index): bool
return false;
}

// Nicknames do not interrupt the adjacent particles establishing a surname.
// Nicknames do not interrupt the adjacent-particle surname heuristic.
$next = $this->skipNicknameParts($parts, $index + 1);
if (($parts[$next] ?? null) instanceof LastnamePrefix) {
return true;
Expand Down
2 changes: 1 addition & 1 deletion tests/SurnamePrefixTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function testMiddleNameParticleIsLowercased(string $input, string $middle
}

/**
* Adjacent particles resolve surname ambiguity without a firstname.
* Adjacent particles select the surname interpretation without a firstname.
*
* @return array<string, array{string, string, string}>
*/
Expand Down
Loading