Skip to content

Should an "all particle" middle name exist? (Mesnil Garcia van reports middle van and then declines to initial it) #402

Description

@derek73

A middle name whose every word is a particle is either a defect or a miscount, and today it is both, depending on which half of the particle vocabulary produced it.

Policy(name_order=FAMILY_FIRST)
  "Mesnil Garcia de"     given='Garcia'  middle='de'    family='Mesnil'   initials='G. M.'
  "Mesnil Garcia van"    given='Garcia'  middle='van'   family='Mesnil'   initials='G. M.'
  "Mesnil Garcia Juan"   given='Garcia'  middle='Juan'  family='Mesnil'   initials='G. J. M.'

The never-given case is an error. de can never be a name, so standing alone as a middle name is exactly what the vocabulary exists to prevent. That is #365, and it is the only shape in the default order that produced one — until #379 attached the comma form, "Vega, Juan de la" was the other.

The ambiguous case is a miscount. van is in the middle field, no PARTICLE_OR_GIVEN fork is reported for it, and rule O4 gave it that role on purpose — so the parser is counting it as a middle name in every way except the one that would show. Then initials() skips it. Either it is a name word there and should give G. V. M., or it is not and should not be in middle.

The rule this wants

R3 skips particle-tagged words outside given, which is right for family — "Juan de la Vega" gives J. V., and the particles genuinely are not initialable there because the part has a base word to carry the initial. The qualifier it is missing: skip a particle when the part has other words. A part that is entirely particles is being reported as a name, so it initials.

That change makes the defensive branch behind it unnecessary rather than merely untested.

Why this is filed rather than fixed in passing

The guard for this shape lived in tests/test_initials.py, built on "Vega, Juan de la" — an input whose all-particle middle #379 has just removed. Rather than manufacture a replacement (the previous instinct, and the reason this is worth a rule instead of an example), the invariant belongs in the rules system:

No parse produces a middle name whose every word is a particle.

That is a property over all parses, not an example, so it wants a property test rather than a row — and it cannot be turned on until #365 settles the never-given half. The ambiguous half is the R3 qualifier above, which is independent and could land first.

Sequencing

Activity

  1. self-assigned this
    on Aug 19, 2026
  2. derek73 commented on Aug 19, 2026

    @derek73
    OwnerAuthor

    Correction to the framing above, after checking whether a rule already exists. It does — rules.md#R3 — and it answers the question the opposite way to what I proposed:

    Rationale: initials abbreviate the person's name words; titles, suffixes, particles and nicknames are not name words.
    Initials take the first letter of each given, middle, and base family word; titles, suffixes, particles and nicknames contribute nothing.

    So the suggestion above — "skip a particle only when the part has other words" — contradicts R3 as written. R3 is unconditional, and its Accepted: note embraces the consequence for an all-particle family: "Juan van der" → initials="J.", because "initials of a bare particle run would be nonsense".

    What is actually inconsistent is narrower, and it is not in the initials of a middle. The implementation carries a carve-out R3 does not state, at nameparser/_render.py:113:

    if role is not Role.GIVEN:
        tokens = tuple(t for t in tokens if not (_SKIP_TAGS & t.tags))

    The skip applies to every role except given, so:

    van Gogh             given='van'      ->  initials='v. G.'   particle DOES initial
    Mesnil Garcia van    middle='van'     ->  initials='G. M.'   particle does not
    Juan van der         family='van der' ->  initials='J.'      particle does not
    

    None of R3's four examples covers a particle in the given role, so nothing catches it. It also renders v. lowercase, initials taking the token's first character verbatim.

    Which leaves three separable questions, replacing the two above:

    1. Should R3's carve-out for given be stated, or removed? It has a defensible reason — where an ambiguous particle is read as the given name the fork is reported and the word IS being counted as a name, so initialing it is consistent. But that reasoning applies equally to a particle read as a middle name, where the code does the opposite. Whichever way it goes, R3 should say so and carry an example.

    2. Should an all-particle middle exist at all? Under R3 as written, a particle is never a name word, so a middle name consisting only of particles is an error in both halves — not a miscount in the ambiguous half as I said above. For never-given particles that is Mesnil Garcia de strands the particle under FAMILY_FIRST but folds it under FAMILY_FIRST_GIVEN_LAST #365. For ambiguous ones it follows from R3 rather than from a new judgement.

    3. The defensive branch that skips a part contributing no initials stays until (2) is settled, and is untested in the meantime — the input it was built on, "Vega, Juan de la", lost its all-particle middle in Beethoven, Ludwig van puts the tussenvoegsel in middle instead of the family name #379.

    The original observation stands and is what makes this worth a rule rather than an example: when everything is working there should be no all-particle middle name, unless we mean it as a middle name — in which case R3 has to say why it initials there and not elsewhere.

  3. derek73 commented on Aug 19, 2026

    @derek73
    OwnerAuthor

    Cross-reference: #404 proposes a principle — a particle that has no name word to attach to is not doing particle work, so it is positioned and rendered as ordinary text — that would resolve this issue as a consequence rather than as its own judgement. Worth deciding there before fixing this one field at a time.

  4. added this to the v2.2 milestone on Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions