Locale YAML how-to
Each file under src/Humanizer/Locales owns one locale. YAML holds words,
phrases, lexical tables, formatting overrides, and structural engine choices.
Reusable algorithms stay in runtime C#; the source generator compiles YAML
into typed registrations, so runtime code never parses YAML or JSON.
Valid top-level keys are locale, optional variantOf, and surfaces.
Canonical surfaces are list, formatter, phrases, inflection, number,
ordinal, clock, compass, and calendar.
Define locale-owned behavior
locale: 'en-US'
variantOf: 'en'
surfaces:
number:
words:
engine: 'conjunctional-scale'
minusWord: 'minus'
andWord: 'and'
parse:
engine: 'token-map'
normalizationProfile: 'LowercaseRemovePeriods'
cardinalMap:
one: 1
two: 2
Author dense lexical tables as sequences when every slot matters. Use numeric keys for sparse tables:
tensMap:
2: 'twenty'
3: 'thirty'
Inheritance merges mappings and replaces sequences. A child scalar replaces
the parent scalar. Changing engine replaces that mapped block.
Use calendar.months, calendar.monthsGenitive, or calendar.hijriMonths
only when platform globalization data is incorrect or differs across targets.
Use number.formatting for proven decimal-separator, negative-sign, or
group-separator drift. These overrides do not mutate CultureInfo and do not
override a caller-supplied custom provider.
Follow the complete platform globalization override recipe to capture the cross-target probe, author the narrowest override, and test every affected API.
Preserve inheritance and surface boundaries
Omission is the inheritance signal; do not use empty mappings. Do not add a
block merely to say “default.” The narrow exception is
engine: 'default' on the documented ordinal and clock surfaces.
Keep phrases (the output tables) separate from formatter (selection and
grammar metadata). Keep render-side number.words aligned with parse-side
number.parse.
If no existing engine fits, use the
engine-choice workflow before
adding schema or runtime code. The exhaustive
YAML reference lists the fields and engines
accepted on main.