Skip to main content

Crate cletter

Crate cletter 

Source
Expand description

Locale-correct business correspondence, composed from focused units.

cletter is the front door: it re-exports cnice (salutations and valedictions via cnice::greet and cnice::farewell), cink (signature images) and cdate (date formats), and adds what only makes sense together — locale resolution, openings, subjects, orthography, and advisories.

The locale tables live as data in tables/*.json (see tables/README.md); tests/vectors/*.json is the executable contract every language port runs. The Typst module in typst/ derives from the same tables.

One locale per document (BCP 47). Unknown locales fall back through the base language to English. Explicit overrides always win — tables supply defaults, never commands. Same input always yields the same output: no models, no I/O.

Structs§

DecodedImage
Recognized image bytes plus intrinsic dimensions when the format carries them (SVG passes through dimension-less). Pixels are not decoded or validated.

Enums§

ImageMime
Image formats normalize accepts.

Functions§

apply_ortho
Apply the locale’s literal spelling substitutions to caller-selected prose. Swiss and Liechtenstein German replace ß with ss and ẞ with SS. This explicit helper cannot recognize protected names, quotations, URLs or source material; exclude them before calling, or use orthography_issues without mutation. Opening, subject, closing and user overrides are never transformed implicitly.
available_locales
BCP 47 locale codes with a valediction entry, sorted.
closing
Valediction for a BCP 47 locale. Unknown locales fall back through the base language to English; an explicit override always wins (used for per-workspace closing choices).
country_from_location
Extract an uppercase ISO country code from a free-text location: country keywords first, then Swiss cantons (City, Canton shape). When multiple countries match, keyword declaration order in the canonical table determines priority, consistently across language ports. Matching lowercases Unicode-aware (locations are free text, unlike the ASCII-only table tokens), mirroring the reference implementation.
default_max_pixels
Default oversize threshold in pixels, from tables/defaults.json.
exceeds_limits
Whether the raster exceeds a pixel budget. Dimension-less formats (SVG) scale without loss and never exceed.
honorific_warning
Non-blocking advisory when the recipient name carries no parsable honorific for the locale: the letter falls back to the formal salutation, so a human should supply the full address form. Returns None for empty names (already covered by recipient_salutation_warning) and for complete names.
image_snippet
Typst #image call for a sized signature. Width is emitted only when a max-width clamp applied (see signature_size); layout and placement stay with the caller, whose line budgets they affect.
is_valid_date
Whether a proleptic Gregorian calendar date exists. Correspondence never constrains the year range; only the month/day relationship is checked.
long_date
Long date for a locale: 7. September 2026 (de), September 7, 2026 (en). Unknown locales fall back through the base language to English. Returns None for invalid calendar dates.
medium_date
Medium date for a locale: 07.09.2026 (de), Sep 7, 2026 (en). Returns None for invalid calendar dates.
month_year
Month and year for a correspondence dateline: September 2026. Returns None for an invalid month.
normalize
Recognize a signature image given as a data: URL or raw base64. Base64 must use the canonical alphabet, padding and trailing bits without whitespace. Data URLs must end their metadata with the ;base64 flag. Returns None for empty, undecodable, malformed-header, or unsupported inputs (including WebP and GIF). This reads raster headers only: successful recognition does not validate pixel data or sanitize SVG content.
normalize_language
Normalize a loose language string to a supported lowercase BCP 47 code. Trims whitespace, accepts underscore separators and mixed case, and falls back to the base language for unknown variants. Unknown languages yield None.
normalize_locale_id
Normalize an explicit locale ID’s spelling without inferring a locale. Trims only ASCII space, tab, LF, CR, VT and FF, replaces underscores with hyphens and lowercases ASCII letters. Other characters are preserved. Preserves all subtags, including variants absent from the correspondence tables. This is not syntax or registry validation; callers validate their supported shape separately. Empty input stays empty, and no region is added.
opening
Opening line: when a name is given for a locale covered by the uniform salutation renderer, the name is parsed and rendered the same way as salutation; otherwise the named template is filled verbatim, or the formal address when no name is given. An explicit override always wins.
orthography_issues
Non-mutating diagnostics: return each applicable source/replacement pair found in the text, once, in table order. Pass generated prose only; names, quotations, URLs and exact source material must be excluded by the caller.
orthography_replacements
Literal orthography replacements for the locale, in table order. An empty slice means no substitutions. This is spelling data, not a full grammar checker; the caller owns the boundary between prose and source text.
recipient_salutation_warning
Non-blocking advisory when the recipient name is missing: the letter still renders with the formal salutation, but a tailored opportunity should name a person. Returns None when a last name is available.
resolve_locale
Resolve a language plus an optional free-text location to a BCP 47 locale: variant mapping through the country, base fallback, en when nothing is recognized. No location preserves the normalized language.
salutation
Locale-correct salutation through the uniform renderer for every locale it covers (no per-language branch: coverage is data in the salutation tables); all other locales resolve the opening template.
salutation_honorific
Canonical display honorific of a recipient name for the locale, or “” when the first token is unparsable. Abbreviations outside the table are rejected; display forms are canonicalized (never accusative, never abbreviated beyond the table form). No gender is ever inferred: without an explicit honorific the caller falls back to the formal template.
salutation_last_name
Last whitespace-separated token of a recipient name. “Dr. Jane Doe” -> “Doe”; single-token and hyphenated names survive; empty/whitespace yields “”.
salutation_supported
Whether a locale code has a salutation row: present directly or through its (lowercased) base language. Consumers use this predicate instead of any language list in code.
salutation_surname
Surname for the salutation: last significant token after dropping the honorific, academic titles, and post-nominal grades. The raw token is preserved (never normalized for display).
salutation_titles
Academic titles preserved in the salutation, as display forms. Protocol keeps only the highest title, so a sole title (e.g. Professor) suppresses every other title.
scale_to_fit
Linear scale factor that fits the image into a pixel budget, never above 1.0 (never upscales). The caller resamples and re-submits.
short_date
Short numeric date for a locale: 07.09.26 (de), 9/7/26 (en). Returns None for invalid calendar dates.
signature_size
Point size for a target height, preserving aspect ratio, clamped to an optional maximum width. Returns None when the image carries no dimensions (SVG without explicit metrics), when dimensions or requested sizes are nonpositive/nonfinite, or when the result cannot be represented as positive finite point dimensions. The caller must handle those cases.
subject
Subject line: prefix plus title, or the unsolicited-subject default when no title is known. The override replaces the prefix only, mirroring how per-workspace subject choices compose.
supported_formats
Accepted image formats, from tables/defaults.json.
warnings
Non-blocking advisories for a recipient name: the missing-name warning in every locale, the honorific warning wherever the uniform renderer applies. Empty means the record is clean.