cz-typography
Version:
Universal Czech typography fixer for JavaScript, React, Next.js, and any SSR framework. Non-breaking spaces after one-letter prepositions, units, dates, ordinals and more.
203 lines (190 loc) • 6.61 kB
TypeScript
/**
* Glues date components together with non-breaking spaces.
*
* - `5. 12. 2024` → `5.\u00A012.\u00A02024`
* - `5. 12.` → `5.\u00A012.`
*
* @param {string} text
* @returns {string}
*/
declare function applyDates(text: string): string;
/**
* Glues an initial (a single uppercase letter followed by a dot) to the
* following word with a non-breaking space. Repeats until stable so chains
* like `J. R. R. Tolkien` are fully fixed.
*
* @param {string} text
* @returns {string}
*/
declare function applyInitials(text: string): string;
/**
* Glues ordinal numbers to the following word with a non-breaking space.
* Triggers only when the next character is a Unicode lowercase letter so
* sentences ending with an ordinal (e.g. `žil v 19. století. Měl…`)
* are not affected at the sentence boundary.
*
* - `1. ledna` → `1.\u00A0ledna`
* - `25. listopadu 2024` → `25.\u00A0listopadu 2024`
*
* @param {string} text
* @returns {string}
*/
declare function applyOrdinals(text: string): string;
/**
* Glues Czech one-letter prepositions and conjunctions (a, i, k, o, s, u,
* v, z) to the following word with a non-breaking space.
*
* Case-insensitive – also handles capitalised forms at the start of a
* sentence (`K Tobě`, `V domě`, `S Petrem`).
*
* Uses a lookbehind so consecutive prepositions (`v a z`) are all fixed
* in a single pass.
*
* @param {string} text
* @returns {string}
*/
declare function applyPrepositions(text: string): string;
/**
* Glues a name to a following Roman numeral (with optional dot) using a
* non-breaking space.
*
* - `Karel IV.` → `Karel\u00A0IV.`
* - `Jindřich VIII.` → `Jindřich\u00A0VIII.`
* - `papež Jan Pavel II.` → `papež Jan Pavel\u00A0II.`
*
* @param {string} text
* @returns {string}
*/
declare function applyRoman(text: string): string;
/**
* Replaces a regular space used as a thousand separator with a non-breaking
* space so the number stays on one line (`10 000` → `10\u00A0000`).
*
* Applied repeatedly to handle multiple separators in a single number
* (`1 000 000`).
*
* @param {string} text
* @returns {string}
*/
declare function applyThousands(text: string): string;
/**
* Glues a number to its unit of measurement with a non-breaking space.
*
* Two passes:
* 1. **Safe units** – multi-character or symbolic units (`km`, `°C`, `Kč`,
* `Ω`) match whenever they follow a digit and are not the prefix of a
* longer word.
* 2. **Strict units** – single-letter units that collide with common Czech
* words (`s`, `m`, `g`, `K`, `V`, `A`, `W`) match only when followed by
* interpunction or end-of-string – never when followed by another
* letter (avoids false positives like `5 mužů`).
*
* @param {string} text
* @returns {string}
*/
declare function applyUnits(text: string): string;
/**
* Czech one-letter prepositions and conjunctions that should not be left
* at the end of a line (per Czech orthography rules).
*
* Source: https://prirucka.ujc.cas.cz/?id=880
*
* @type {readonly string[]}
*/
declare const PREPOSITIONS: readonly string[];
/**
* Apply Czech typography rules to a string.
*
* Returns the input unchanged when it isn't a string, so the function is
* safe to call on `null`, `undefined`, numbers etc. without guarding.
*
* Pipeline order matters – `thousands` runs before `units`, otherwise the
* "10 000 km" case would steal the thousand-separator space as the
* number-to-unit space.
*
* @param {string} text
* @param {FixCzechOptions} [options]
* @returns {string}
*/
declare function fixCzech(text: string, options?: FixCzechOptions): string;
type FixCzechOptions = {
/**
* Glue one-letter prepositions/conjunctions to the next word.
*/
prepositions?: boolean;
/**
* Glue numbers to units of measurement.
*/
units?: boolean;
/**
* Glue initials (J., A.) to surnames.
*/
initials?: boolean;
/**
* Glue dates (5. 12. 2024) together.
*/
dates?: boolean;
/**
* Glue ordinal numbers (1. ledna) to the next word.
*/
ordinals?: boolean;
/**
* Glue names to Roman numerals (Karel IV.).
*/
roman?: boolean;
/**
* Replace thousands separators (10 000) with nbsp.
*/
thousands?: boolean;
};
/**
* Apply Czech typography rules to an HTML string. Tags, attributes,
* comments, doctypes and the contents of `script`/`style`/`pre`/`code`/
* `textarea` elements are left untouched.
*
* @param {string} html
* @param {import('./fixCzech.js').FixCzechOptions} [options]
* @returns {string}
*/
declare function fixCzechHtml(html: string, options?: FixCzechOptions): string;
/**
* Stateful streaming processor – feeds chunks of HTML through the same
* transformation as {@link fixCzechHtml} while keeping a small tail
* buffer to handle words and tags split across chunk boundaries.
*
* @param {import('./fixCzech.js').FixCzechOptions} [options]
* @returns {{ feed(chunk: string): string, flush(): string }}
*/
declare function createFixCzechProcessor(options?: FixCzechOptions): {
feed(chunk: string): string;
flush(): string;
};
/**
* Create a Web-Streams `TransformStream` that applies Czech typography
* rules to an HTML response on the fly. Compatible with Vercel Edge,
* Cloudflare Workers, Node.js 18+, Deno and Bun.
*
* @param {import('./fixCzech.js').FixCzechOptions} [options]
* @returns {TransformStream<Uint8Array | string, Uint8Array>}
*/
declare function createFixCzechStream(options?: FixCzechOptions): TransformStream<Uint8Array | string, Uint8Array>;
/**
* Units of measurement that are safe to glue to a preceding number with a
* non-breaking space, regardless of what follows.
*
* Sorted from longest to shortest so the regex alternation matches the most
* specific unit first (e.g. `kWh` before `kW` before `W`).
*
* @type {readonly string[]}
*/
declare const SAFE_UNITS: readonly string[];
/**
* Units that collide with common Czech words/letters when used as a
* single character (e.g. `s` is also a preposition, `m` matches `m` in
* "5 mužů"). They are applied only when the unit is followed by a clear
* word boundary that is not another letter (interpunction or end of string).
*
* @type {readonly string[]}
*/
declare const STRICT_UNITS: readonly string[];
export { PREPOSITIONS, SAFE_UNITS, STRICT_UNITS, applyDates, applyInitials, applyOrdinals, applyPrepositions, applyRoman, applyThousands, applyUnits, createFixCzechProcessor, createFixCzechStream, fixCzech as default, fixCzech, fixCzechHtml };