@lunmark/vokativ
v0.1.0
Published
The Serbian vocative (vokativ) of a person's name, in Latin or Cyrillic.
Maintainers
Readme
@lunmark/vokativ
The Serbian vocative (vokativ) of a person's name, for JavaScript and TypeScript.
import { vokativ } from "@lunmark/vokativ"
vokativ("Ivan") // "Ivane"
vokativ("Mihajlo") // "Mihajlo"
vokativ("Ljubica") // "Ljubice"
vokativ("Петар") // "Петре"
vokativ("Dusan") // "Dusane" (a plain spelling stays plain)
vokativ("Marko Janković", { gender: "m" }) // "Marko Jankoviću"
vokativ("Ana Janković", { gender: "f" }) // "Ana Janković"
vokativ("Jovan-Petar") // "Jovane-Petre"
vokativ("Ivan", { script: "cyrillic" }) // "Иване"- Latin and Cyrillic, any case: only the ending changes, in the name's own script.
- No dependencies, about 2.3 KB gzipped, ESM with TypeScript types.
- Runs in Node 18+ and every current browser, with the same code.
API
vokativ(fullName, { gender, script }?)
Treats the first word as the given name and the rest as surnames. gender is "m", "f"
or left out.
script ("latin" or "cyrillic") writes the whole name in that script, for a page in one
script showing names typed in either. Left out, the name keeps its own. A plain "dj" reads as
đ (Djordje → Ђорђе), and a name with letters Serbian doesn't have (Wendy, René) stays as
written.
A woman's surname never changes ("gospođo Janković"), so surnames are declined only for
gender: "m". Without a gender they're left as written: "Ana Jankoviću" is wrong, while
"Marko Janković" is merely plain. For the same reason, gender: "f" leaves a given name that
ends in a consonant as it is (Karmen, Ines).
A name longer than 100 characters comes back as written: names often come from strangers, and no real one is that long.
How the rules work, and how accurate they are: see the repo README.
Development
Needs Node 24 (the scripts run TypeScript directly) and pnpm, which switches itself to
the version in devEngines.
pnpm install
pnpm test # unit tests + every name in ../data
pnpm check # Biome: lint and format (pnpm fix applies fixes)
pnpm typecheck
pnpm check:dataset # the rules alone against ../data: accuracy and every miss
pnpm build:exceptions # regenerate src/exceptions.ts after changing a rule or the errata
pnpm build # dist/, what gets published| Path | What it is |
| --- | --- |
| src/index.ts | the public API |
| src/rules.ts | the rules, and applying an exception |
| src/translit.ts | Latin ↔ Cyrillic, and diacritic folding |
| src/exceptions.ts | generated from ../data; never edit it by hand |
| test/dataset.ts | reads ../data (see its README) |
src/ imports nothing outside itself, and a test enforces that: it's what keeps the package
working in the browser. Reporting a wrong name or sending a fix: see
Contributing.
Releasing
See Releasing in the repo README.
