Skip to content

nplurals=1 languages (ko/ja/id) lose count info on singular-vs-plural placeholder mismatch #15

Description

@claude

What happened

Translating ko (nplurals=1: "Plural-Forms: nplurals=1; plural=0;\n"), several plural entries where the English singular msgid has no placeholder but the plural msgid does (e.g. "There is one person ahead of you in the waiting list." / "There are %(count)d people ahead of you in the waiting list.") caused ./i18n fix to clear my translation.

_fix_format_errors's mismatch() check compares msgstr[0] only against msgid[0] (the singular form). For languages with nplurals=1 (ko, ja, id in this repo), msgstr[0] is the only string ever shown to users — at runtime it's used for count=1 and count=5 alike — so a translator naturally wants to reference %(count)d in it. But doing so trips the mismatch check because the singular English msgid doesn't have that placeholder.

The established convention in already-translated nplurals=2+ languages (checked de/fr/tr) is to hardcode "1"/"one" in msgstr[0] and only add the count placeholder in msgstr[1]. For nplurals=1 languages there is no msgstr[1], so following that same convention means the count is silently dropped from the UI for all values >1 (e.g. Korean would always render "한 사람이 있습니다" — "there is a person" — regardless of whether it's 1 or 50 people ahead in the waiting list).

Command that failed

./i18n fix ko
# cleared: 'There is one person ahead of you in the waiting list.'
# cleared: 'You have one more hour to borrow it.'
# ...and 7 more similarly-shaped entries

Impact

Not a hard blocker — I reworded these 9 entries to drop the count and match the singular's placeholder-free shape, validate/test now pass. But this is a real information loss for nplurals=1 languages (ko, ja, id) specifically on this class of string, and will recur for every future nplurals=1 batch that touches a "one X / %(count)d Xs" pair.

Suggested fix

Worth a design discussion rather than a quick patch:

  • Either accept the tradeoff (document it in the instructions so future runs don't re-litigate it), or
  • Special-case nplurals=1 catalogs in mismatch() to allow msgstr[0] to reference the plural msgid's placeholders too (union of singular+plural named vars), since that string is the only one ever rendered.

Flagging as a systemic pattern affecting ja and id as well, not just ko.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions