# gizlang:locale

the linguistic data of the Unicode CLDR (48.2.3, pinned; the CLDR generator writes the tables at the end of this file) and the algorithms that read it, once for the server, the browser and workers. Nothing here is a foreign runtime: a locale is a value built from a record, and every function is a pure function of that value and its arguments. tags        BCP 47 (RFC 5646) canonical case, CLDR likely scripts and parent locales; RFC 4647 lookup with script awareness plurals     the CLDR cardinal and ordinal rules of every language, compiled to Gizlang conditions (operands n i v w f t c) numbers     decimal, percent, currency and compact patterns with the locale's symbols, grouping and digits dates       the Gregorian date, time and date-time styles, a set of skeletons, and patterns; an instant and an offset relative    "yesterday", "in 3 days", "5 minutes ago"; lists "a, b, and c"; the name of a language in itself Unicode data: https://www.unicode.org/license.txt (CLDR is under the Unicode License v3).

```gizlang
import * as Locale from "gizlang:locale";
```

## Types

### `NumberPattern`

```gizlang
type NumberPattern = { prefix: string; suffix: string; negPrefix: string; negSuffix: string; minInt: i64; minFraction: i64; maxFraction: i64; primary: i64; secondary: i64; }
```

A number pattern of CLDR (`#,##0.###`, `¤#,##0.00`, `#,##0%`), read once.

- `prefix`: `string`
- `suffix`: `string`
- `negPrefix`: `string`
- `negSuffix`: `string`
- `minInt`: `i64`
- `minFraction`: `i64`
- `maxFraction`: `i64`
- `primary`: `i64`
- `secondary`: `i64`

### `Locale`

```gizlang
type Locale
```

A locale with data: build one with `locale(tag)`. `tag` is the tag asked for, canonical (`pt-BR`); `data` the locale whose data it reads
(`pt`); `chain` the fallback chain of `tag` (`pt-BR`, `pt`), which a catalog of messages follows too.

- `tag`: `string`
- `data`: `string`
- `chain`: `Vec<string>`
- `language`: `string`
- `script`: `string`
- `region`: `string`
- `rtl`: `bool`

### `Collator`

```gizlang
type Collator = { lang: string; strength: i64; upperFirst: bool; shifted: bool; numeric: bool; backwards: bool; caseLevel: bool; libc: bool; tailor: Vec<i64>; }
```

A collator: sort keys of text for a language, as ICU or the C library order it.

- `lang`: `string`
- `strength`: `i64` — 1 primary, 2 secondary, 3 tertiary, 4 quaternary, 5 identical.
- `upperFirst`: `bool`
- `shifted`: `bool` — Whitespace and punctuation weigh only at the fourth level (alternate=shifted).
- `numeric`: `bool` — Runs of digits weigh as their numeric value.
- `backwards`: `bool` — Accents compare from the end of the text (French).
- `caseLevel`: `bool` — A case level follows the secondary level.
- `libc`: `bool` — The C library order: punctuation and symbols are shifted too and weigh by code point.
- `tailor`: `Vec<i64>` — Tailored letters, five values each: base, combining mark or 0, primary, second primary or 0, secondary.

## Functions

### `canonical`

```gizlang
function canonical(tag: string): string
```

TAG in the canonical case of BCP 47 (`ko`, `zh-Hant-TW`, `es-419`), `_` read as `-`, with the deprecated language codes CLDR replaces
(`iw` is `he`, `in` is `id`, `ji` is `yi`, `jw` is `jv`, `mo` is `ro`). Extensions (`-u-…`, `-x-…`) are dropped: no presentation decision reads them.

Effects: fail.

### `wellFormed`

```gizlang
function wellFormed(tag: string): bool
```

Whether TAG is a well-formed language tag of the form this module reads: a language of 2 or 3 letters (or 5 to 8), then an optional
script, region and variants. A request or a file names a locale only through a tag that passes.

Effects: fail.

### `likelyScript`

```gizlang
function likelyScript(tag: string): string
```

The likely script of TAG (`ko` is Kore, `zh-TW` is Hant, `sr-ME` is Latn), or "" when CLDR has none.

Effects: fail.

### `rightToLeft`

```gizlang
function rightToLeft(tag: string): bool
```

Whether TAG is written right to left: by its script, or by the likely script of its language and region.

Effects: fail.

### `parent`

```gizlang
function parent(tag: string): string
```

The parent of TAG in CLDR inheritance: parentLocales (`en-GB` is `en-001`, `es-MX` is `es-419`, `zh-Hant` is the root), else TAG
without its last subtag; "" at the root.

Effects: fail.

### `chain`

```gizlang
function chain(tag: string): Vec<string>
```

The fallback chain of TAG, most specific first: TAG canonical, with its likely script added when the region decides it (`zh-TW` is
`zh-Hant-TW`, `zh-Hant`), then its parents. `zh-TW` never falls back to `zh`, whose script is Hans.

Effects: fail.

### `acceptLanguage`

```gizlang
function acceptLanguage(header: string): Vec<string>
```

The tags of an Accept-Language header, best first (by q, then in order); `*` and q=0 are left out.

Effects: fail.

### `best`

```gizlang
function best(requested: Vec<string>, supported: Vec<string>): Option<string>
```

The supported tag that serves REQUESTED best (RFC 4647 lookup over CLDR chains), or none. For each requested tag in order: a supported
tag in its chain (`ko-KR` takes `ko`, `zh-TW` takes `zh-Hant`), else a supported tag of the same language and script (`pt` takes
`pt-BR`, `zh-CN` takes `zh` and never `zh-Hant`).

Effects: fail.

### `available`

```gizlang
function available(): Vec<string>
```

The locales that have data, as canonical tags.

Effects: fail.

### `dataTag`

```gizlang
function dataTag(tag: string): Option<string>
```

The data locale for TAG: the first tag of its chain that has data (`ko-KR` is `ko`, `zh-TW` is `zh-Hant-TW`), or none.

Effects: fail.

### `locale`

```gizlang
function locale(tag: string): Option<Locale>
```

The locale of TAG: its numbers, dates and names from the first tag of its chain that has data, else from English (a language CLDR
has no data for, such as Latin, still names its catalog and keeps its plural rules and direction). None for a malformed tag.

Effects: fail.

### `nameOf`

```gizlang
function nameOf(tag: string): string
```

The name of the language of TAG in itself, or TAG when no data has it.

Effects: fail.

### `plural`

```gizlang
function plural(tag: string, n: i64): string
```

The plural category ("zero", "one", "two", "few", "many" or "other") of the integer N in the language of TAG.

Effects: fail.

### `pluralShown`

```gizlang
function pluralShown(tag: string, shown: string, ordinal: bool): string
```

The category of a number as it is shown, in decimal digits with an optional compact exponent (`1.50`, `1.2c6` for 1.2M): the
operands of CLDR come from the visible digits, so `1` and `1.0` differ. ORDINAL picks the ordinal rules.

Effects: fail.

### `currencyDigits`

```gizlang
function currencyDigits(code: string): i64
```

The minor-unit digits of the currency CODE (KRW and JPY 0, most 2).

Effects: fail.

### `collationTag`

```gizlang
function collationTag(name: string): Option<string>
```

The ICU language tag of locale NAME, as uloc_toLanguageTag gives it: `@colStrength=primary` is `und-u-ks-level1`;
none for an unknown keyword.

Effects: fail.

### `collator`

```gizlang
function collator(tag: string): Option<Collator>
```

The collator of ICU locale TAG (`sv`, `und-u-kf-upper`, `de@collation=phonebook`, `@colStrength=primary`); none for a
keyword value ICU rejects.

Effects: fail.

### `libcCollator`

```gizlang
function libcCollator(name: string): Collator
```

The collator emulating the C library locale NAME (`en_US.utf8`).

Effects: fail.

### `lowerIn`

```gizlang
function lowerIn(lang: string, text: string): string
```

TEXT in lower case by the rules of language LANG (Turkic I is ı).

Effects: fail.

### `upperIn`

```gizlang
function upperIn(lang: string, text: string): string
```

TEXT in upper case by the rules of language LANG (Turkic i is İ).

Effects: fail.

### `cldrVersion`

```gizlang
function cldrVersion(): string
```

The CLDR version of the data.

## Methods

### `Locale.slot`

```gizlang
function Locale.slot(self: Locale, tags: Vec<string>): i64
```

The place of the locale in TAGS, the locales of a catalog of messages, from 1; 0 when the catalog has none of its chain (the source
text then shows). `pt-BR` takes a catalog `pt` when there is no `pt-BR`. The code that the ghtml compiler writes picks its variant by it.

Effects: fail.

### `Locale.dir`

```gizlang
function Locale.dir(self: Locale): string
```

The direction of the locale's script: "rtl" or "ltr", for the `dir` attribute.

### `Locale.name`

```gizlang
function Locale.name(self: Locale): string
```

The name of the locale's language in itself ("한국어", "English", "日本語"), for a language picker.

Effects: fail.

### `Locale.plural`

```gizlang
function Locale.plural(self: Locale, n: i64): string
```

The cardinal category of the integer N.

Effects: fail.

### `Locale.ordinal`

```gizlang
function Locale.ordinal(self: Locale, n: i64): string
```

The ordinal category of N ("one" for 1st, "two" for 2nd, "few" for 3rd in English).

Effects: fail.

### `Locale.pluralOf`

```gizlang
function Locale.pluralOf(self: Locale, x: f64, fraction: i64): string
```

The cardinal category of X as it is shown with FRACTION digits (`1.0` is "other" in English: the visible zeros count).

Effects: fail.

### `Locale.integer`

```gizlang
function Locale.integer(self: Locale, n: i64): string
```

The integer N in the locale (`1,234,567`, `1.234.567`, `١٬٢٣٤`).

Effects: fail.

### `Locale.number`

```gizlang
function Locale.number(self: Locale, x: f64, max: i64): string
```

X with at most MAX fraction digits (`1,234.5`), by the decimal pattern of the locale.

Effects: fail.

### `Locale.fixed`

```gizlang
function Locale.fixed(self: Locale, x: f64, digits: i64): string
```

X with exactly DIGITS fraction digits (`1,234.50`).

Effects: fail.

### `Locale.percent`

```gizlang
function Locale.percent(self: Locale, x: f64, max: i64): string
```

The ratio X as a percent (`0.256` is `26%`, `25,6 %` with one fraction digit in French).

Effects: fail.

### `Locale.currencySymbol`

```gizlang
function Locale.currencySymbol(self: Locale, code: string): string
```

The symbol of the currency CODE in the locale (`$`, `US$`, `₩`), or CODE.

Effects: fail.

### `Locale.money`

```gizlang
function Locale.money(self: Locale, minor: i64, code: string): string
```

The amount MINOR, in minor units of CODE (cents for USD, won for KRW), in the currency pattern of the locale: `$1,234.50`, `₩1,235`.
An amount is an integer of minor units: a float never decides money.

Effects: fail.

### `Locale.compact`

```gizlang
function Locale.compact(self: Locale, x: f64): string
```

X in the short compact form of the locale (`1.2K`, `12K`, `1.2만`, `12억`): the CLDR pattern of its power of ten, with two digits of
precision as browsers show it; below 1000, the number itself.

Effects: fail.

### `Locale.pattern`

```gizlang
function Locale.pattern(self: Locale, ms: i64, offset: i64, pattern: string): string
```

The instant MS (milliseconds since 1970, UTC) at OFFSET seconds east of UTC, in the CLDR date pattern PATTERN of the locale
(`y. M. d.`, `MMM d, y`, `HH:mm`). Quoted text stays; the zone letters show `GMT+9`.

Effects: fail.

### `Locale.date`

```gizlang
function Locale.date(self: Locale, ms: i64, offset: i64, style: string): string
```

The date of the instant MS at OFFSET seconds, in the STYLE of the locale: "full", "long", "medium" or "short".

Effects: fail.

### `Locale.time`

```gizlang
function Locale.time(self: Locale, ms: i64, offset: i64, style: string): string
```

The time of day of the instant MS at OFFSET seconds, in the STYLE of the locale.

Effects: fail.

### `Locale.dateTime`

```gizlang
function Locale.dateTime(self: Locale, ms: i64, offset: i64, date: string, time: string): string
```

The date and time of MS at OFFSET seconds: the date in DATE style and the time in TIME style, joined as the locale joins them.

Effects: fail.

### `Locale.skeleton`

```gizlang
function Locale.skeleton(self: Locale, ms: i64, offset: i64, skeleton: string): string
```

MS at OFFSET seconds by a CLDR skeleton of the locale: yMMMd, yMMM, MMMd, MMMEd, yMd, Md, Hm, hm, Hms, hms, Ed, yMMMEd, MMMMd or
yMMMMd. Another skeleton is the medium date.

Effects: fail.

### `Locale.relative`

```gizlang
function Locale.relative(self: Locale, value: i64, unit: string): string
```

VALUE units UNIT from now ("year", "quarter", "month", "week", "day", "hour", "minute" or "second"): a word where the locale has one
("yesterday", "내일"), else the pattern of the plural category ("in 3 days", "3일 전").

Effects: fail.

### `Locale.since`

```gizlang
function Locale.since(self: Locale, now: i64, then: i64): string
```

The instant THEN seen from NOW (both in milliseconds) in the largest whole unit: "just now" is 0 seconds, then minutes, hours, days,
weeks, months (30 days) and years (365 days).

Effects: fail.

### `Locale.list`

```gizlang
function Locale.list(self: Locale, items: Vec<string>, kind: string): string
```

ITEMS joined as the locale lists them: KIND "and" (`a, b, and c`), "or" or "unit" (`3 h, 5 min`).

Effects: fail.

### `Collator.tailored`

```gizlang
function Collator.tailored(self: Collator, rules: string): Option<Collator>
```

A copy tailored by ICU RULES such as `&a < g < h`; none for rules it cannot read.

Effects: fail.

### `Collator.key`

```gizlang
function Collator.key(self: Collator, text: string): bytes
```

The sort key of TEXT: keys compare as bytes in the collation order.

Effects: fail.

### `Collator.compare`

```gizlang
function Collator.compare(self: Collator, a: string, b: string): i64
```

Compares A and B in the collation order: -1, 0 or 1.

Effects: fail.

