UNPKG

text-aligner

Version:

Align text by adding spaces to each string so that all strings have the same number of English and Chinese characters.

142 lines (141 loc) 4.11 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { alignText: () => alignText }); module.exports = __toCommonJS(index_exports); var FallbackKey = "@@fallback"; var FallbackPlaceholder = "\u2007"; var DefaultPaddingMap = { cjk: { test: (char) => isCJK(char), placeholder: "\u2001" }, [FallbackKey]: { test: FallbackKey, placeholder: FallbackPlaceholder } }; function isCJK(char) { const cjkRanges = [ // Chinese (Hanzi) ranges [19968, 40959], // CJK Unified Ideographs [13312, 19903], // CJK Unified Ideographs Extension A [131072, 173791], // CJK Unified Ideographs Extension B [173824, 177983], // CJK Unified Ideographs Extension C [177984, 178207], // CJK Unified Ideographs Extension D [178208, 183983], // CJK Unified Ideographs Extension E [63744, 64255], // CJK Compatibility Ideographs [194560, 195103], // CJK Compatibility Ideographs Supplement // Japanese ranges [12352, 12447], // Hiragana [12448, 12543], // Katakana [12784, 12799], // Katakana Phonetic Extensions // Korean ranges [44032, 55203], // Hangul Syllables [4352, 4607], // Hangul Jamo [12592, 12687] // Hangul Compatibility Jamo ]; const charCode = char.codePointAt(0); return cjkRanges.some(([start, end]) => charCode >= start && charCode <= end); } function countChars(str, rules) { const counts = { [FallbackKey]: 0 }; Object.keys(rules).forEach((key) => counts[key] = 0); for (const char of str) { let matched = false; for (const [key, rule] of Object.entries(rules)) { if (key === FallbackKey || rule.test === FallbackKey) { continue; } if (typeof rule.test === "function" ? rule.test(char) : rule.test.test(char)) { counts[key]++; matched = true; break; } } if (!matched) { counts[FallbackKey]++; } } return counts; } function findMaxCounts(counts) { const maxCounts = {}; for (const count of counts) { Object.keys(count).forEach((key) => { maxCounts[key] = Math.max(maxCounts[key] || 0, count[key]); }); } return maxCounts; } function alignText(strings, paddingMap = DefaultPaddingMap) { const normalizedPaddingMap = {}; for (const [key, value] of Object.entries(paddingMap)) { if (typeof value === "string") { if (!DefaultPaddingMap[key]) { continue; } normalizedPaddingMap[key] = { test: DefaultPaddingMap[key]?.test, placeholder: value }; continue; } normalizedPaddingMap[key] = value; } normalizedPaddingMap[FallbackKey] ??= { test: FallbackKey, placeholder: FallbackPlaceholder }; const counts = strings.map((str) => countChars(str, normalizedPaddingMap)); const maxCounts = findMaxCounts(counts); return strings.map((str, index) => { const currentCounts = counts[index]; let result = str; for (const [key, count] of Object.entries(maxCounts)) { const diff = count - currentCounts[key]; result += normalizedPaddingMap[key].placeholder.repeat(diff); } return result; }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { alignText }); //# sourceMappingURL=index.cjs.map