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.
1 lines • 18.2 kB
Source Map (JSON)
{"version":3,"sources":["../../src/rules/dates.js","../../src/rules/initials.js","../../src/rules/ordinals.js","../../src/data/prepositions.js","../../src/rules/prepositions.js","../../src/rules/roman.js","../../src/rules/thousands.js","../../src/data/units.js","../../src/rules/units.js","../../src/fixCzech.js","../../src/next/loader.cjs"],"names":["init_prepositions","init_units","exports","fixCzech"],"mappings":"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","file":"loader.cjs","sourcesContent":["const FULL_DATE_REGEX = /(\\d{1,2})\\.[ \\t]+(\\d{1,2})\\.[ \\t]+(\\d{2,4})\\b/g;\r\nconst DAY_MONTH_REGEX = /(\\d{1,2})\\.[ \\t]+(\\d{1,2})\\.(?=[^\\p{L}\\p{N}]|$)/gu;\r\n\r\n/**\r\n * Glues date components together with non-breaking spaces.\r\n *\r\n * - `5. 12. 2024` → `5.\\u00A012.\\u00A02024`\r\n * - `5. 12.` → `5.\\u00A012.`\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyDates(text) {\r\n return text\r\n .replace(FULL_DATE_REGEX, '$1.\\u00A0$2.\\u00A0$3')\r\n .replace(DAY_MONTH_REGEX, '$1.\\u00A0$2.');\r\n}\r\n","const INITIAL_REGEX = /(\\b\\p{Lu})\\.[ \\t]+(?=\\p{Lu})/gu;\r\n\r\n/**\r\n * Glues an initial (a single uppercase letter followed by a dot) to the\r\n * following word with a non-breaking space. Repeats until stable so chains\r\n * like `J. R. R. Tolkien` are fully fixed.\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyInitials(text) {\r\n let previous;\r\n let current = text;\r\n do {\r\n previous = current;\r\n current = current.replace(INITIAL_REGEX, '$1.\\u00A0');\r\n } while (current !== previous);\r\n return current;\r\n}\r\n","const ORDINAL_REGEX = /(\\d{1,2})\\.[ \\t]+(?=\\p{Ll})/gu;\r\n\r\n/**\r\n * Glues ordinal numbers to the following word with a non-breaking space.\r\n * Triggers only when the next character is a Unicode lowercase letter so\r\n * sentences ending with an ordinal (e.g. `žil v 19. století. Měl…`)\r\n * are not affected at the sentence boundary.\r\n *\r\n * - `1. ledna` → `1.\\u00A0ledna`\r\n * - `25. listopadu 2024` → `25.\\u00A0listopadu 2024`\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyOrdinals(text) {\r\n return text.replace(ORDINAL_REGEX, '$1.\\u00A0');\r\n}\r\n","/**\r\n * Czech one-letter prepositions and conjunctions that should not be left\r\n * at the end of a line (per Czech orthography rules).\r\n *\r\n * Source: https://prirucka.ujc.cas.cz/?id=880\r\n *\r\n * @type {readonly string[]}\r\n */\r\nexport const PREPOSITIONS = Object.freeze([\r\n 'a',\r\n 'i',\r\n 'k',\r\n 'o',\r\n 's',\r\n 'u',\r\n 'v',\r\n 'z',\r\n]);\r\n","import { PREPOSITIONS } from '../data/prepositions.js';\r\n\r\nconst PREPOSITION_REGEX = new RegExp(\r\n `(?<=^|[\\\\s(\\\\[\"'\\u00A0\\u2018\\u201C\\u00BB\\u2014\\u2013-])(${PREPOSITIONS.join('|')})[ \\\\t]+(?=\\\\S)`,\r\n 'giu',\r\n);\r\n\r\n/**\r\n * Glues Czech one-letter prepositions and conjunctions (a, i, k, o, s, u,\r\n * v, z) to the following word with a non-breaking space.\r\n *\r\n * Case-insensitive – also handles capitalised forms at the start of a\r\n * sentence (`K Tobě`, `V domě`, `S Petrem`).\r\n *\r\n * Uses a lookbehind so consecutive prepositions (`v a z`) are all fixed\r\n * in a single pass.\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyPrepositions(text) {\r\n return text.replace(PREPOSITION_REGEX, '$1\\u00A0');\r\n}\r\n","const ROMAN_NUMERAL =\r\n '(?:(?=[IVXLCDM])M{0,3}(?:CM|CD|D?C{0,3})(?:XC|XL|L?X{0,3})(?:IX|IV|V?I{0,3}))';\r\nconst ROMAN_REGEX = new RegExp(\r\n `(\\\\b\\\\p{Lu}\\\\p{L}+)[ \\\\t]+(?=${ROMAN_NUMERAL}\\\\.(?=[^\\\\p{L}\\\\p{N}]|$))`,\r\n 'gu',\r\n);\r\n\r\n/**\r\n * Glues a name to a following Roman numeral (with optional dot) using a\r\n * non-breaking space.\r\n *\r\n * - `Karel IV.` → `Karel\\u00A0IV.`\r\n * - `Jindřich VIII.` → `Jindřich\\u00A0VIII.`\r\n * - `papež Jan Pavel II.` → `papež Jan Pavel\\u00A0II.`\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyRoman(text) {\r\n return text.replace(ROMAN_REGEX, '$1\\u00A0');\r\n}\r\n","const THOUSANDS_REGEX = /(\\d)[ \\t](\\d{3})(?=\\D|$)/g;\r\n\r\n/**\r\n * Replaces a regular space used as a thousand separator with a non-breaking\r\n * space so the number stays on one line (`10 000` → `10\\u00A0000`).\r\n *\r\n * Applied repeatedly to handle multiple separators in a single number\r\n * (`1 000 000`).\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyThousands(text) {\r\n let previous;\r\n let current = text;\r\n do {\r\n previous = current;\r\n current = current.replace(THOUSANDS_REGEX, '$1\\u00A0$2');\r\n } while (current !== previous);\r\n return current;\r\n}\r\n","/**\r\n * Units of measurement that are safe to glue to a preceding number with a\r\n * non-breaking space, regardless of what follows.\r\n *\r\n * Sorted from longest to shortest so the regex alternation matches the most\r\n * specific unit first (e.g. `kWh` before `kW` before `W`).\r\n *\r\n * @type {readonly string[]}\r\n */\r\nexport const SAFE_UNITS = Object.freeze(\r\n [\r\n 'km/h',\r\n 'm/s',\r\n 'kWh',\r\n 'mAh',\r\n 'mbar',\r\n 'kbps',\r\n 'Mbps',\r\n 'Gbit',\r\n 'kPa',\r\n 'bar',\r\n 'kg',\r\n 'mg',\r\n 'cm',\r\n 'mm',\r\n 'µm',\r\n 'nm',\r\n 'km',\r\n 'ml',\r\n 'cl',\r\n 'dl',\r\n 'kJ',\r\n 'Nm',\r\n 'Wb',\r\n 'lm',\r\n 'lx',\r\n 'cd',\r\n 'mol',\r\n 'min',\r\n 'ms',\r\n 'ns',\r\n 'Hz',\r\n 'Pa',\r\n 'kW',\r\n 'MW',\r\n 'Ohm',\r\n '°C',\r\n '°F',\r\n '°',\r\n '‰',\r\n '%',\r\n 'px',\r\n 'pt',\r\n 'dpi',\r\n 'bpm',\r\n 'EUR',\r\n 'USD',\r\n 'CZK',\r\n 'Kč',\r\n 'mg/m³',\r\n 'str',\r\n 'osob',\r\n 'ks',\r\n 'MJ',\r\n 'TB',\r\n 'GB',\r\n 'MB',\r\n 'kB',\r\n 'bit',\r\n 'GBit',\r\n 'mol',\r\n 'Ω',\r\n '€',\r\n '$',\r\n '£',\r\n ].sort((a, b) => b.length - a.length),\r\n);\r\n\r\n/**\r\n * Units that collide with common Czech words/letters when used as a\r\n * single character (e.g. `s` is also a preposition, `m` matches `m` in\r\n * \"5 mužů\"). They are applied only when the unit is followed by a clear\r\n * word boundary that is not another letter (interpunction or end of string).\r\n *\r\n * @type {readonly string[]}\r\n */\r\nexport const STRICT_UNITS = Object.freeze(\r\n ['m', 's', 'l', 't', 'g', 'V', 'A', 'W', 'J', 'K', 'B'].sort(\r\n (a, b) => b.length - a.length,\r\n ),\r\n);\r\n","import { SAFE_UNITS, STRICT_UNITS } from '../data/units.js';\r\n\r\nfunction escapeRegex(value) {\r\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\nconst SAFE_PATTERN = SAFE_UNITS.map(escapeRegex).join('|');\r\nconst STRICT_PATTERN = STRICT_UNITS.map(escapeRegex).join('|');\r\n\r\nconst SAFE_UNIT_REGEX = new RegExp(\r\n `(\\\\d)[ \\\\t]+(?=(?:${SAFE_PATTERN})(?![\\\\p{L}\\\\p{N}]))`,\r\n 'gu',\r\n);\r\n\r\nconst STRICT_UNIT_REGEX = new RegExp(\r\n `(\\\\d)[ \\\\t]+(?=(?:${STRICT_PATTERN})(?:[.,;:!?)\\\\]/\\\\u00A0]|$))`,\r\n 'gu',\r\n);\r\n\r\n/**\r\n * Glues a number to its unit of measurement with a non-breaking space.\r\n *\r\n * Two passes:\r\n * 1. **Safe units** – multi-character or symbolic units (`km`, `°C`, `Kč`,\r\n * `Ω`) match whenever they follow a digit and are not the prefix of a\r\n * longer word.\r\n * 2. **Strict units** – single-letter units that collide with common Czech\r\n * words (`s`, `m`, `g`, `K`, `V`, `A`, `W`) match only when followed by\r\n * interpunction or end-of-string – never when followed by another\r\n * letter (avoids false positives like `5 mužů`).\r\n *\r\n * @param {string} text\r\n * @returns {string}\r\n */\r\nexport function applyUnits(text) {\r\n return text\r\n .replace(SAFE_UNIT_REGEX, '$1\\u00A0')\r\n .replace(STRICT_UNIT_REGEX, '$1\\u00A0');\r\n}\r\n","import { applyDates } from './rules/dates.js';\r\nimport { applyInitials } from './rules/initials.js';\r\nimport { applyOrdinals } from './rules/ordinals.js';\r\nimport { applyPrepositions } from './rules/prepositions.js';\r\nimport { applyRoman } from './rules/roman.js';\r\nimport { applyThousands } from './rules/thousands.js';\r\nimport { applyUnits } from './rules/units.js';\r\n\r\n/**\r\n * @typedef {object} FixCzechOptions\r\n * @property {boolean} [prepositions=true] Glue one-letter prepositions/conjunctions to the next word.\r\n * @property {boolean} [units=true] Glue numbers to units of measurement.\r\n * @property {boolean} [initials=true] Glue initials (J., A.) to surnames.\r\n * @property {boolean} [dates=true] Glue dates (5. 12. 2024) together.\r\n * @property {boolean} [ordinals=true] Glue ordinal numbers (1. ledna) to the next word.\r\n * @property {boolean} [roman=true] Glue names to Roman numerals (Karel IV.).\r\n * @property {boolean} [thousands=true] Replace thousands separators (10 000) with nbsp.\r\n */\r\n\r\nconst DEFAULT_OPTIONS = Object.freeze({\r\n prepositions: true,\r\n units: true,\r\n initials: true,\r\n dates: true,\r\n ordinals: true,\r\n roman: true,\r\n thousands: true,\r\n});\r\n\r\n/**\r\n * Apply Czech typography rules to a string.\r\n *\r\n * Returns the input unchanged when it isn't a string, so the function is\r\n * safe to call on `null`, `undefined`, numbers etc. without guarding.\r\n *\r\n * Pipeline order matters – `thousands` runs before `units`, otherwise the\r\n * \"10 000 km\" case would steal the thousand-separator space as the\r\n * number-to-unit space.\r\n *\r\n * @param {string} text\r\n * @param {FixCzechOptions} [options]\r\n * @returns {string}\r\n */\r\nexport function fixCzech(text, options) {\r\n if (typeof text !== 'string' || text.length === 0) {\r\n return text;\r\n }\r\n\r\n const opts = options ? { ...DEFAULT_OPTIONS, ...options } : DEFAULT_OPTIONS;\r\n\r\n let result = text;\r\n if (opts.thousands) result = applyThousands(result);\r\n if (opts.dates) result = applyDates(result);\r\n if (opts.ordinals) result = applyOrdinals(result);\r\n if (opts.units) result = applyUnits(result);\r\n if (opts.initials) result = applyInitials(result);\r\n if (opts.roman) result = applyRoman(result);\r\n if (opts.prepositions) result = applyPrepositions(result);\r\n return result;\r\n}\r\n\r\nexport default fixCzech;\r\n","'use strict';\r\n\r\nconst { fixCzech } = require('../fixCzech.js');\r\n\r\nconst JSX_TEXT_REGEX = />([^<>{}]*?[a-zA-Záčďéěíňóřšťúůýž][^<>{}]*?)</g;\r\n\r\n/**\r\n * Webpack loader that rewrites static JSX text nodes by piping them\r\n * through {@link fixCzech}. Operates on the source string – greps for\r\n * `>plain text<` segments inside JSX-looking files and replaces the\r\n * captured text. `{...}` expressions are deliberately ignored, so\r\n * dynamic interpolations are untouched.\r\n *\r\n * For more aggressive rewriting use the runtime middleware – this\r\n * loader is an opt-in optimisation for build-time processing of\r\n * obviously-static JSX text.\r\n *\r\n * @param {string} source\r\n * @returns {string}\r\n */\r\nmodule.exports = function czTypographyLoader(source) {\r\n const opts = this.getOptions ? this.getOptions() || {} : {};\r\n return source.replace(JSX_TEXT_REGEX, function (full, text) {\r\n const fixed = fixCzech(text, opts.options);\r\n if (fixed === text) return full;\r\n return '>' + fixed + '<';\r\n });\r\n};\r\n"]}