CLDR's personNames keeps two fields where this library has one suffix:
| CLDR field |
examples |
generation |
Jr., Sr., III |
credentials |
PhD, MD, Esq. |
And it does not just store them apart — it formats them differently. Every en pattern reads {given} {given2} {surname} {generation}, {credentials}: generation space-joined to the name, credentials comma-preceded. ko uses credentials in 4 patterns and ja uses generation in 1, so this is not a Western-only carve-up.
Right now parse("Smith, Jr., PhD").suffix is 'Jr., PhD' — one string, two different kinds of thing, and a caller who wants only the generational part has to re-parse it against vocabulary they would have to reconstruct.
The vocabulary is already split
This is the part that makes it worth investigating rather than filing as a someday:
suffix_words ( 40): jr, sr, jnr, snr, junior, ii, iii, iv, v, ...
suffix_acronyms (613): aas, aba, abpp, acp, ...
suffix_acronyms is credentials, entirely. suffix_words is generational plus a handful that are neither — esq, esquire, ret, vet, dr, 2. So the data is largely partitioned already; the merge happens at the output field, not in the vocabulary.
The open question is where the exceptions go. CLDR has only two buckets, so Esq., Ret. and Vet. need a home — credentials as a catch-all, or a third bucket the CLDR model does not have.
It could be additive
ParsedName already has derived views that are not Roles — family_base, family_particles, surnames, given_names. generation and credentials could ship the same way: computed over the existing suffix tokens, exposed as render keys and attributes, with suffix unchanged.
That would mean no migration and nothing breaking — a caller matching on suffix keeps working, and a caller who wants the split gets it. Worth confirming that framing survives contact with _render's spec handling and the {suffix} key before committing to it.
Why it keeps coming up
Three open issues turn on this distinction:
None of them needs this to be fixed. But all three are reasoning about a distinction the model does not currently express, which is worth noticing.
What an investigation would settle
- Where
esq/esquire/ret/vet/dr belong, and whether two buckets are enough
- Derived views versus new
Role members — the former is additive, the latter is a 3.0-shaped change
- Whether
initials() and capitalized() need to know
- Whether the vocabulary sets become the source of truth for the split, or a new mapping is needed (the sets overlap by one entry today, and
suffix_words is not purely generational)
- What
HumanName does — it has no such fields, so the v1 facade would expose nothing new
Source: CLDR personNames, common/main/*.xml. It supplies the field slots and the formatting, not the vocabulary — deciding which shipped entries are which is our problem either way.
CLDR's
personNameskeeps two fields where this library has onesuffix:generationcredentialsAnd it does not just store them apart — it formats them differently. Every
enpattern reads{given} {given2} {surname} {generation}, {credentials}: generation space-joined to the name, credentials comma-preceded.kousescredentialsin 4 patterns andjausesgenerationin 1, so this is not a Western-only carve-up.Right now
parse("Smith, Jr., PhD").suffixis'Jr., PhD'— one string, two different kinds of thing, and a caller who wants only the generational part has to re-parse it against vocabulary they would have to reconstruct.The vocabulary is already split
This is the part that makes it worth investigating rather than filing as a someday:
suffix_acronymsis credentials, entirely.suffix_wordsis generational plus a handful that are neither —esq,esquire,ret,vet,dr,2. So the data is largely partitioned already; the merge happens at the output field, not in the vocabulary.The open question is where the exceptions go. CLDR has only two buckets, so
Esq.,Ret.andVet.need a home — credentials as a catch-all, or a third bucket the CLDR model does not have.It could be additive
ParsedNamealready has derived views that are notRoles —family_base,family_particles,surnames,given_names.generationandcredentialscould ship the same way: computed over the existing suffix tokens, exposed as render keys and attributes, withsuffixunchanged.That would mean no migration and nothing breaking — a caller matching on
suffixkeeps working, and a caller who wants the split gets it. Worth confirming that framing survives contact with_render's spec handling and the{suffix}key before committing to it.Why it keeps coming up
Three open issues turn on this distinction:
Smith, Jr.→ title rather than suffix). CLDR saysJris generation and belongs space-joined, so a comma before it is genuinely unusual — which is why that input is ambiguous rather than simply wrong.Smith, LEED AP). CLDR's own sample iscredentials='MD DDS'— multi-word, space-separated — which is exactly the shape Recognize multi-word credential suffixes after a comma ("Smith, LEED AP") #291 wants recognized.Smith, Ph. D. Jr.puts the credential infirst(regression from 1.4.0) #325 (Smith, Ph. D. Jr.puts the credential infirst). The bug is a credential and a generational suffix in one run being handled as undifferentiated suffix text.None of them needs this to be fixed. But all three are reasoning about a distinction the model does not currently express, which is worth noticing.
What an investigation would settle
esq/esquire/ret/vet/drbelong, and whether two buckets are enoughRolemembers — the former is additive, the latter is a 3.0-shaped changeinitials()andcapitalized()need to knowsuffix_wordsis not purely generational)HumanNamedoes — it has no such fields, so the v1 facade would expose nothing newSource: CLDR
personNames,common/main/*.xml. It supplies the field slots and the formatting, not the vocabulary — deciding which shipped entries are which is our problem either way.