Translation & Localization

ICU Plural Messages (per-language CLDR categories)

Writes and fixes ICU MessageFormat strings for several locales at once, with exactly the plural categories each language uses (one, few, many, other and the rest), the mandatory other arm, exact-number arms such as =0, selectordinal, select, offset, nested messages and correct apostrophe quoting. Answers with a bare JSON map of locale code to message. Use when asked to write or translate a plural message, an ICU string, a count label such as "3 files", an ordinal such as "1st, 2nd, 3rd", a gender or enum select, or to fix a message that shows the wrong word form or fails to parse in react-intl, FormatJS, Angular, Flutter intl or Java MessageFormat.

ICU Plural Messages (per-language CLDR categories) is a tested SKILL.md that writes and fixes ICU MessageFormat strings for several locales at once, with exactly the plural categories each language uses (one, few, many, other and the rest), the mandatory other arm, exact-number arms such as =0, selectordinal, select, offset, nested messages and correct apostrophe quoting; an agent buys it once for $0.02 over x402.

Tested 2026-10-08No code, no hidden instructionsv1.0.0 · 9.5 KB · perpetual license

Not for

Gettext .po files, i18next key suffixes, Rails YAML plurals, or translating whole screens. It writes messages from the CLDR language rules but does not run your library, so a library with an older CLDR may differ for a few languages. Give it the text and the number variable; it returns the message.

Tested, honestly

Tested 2026-10-08 with a strong and a weak model.

With and without the skill

Results with and without the skill, for Sonnet and Haiku
SonnetHaiku
withwithoutwithwithout
Messages with the right arms (23 cases)23/2323/2323/2320/23

The same request on both sides, JSON-only asked for in both; a fence around the answer is removed first. Read by hand, Sonnet without the skill was right everywhere on content (its only miss was a code fence around one answer, which the rescoring strips). Haiku without the skill wrote no many arm for Czech, for French, Spanish and Italian, and for Brazilian Portuguese, so the number one million would show the wrong wording. Everything else Haiku wrote alone passed, including the apostrophe, the literal brace and the other-only languages.

Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.

SonnetStrong model, claude-sonnet-5-5
Wrote usable ICU messages for all 23 cases, read by hand: Japanese, Korean and Chinese got no one arm, English got =0 rather than a zero arm, the apostrophe before a placeholder was doubled and a literal brace was quoted, an offset:1 message counted the viewer out, and the fix cases added the missing Russian forms and the missing other arm.
HaikuWeak model, claude-haiku-5-5
Also 23 of 23 with the skill: the same arms per language as Sonnet, including many for French, Spanish, Italian, Czech and Brazilian Portuguese, which it left out without the skill.

Full test summary

Example

Our own test text, before and after the skill ran. Excerpts only.

English · claude-sonnet-5-5

Before

{count} files

After

{"en":"{count, plural, one {# file} other {# files}}","ja":"{count, plural, other {#個のファイル}}","ar":"{count, plural, zero {لا ملفات} one {ملف واحد} two {ملفان} few {# ملفات} many {# ملفًا} other {# ملف}}"}

What is in the file

  • Hard rules
  • Writing a good arm
  • Work in this order
  • Short examples

Languages

English. Tried in: English.

License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.

Versions

Current version 1.0.0, updated 2026-10-08. Whoever bought an earlier version gets new ones free through the same re-download token.

  1. v1.0.0 · 2026-10-08

    First release: writes and fixes ICU MessageFormat strings for several locales, with the CLDR plural categories of each language, `=0` versus `zero`, offset, selectordinal, select, nested messages and apostrophe quoting; answers with a bare JSON map locale to message.

    Facts re-checked on 2026-10-08: the category table against the Unicode CLDR plural chart (fetched) and against Intl.PluralRules in Node 24 (ICU 78, CLDR 48) for 38 locales; apostrophe, required `other` and `offset` against the ICU user guide page on messages (fetched).

    Model runs 2026-10-08, 23 cases, fence stripped: Sonnet 23/23 with and 23/23 without; Haiku 23/23 with and 20/23 without. Sonnet's gain is 0 cases, Haiku's 3 (the many arm). Price set to $0.02 by the measured benefit rule (Sonnet gain at most 1).

FAQ

Which plural categories does each language need?

The skill carries a table checked against the Unicode CLDR chart for more than thirty languages: Japanese, Korean and Vietnamese only other; English and German one and other; French, Spanish and Italian one, many and other; Russian and Polish one, few, many and other; Czech with a many arm that only fractions reach; Hebrew one, two and other; Arabic all six. Latvian has a zero form, Slovenian and Irish dual forms. Unknown languages follow the CLDR definition, never a neighbour.

What is the difference between =0 and zero, and what about apostrophes?

The arm =0 matches the exact number in every language, while zero is a category only Arabic, Welsh and Latvian have, so an English zero arm never fires. An apostrophe quotes only when it sits directly before a brace: the skill doubles it before a placeholder (l''{name}) and quotes literal braces, the two cases that break a parse. A stray unquoted brace in running text, such as a keyboard hint, is the other classic crash, and the skill quotes it. Spelling the typographic apostrophe avoids the issue entirely.

Does it handle offset, selectordinal, nested select and repairs?

Yes: offset:1 for the you-and-others wording, English one, two, few, other ordinals (and other-only for German or Japanese), select with a full plural inside every arm, and repair of an existing message such as a Russian string with only one and other, or an English one that lacks the other arm. Placeholders, variable names and keywords stay in English; only the words inside the arms change, and gendered verbs get their own arm.

Does it help Claude Sonnet?

On our 23 cases Sonnet scored 23 of 23 both with the skill and without it, once its fence was stripped. The skill helped Haiku, which went from 20 to 23: alone it left out the many arm that Czech, French, Spanish, Italian and Brazilian Portuguese need (millions, fractions). Parse the JSON it returns in your own library, because the skill never runs it.

Share

Read this page as Markdown: /skills/icu-plural-messages.md.

  • Translate App Text (JSON, YAML, PO)

    Translation & Localization

    SKILL.md · v1.0.1 · 8.5 KB

    Translates app strings and locale files (JSON, YAML, gettext PO, ICU messages, HTML snippets) into another language without breaking them. Keys, placeholders such as {name}, {{count}}, %s, %(name)s and %{count}, ICU plural and select syntax, HTML tags and URLs come back byte for byte; only the human text is translated, and plural forms are added where the target language needs more of them. Use when asked to translate a JSON or YAML locale file, an en.json, a .po file, i18n strings or UI text, or to localize an app.

    $0.01once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 3 Oct 2026

  • PO Translate: Gettext Files That Still Compile

    Translation & Localization

    SKILL.md · v1.0.0 · 9.2 KB

    Translates the messages of a gettext PO file (.po) into another language and returns the whole file, so msgfmt and the app that loads it accept it. Only the msgstr values change. msgid, msgid_plural and msgctxt, every comment line, flags, the header (apart from its Plural-Forms line), obsolete entries and all placeholders such as %s, %d, %(name)s, {name} and %1$s come back exactly as they were. Entries with plural forms get exactly the number of msgstr lines the target language needs, for example three for Russian, Ukrainian, Polish and Czech, six for Arabic and one for Japanese. Use to translate or localize a .po file for WordPress, Django, Qt, GNU gettext or any app that ships gettext catalogs.

    $0.02once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026