Documentation
File formats
Eight formats, and how plurals are handled in each.
| Format | Extension | Used by |
|---|---|---|
| JSON | .json | Web, React, Vue, Node.js, i18next |
| ARB | .arb | Flutter, Dart |
| Android XML | .xml | Android |
| Apple Strings | .strings | iOS, macOS |
| Strings Dictionary | .stringsdict | iOS, macOS — plurals |
| String Catalog | .xcstrings | iOS 16+, macOS 13+ |
| Gettext PO | .po | WordPress, Django, PHP |
| YAML | .yaml / .yml | Ruby on Rails, i18next |
Plurals
Plural forms are not translated as ordinary strings. ParlanceKit extracts them, asks the model for every plural category the target language requires, and writes them back in the shape the format expects.
This matters because languages disagree about how many forms exist. English has two. Russian has four categories in CLDR: one, few, many, and other. Arabic has six. A source file with a singular and a plural will produce all four Russian forms, correctly inflected — not two.
Plural categories are generated for the target language, never assumed from the source. This holds regardless of what language your source file is written in.
Format-specific behaviour
String Catalogs (.xcstrings)
A catalog contains every language in a single file. ParlanceKit updates it in place, adding each target language's localizations alongside your source. Plurals nested inside substitutions or device variations are handled too.
Gettext (.po)
PO files use positional plural slots — msgstr[0], msgstr[1] — and the number of slots comes from the language's gettext rule, which is not always the same as its CLDR category count. ParlanceKit writes the correct number of slots and the correct Plural-Forms header.
ARB (.arb)
ICU plural syntax is parsed, expanded to the target's categories, and rebuilt. Surrounding prose, offsets, and exact matches such as =0 are preserved.
Placeholders
Every common placeholder syntax is protected before the text reaches the model and restored afterwards: {name}, {{count}}, %d, %@, %lld, %1$s, %{name}, %(name)s, %<n>d, and Apple's %#@variable@. A literal %% is preserved as a literal percent.
If a translation comes back with a placeholder missing or altered, ParlanceKit retries that string once. If it is still wrong, the string is left untranslated rather than written broken.