Skip to main content

cnice

Formulaic correspondence phrases: salutations and valedictions for every covered locale.

crates.io npm PyPI Rust API

cnice is a facade over two deterministic correspondence libraries: salutations (cnice.greet, previously the German-only cgreet repo) and locale-specific valedictions (cnice.farewell, previously cfarewell). One matcher renders every language from table rows — a new language is a new row, never new code. Same input always yields the same output: no models, no I/O.

import { farewell, greet } from '@corbet-labs/cnice';

greet.salutation('de-ch', 'Frau Dr. Müller');
// Sehr geehrte Frau Dr. Müller
greet.salutation('fr', 'Madame Dupont');
// Madame Dupont,
farewell.closing('de-ch');
// Freundliche Grüsse

Install

Version 0.1.3 is published to registries.

Environment Command
Rust / Cargo cargo add cnice
Python / pip python -m pip install cnice
Python / uv uv add cnice
Node.js / npm npm install @corbet-labs/cnice
pnpm pnpm add @corbet-labs/cnice
Yarn yarn add @corbet-labs/cnice
Bun bun add @corbet-labs/cnice
Deno deno add npm:@corbet-labs/cnice
Typst #import "@preview/cnice:0.1.3": *

The JavaScript distribution includes compiled ESM, CommonJS, TypeScript declarations, and a standalone browser module. Node.js 20+ is supported; no TypeScript loader is required.

// CommonJS
const { greet, farewell } = require('@corbet-labs/cnice');
<script type="module">
  import { greet } from 'https://cdn.jsdelivr.net/npm/@corbet-labs/cnice@0.1.3/dist/browser.js';
  console.log(greet.salutation('de-ch', 'Frau Dr. Müller'));
</script>

See the installation guide for CLI commands and other distribution options. JSR installation is documented there too.

Rust

use cnice::{farewell, greet};

assert_eq!(greet::salutation("de-ch", "Frau Dr. Müller"), "Sehr geehrte Frau Dr. Müller");
assert_eq!(greet::salutation("fr", "Madame Dupont"), "Madame Dupont,");
assert_eq!(farewell::closing("de-ch", None), "Freundliche Grüsse");

Typst in Rust hosts

The crate also ships the Typst package. Applications that embed the Typst compiler can register it from cnice::typst instead of downloading or vendoring a copy, so Rust and Typst always come from the same release. FILES holds package-relative paths (typst.toml, typst/lib.typ, and the tables/ the Typst sources read) with their bytes; spec() is the import specification.

use cnice::typst::{FILES, NAME, NAMESPACE, VERSION, spec};

assert_eq!((NAMESPACE, NAME), ("preview", "cnice"));
assert_eq!(spec(), format!("@preview/cnice:{VERSION}"));
for (path, bytes) in FILES {
    // Serve `bytes` for `path` inside the package `spec()` in your Typst world.
    let _ = (path, bytes.len());
}

Documents then import the package as usual, for example #import "@preview/cnice:0.1.3": greet, farewell.

Python

from cnice import farewell, greet

assert greet.salutation("de-ch", "Frau Dr. Müller") == 'Sehr geehrte Frau Dr. Müller'
assert greet.salutation("fr", "Madame Dupont") == 'Madame Dupont,'
assert farewell.closing("de-ch") == 'Freundliche Grüsse'

The Python CLI accepts bare and namespaced function names and writes JSON to stdout:

cnice greet.salutation '["de-ch", "Frau Dr. Müller"]'
cnice closing '["de-ch"]'
python -m cnice --help

API

Function Purpose
greet.salutation / greet.salutation / greet.salutation Complete salutation for any covered locale
greet.salutationHonorific, greet.salutationTitles, greet.salutationSurname Parse explicitly supplied recipient details (locale-keyed)
greet.isSupported / greet.is_supported / greet.is-supported Whether a locale has a salutation row
greet.recipientSalutationWarning, greet.honorificWarning Report incomplete input
farewell.closing(locale, override?) Resolve a valediction; even an empty override wins
farewell.availableLocales() / farewell.available_locales() / farewell.available-locales() List the canonical locale codes

Covered salutation locales: de, de-ch, de-at, de-li, fr, it, rm, en, en-gb, en-us. Comma behavior, title precedence and formal fallbacks are row data, identical on every port. A recognized Professor title takes precedence over Dr. Missing honorifics or surnames produce the formal fallback. The library does not infer a person’s gender from their name. Valediction lookups are case-insensitive and resolve the exact locale, then its base language, then English; an explicit override always wins.

Correspondence family

Library Responsibility
cletter Compose the correspondence helpers
cnice Formulaic salutations and valedictions (this repo: cnice.greet + cnice.farewell)
cdate Calendar-date formatting
cink Handwritten signature images
cgrade Planned correspondence helper
cnumber Number formatting with Swiss amtlich mode
cbcp Planned correspondence helper

Development

Behavior is defined by the locale tables and shared conformance vectors. Rust, JavaScript, Python, and Typst run the same 189 vectors. Selected CI checks exercise installed JavaScript tarballs, Python wheels and command-line entrypoints, and Typst packages. Release validation records the actual runtime and platform; Linux results do not establish native Windows or macOS coverage. All crates forbid unsafe code in their own source.

See the release guide for generation, verification, and publication commands.

License

Copyright 2026 Julian Y. Richard Corbet. The 0.1.3 release line is licensed under LGPL-3.0-only WITH LGPL-3.0-linking-exception, with the incorporated GPL version 3. Combined works may link statically or dynamically without relinking duties; library modifications stay LGPL. Applications can use a different license subject to the LGPL's conditions. The cgreet and cfarewell repositories keep their own release grants untouched; this facade does not relicense them.

See the licensing notes for distribution conditions and retained notices. Contributions are accepted under the Contributor License Agreement.

Metadata

Release files for cnice 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cnice 0.1.3
File Size Uploaded Provenance Actions
cnice-0.1.3.tar.gz 42.6 kB Without provenance Details for cnice-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cnice 0.1.3
File Interpreter ABI Platform Actions
cnice-0.1.3-py3-none-any.whl Python 3 none any Details for cnice-0.1.3-py3-none-any.whl

Total release size: 84.7 kB

Release files / cnice-0.1.3.tar.gz

Download URL cnice-0.1.3.tar.gz
Size 42.6 kB
Tags Source
SHA-256 checksum
How to use checksums
aff53271751885ae166ad2f92ab46b36d6e8f1acf061f6da9054566b46e8682e
BLAKE2b-256 checksum
How to use checksums
ecc440ea1ff829f021db20446cda937dd990c6dd79fed52b187ce978e6d038a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.11 {"installer":{"name":"uv","version":"0.12.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.11","id":"zokor","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / cnice-0.1.3-py3-none-any.whl

Download URL cnice-0.1.3-py3-none-any.whl
Size 42.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2d6b4726023ed7cd8772b2a35b34223b524ce485dda058c8beab03ee6fb00130
BLAKE2b-256 checksum
How to use checksums
b9dcb7f80925747faf2ab382db6f4f813344051a6f4bd1999f1e3f118ce9220a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.11 {"installer":{"name":"uv","version":"0.12.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.11","id":"zokor","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for cnice 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page