// Типографика для вывода: неразрывные пробелы после коротких слов и между числом и единицей, // неразрывный дефис в двойных латинских фамилиях. Смысл текста не меняется. const NBSP = ' '; const SHORT = 'а|в|во|и|к|ко|на|не|но|о|об|от|до|по|с|со|у|за|из|для|как|или'; const SHORT_RE = new RegExp(`(^|[\\s(«—–-])(${SHORT}) `, 'giu'); const UNIT_RE = /(\d) (кг|г|шт|BYN|мин|дн\.?|день|дня)(?=$|[\s.,:;!?)»])/gu; const NAME_HYPHEN_RE = /([A-Z][a-z]+)-([A-Z][a-z]+)/g; export function typo(text: string): string { // дважды: «и в Минске» — после замены первого слова второе стоит уже после NBSP let out = text.replace(SHORT_RE, `$1$2${NBSP}`); out = out.replace(new RegExp(`(${NBSP})(${SHORT}) `, 'giu'), `$1$2${NBSP}`); return out.replace(UNIT_RE, `$1${NBSP}$2`).replace(NAME_HYPHEN_RE, '$1‑$2'); } /** Склеить фразу целиком, чтобы она не рвалась: «красное яблоко». */ export function keep(text: string): string { return text.replace(/ /g, NBSP); }