diff --git a/CHANGELOG.md b/CHANGELOG.md index 9decd2d..581b6df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/README.md b/README.md index 74c4b17..fc4d590 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/Mapper/LastnameMapper.php b/src/Mapper/LastnameMapper.php index 16819de..e48cae4 100644 --- a/src/Mapper/LastnameMapper.php +++ b/src/Mapper/LastnameMapper.php @@ -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 */ @@ -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; diff --git a/tests/SurnamePrefixTest.php b/tests/SurnamePrefixTest.php index 8733043..1eba07a 100644 --- a/tests/SurnamePrefixTest.php +++ b/tests/SurnamePrefixTest.php @@ -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 */