UNPKG

pangu

Version:

Opinionated paranoid text spacing: automatically inserts whitespace between CJK (Chinese, Japanese, Korean) and ANS (alphabetical letters, numerical digits and symbols)

434 lines (430 loc) 19.5 kB
#!/usr/bin/env node import { text } from "node:stream/consumers"; import { readFileSync } from "node:fs"; import { readFile } from "node:fs/promises"; //#region src/shared/index.ts var CJK_RADICALS_SUPPLEMENT = "⺀-⻿"; var KANGXI_RADICALS = "⼀-⿟"; var HIRAGANA = "぀-ゟ"; var KATAKANA_NO_MIDDLE_DOT = "゠-ヺー-ヿ"; var BOPOMOFO = "㄀-ㄯ"; var ENCLOSED_CJK_LETTERS_AND_MONTHS = "㈀-㋿"; var CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = "㐀-䶿"; var CJK_UNIFIED_IDEOGRAPHS = "一-鿿"; var CJK_COMPATIBILITY_IDEOGRAPHS = "豈-﫿"; var GREEK_AND_COPTIC = "Ͱ-Ͽ"; var LATIN_1_SUPPLEMENT_AFTER_NBSP = "¡-ÿ"; var NUMBER_FORMS = "⅐-↏"; var LETTERLIKE_SYMBOLS = "℀-⅏"; var DINGBATS = "✀-➿"; var SUPERSCRIPT_SUFFIXES = "®²³¹⁰ⁱ⁴-⁼⁾ⁿ℠™"; var CJK = `${CJK_RADICALS_SUPPLEMENT}${KANGXI_RADICALS}${HIRAGANA}${KATAKANA_NO_MIDDLE_DOT}${BOPOMOFO}${ENCLOSED_CJK_LETTERS_AND_MONTHS}${CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A}${CJK_UNIFIED_IDEOGRAPHS}${CJK_COMPATIBILITY_IDEOGRAPHS}`; var AN = "A-Za-z0-9"; var A = "A-Za-z"; var UPPER_AN = "A-Z0-9"; var OPERATORS = "\\*=&\\-"; var GRADE_OPERATORS = "\\+\\-\\*"; var QUOTES = "`\"״"; var LEFT_BRACKETS_BASIC = "\\(\\[\\{"; var RIGHT_BRACKETS_BASIC = "\\)\\]\\}"; var LEFT_BRACKETS_EXTENDED = "\\(\\[\\{<>“"; var RIGHT_BRACKETS_EXTENDED = "\\)\\]\\}<>”"; var ANS_CJK_AFTER = `${A}${GREEK_AND_COPTIC}0-9@\\$%\\^&\\*\\-\\+\\\\=${LATIN_1_SUPPLEMENT_AFTER_NBSP}${NUMBER_FORMS}${DINGBATS}${LETTERLIKE_SYMBOLS}`; var ANS_BEFORE_CJK = `${A}${GREEK_AND_COPTIC}0-9\\$%\\^&\\*\\-\\+\\\\=${LATIN_1_SUPPLEMENT_AFTER_NBSP}${NUMBER_FORMS}${DINGBATS}${LETTERLIKE_SYMBOLS}${SUPERSCRIPT_SUFFIXES}`; var FILE_PATH_DIRS = "home|root|usr|etc|var|opt|tmp|dev|mnt|proc|sys|bin|boot|lib|media|run|sbin|srv|node_modules|path|project|src|dist|test|tests|docs|templates|assets|public|static|config|scripts|tools|build|out|target|your|\\.claude|\\.git|\\.vscode"; var FILE_PATH_CHARS = "[A-Za-z0-9_\\-\\.@\\+\\*]+"; var UNIX_ABSOLUTE_FILE_PATH = new RegExp(`/(?:\\.?(?:${FILE_PATH_DIRS})|\\.(?:[A-Za-z0-9_\\-]+))(?:/${FILE_PATH_CHARS})*`); var UNIX_RELATIVE_FILE_PATH = new RegExp(`(?:\\./)?(?:${FILE_PATH_DIRS})(?:/${FILE_PATH_CHARS})+`); var WINDOWS_FILE_PATH = /[A-Z]:\\(?:[A-Za-z0-9_\-\. ]+\\?)+/; var ANY_CJK = new RegExp(`[${CJK}]`); var CJK_PUNCTUATION = new RegExp(`([${CJK}])([!;,\\?:]+)(?=[${CJK}${AN}])`, "g"); var PUNCTUATION_CJK = new RegExp(`([!;,\\?]+)(?=[${CJK}])`, "g"); var CJK_TILDE = new RegExp(`([${CJK}])(~+)(?!=)(?=[${CJK}${AN}])`, "g"); var CJK_TILDE_EQUALS = new RegExp(`([${CJK}])(~=)`, "g"); var CJK_PERIOD = new RegExp(`([${CJK}])(\\.)(?![${AN}\\./])(?=[${CJK}${AN}])`, "g"); var AN_PERIOD_CJK = new RegExp(`([${AN}])(\\.)([${CJK}])`, "g"); var AN_COLON_CJK = new RegExp(`([${AN}])(:)([${CJK}])`, "g"); var FIX_CJK_COLON_ANS = new RegExp(`([${CJK}])\\:([${UPPER_AN}\\(\\)])`, "g"); var DOTS_CJK = new RegExp(`([\\.]{2,}|\u2026)([${CJK}])`, "g"); var CJK_QUOTE = new RegExp(`([${CJK}])([${QUOTES}])`, "g"); var QUOTE_CJK = new RegExp(`([${QUOTES}])([${CJK}])`, "g"); var FIX_QUOTE_ANY_QUOTE = new RegExp(`([${QUOTES}]+)[ ]*([\\s\\S]+?)[ ]*([${QUOTES}]+)`, "g"); var QUOTE_AN = new RegExp(`([\u201d])([${AN}])`, "g"); var CJK_QUOTE_AN = new RegExp(`([${CJK}])(")([${AN}])`, "g"); var CJK_SINGLE_QUOTE_BUT_POSSESSIVE = new RegExp(`([${CJK}])('[^s])`, "g"); var SINGLE_QUOTE_CJK = new RegExp(`(')([${CJK}])`, "g"); var FIX_POSSESSIVE_SINGLE_QUOTE = new RegExp(`([${AN}${CJK}])( )('s)`, "g"); var SINGLE_QUOTE_PURE_CJK = new RegExp(`(')([${CJK}]+)(')`, "g"); var HASH_ANS_CJK_HASH = new RegExp(`([${CJK}])(#)([${CJK}]+)(#)([${CJK}])`, "g"); var CJK_HASH = new RegExp(`([${CJK}])(#([^ \\u00a0]))`, "g"); var HASH_CJK = new RegExp(`(([^ \\u00a0/])#)([${CJK}])`, "g"); var NAME_SUFFIX = `(?:(?<![A-Za-z0-9])(?:(?:Apple TV|CATCHPLAY|[Dd]iscovery|Disney|ESPN|Fitness|iCloud|mo ?店|Paramount|PS|Pro)\\+|(?:(?:tw)?(?:AA|BBB|BB|CCC)|tw[AB]|AB|RhD|Rh)[+-])|(?:公視|影劇館)\\+)`; var NAME_SUFFIX_AT_END = new RegExp(`${NAME_SUFFIX}$`); var CLOSING_AFTER_SUFFIX = /[/)\]}\uff09\u3011\u3015\u3009\u300b\u300d\u300f\uff0c\u3002\u3001\uff1b\uff1a\uff01\uff1f]/; var CJK_OPERATOR_ANS = new RegExp(`([${CJK}])([${OPERATORS}])([${AN}])`, "g"); var ANS_OPERATOR_CJK = new RegExp(`([${AN}${RIGHT_BRACKETS_BASIC}])([${OPERATORS}])(?<!${NAME_SUFFIX})([${CJK}])`, "g"); var PIPE_CJK_CONTACT = new RegExp(`[${CJK}]\\||\\|[${CJK}]`); var PIPE_SEPARATOR = /([^\s|])[ ]*(\|+)[ ]*(?=[^\s|])/g; var PLUS_CJK_CONTACT = new RegExp(`[${CJK}]\\+|\\+[${CJK}]`); var PLUS_SEPARATOR = /(?<=[^\s+\uff0c\u3002\uff1b\uff1a\uff01\uff1f\u3001\uff08\uff09\u300c\u300d\u300e\u300f\u3010\u3011\u300a\u300b])\+(?=[^\s+\uff0c\u3002\uff1b\uff1a\uff01\uff1f\u3001\uff08\uff09\u300c\u300d\u300e\u300f\u3010\u3011\u300a\u300b])/g; var RIGHT_BRACKET_PLUS_FULL_WIDTH_LEFT_BRACKET = new RegExp(`(?<=[${RIGHT_BRACKETS_BASIC}])\\+(?=[\\uff08\\u300c\\u300e\\u3010\\u300a])`, "g"); var SINGLE_LETTER_GRADE_CJK = new RegExp(`\\b([${A}])([${GRADE_OPERATORS}])([${CJK}])`, "g"); var CJK_SIGN_DIGIT = new RegExp(`([${CJK}])(\\+)([0-9])`, "g"); var CJK_HYPHEN_FLAG = new RegExp(`([${CJK}])(\\-)([a-z])\\b`, "g"); var DIGIT_PLUS_CJK = new RegExp(`\\b([0-9]+)(\\+)([${CJK}])`, "g"); var CJK_LESS_THAN = new RegExp(`([${CJK}])(<)([${AN}])`, "g"); var LESS_THAN_CJK = new RegExp(`([${AN}])(<)([${CJK}])`, "g"); var CJK_GREATER_THAN = new RegExp(`([${CJK}])(>)([${AN}])`, "g"); var GREATER_THAN_CJK = new RegExp(`([${AN}])(>)([${CJK}])`, "g"); var CJK_LEFT_BRACKET = new RegExp(`([${CJK}])([${LEFT_BRACKETS_EXTENDED}])`, "g"); var RIGHT_BRACKET_CJK = new RegExp(`([${RIGHT_BRACKETS_EXTENDED}])([${CJK}])`, "g"); var ANS_CJK_LEFT_BRACKET_ANY_RIGHT_BRACKET = new RegExp(`([${AN}${CJK}])[ ]*([\u201c])([${AN}${CJK}\\-_ ]+)([\u201d])`, "g"); var LEFT_BRACKET_ANY_RIGHT_BRACKET_ANS_CJK = new RegExp(`([\u201c])([${AN}${CJK}\\-_ ]+)([\u201d])[ ]*([${AN}${CJK}])`, "g"); var ANS_CJK_RIGHT_QUOTE_ANY_RIGHT_QUOTE = new RegExp(`([${AN}${CJK}])[ ]*(?<![\u201c][^\u201c\u201d\n]*)([\u201d])[ ]*([${AN}${CJK}\\-_ ]+?)[ ]*([\u201d])`, "g"); var AN_LEFT_BRACKET = new RegExp(`([${AN}])(?<!\\.[${AN}]*)([${LEFT_BRACKETS_BASIC}])`, "g"); var RIGHT_BRACKET_AN = new RegExp(`([${RIGHT_BRACKETS_BASIC}])([${AN}])`, "g"); var CJK_UNIX_ABSOLUTE_FILE_PATH = new RegExp(`([${CJK}])(${UNIX_ABSOLUTE_FILE_PATH.source})`, "g"); var CJK_UNIX_RELATIVE_FILE_PATH = new RegExp(`([${CJK}])(${UNIX_RELATIVE_FILE_PATH.source})`, "g"); var CJK_WINDOWS_PATH = new RegExp(`([${CJK}])(${WINDOWS_FILE_PATH.source})`, "g"); var UNIX_ABSOLUTE_FILE_PATH_SLASH_CJK = new RegExp(`(${UNIX_ABSOLUTE_FILE_PATH.source}/)([${CJK}])`, "g"); var UNIX_RELATIVE_FILE_PATH_SLASH_CJK = new RegExp(`(${UNIX_RELATIVE_FILE_PATH.source}/)([${CJK}])`, "g"); var CJK_ANS = new RegExp(`([${CJK}])(?![${SUPERSCRIPT_SUFFIXES}])([${ANS_CJK_AFTER}])(?<!${NAME_SUFFIX})`, "g"); var ANS_CJK = new RegExp(`([${ANS_BEFORE_CJK}])([${CJK}])`, "g"); var S_A = new RegExp(`(%)([${A}])`, "g"); var COPYRIGHT_DIGIT = /(\u00a9)([0-9])/g; var MIDDLE_DOT = /([ ]*)([\u00b7\u2022\u2027])([ ]*)/g; var VOID_HTML_TAGS = /* @__PURE__ */ new Set([ "area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr" ]); var BARE_HTML_TAG = /^<([a-zA-Z][a-zA-Z0-9]*)\s*\/?>$/; var CLOSING_HTML_TAG = /<\/([a-zA-Z][a-zA-Z0-9]*)/g; var CJK_HTML_TAG_MENTION = new RegExp(`([${CJK}])(?=\uE004)`, "g"); var HTML_TAG_MENTION_CJK = new RegExp(`(?<=\uE005)([${CJK}])`, "g"); var HTTP_URL = /(?<![A-Za-z0-9])https?:\/\/[^\s<>"`\u3000-\u303f\uff00-\uffef\u2018\u2019\u201c\u201d\u2026\ue000-\uf8ff]+/g; var HTTP_URL_TRAILING_PUNCTUATION = /[.,;:!?'"]+$/; var CJK_HTTP_URL = new RegExp(`([${CJK}])(?=\uE00A)`, "g"); function trimHttpUrl(url) { let unbalancedClosingParentheses = (url.match(/\)/g) ?? []).length - (url.match(/\(/g) ?? []).length; for (;;) { const trimmed = url.replace(HTTP_URL_TRAILING_PUNCTUATION, ""); if (trimmed.endsWith(")") && unbalancedClosingParentheses > 0) { unbalancedClosingParentheses--; url = trimmed.slice(0, -1); continue; } if (trimmed === url) return url; url = trimmed; } } var BRACKET_PATTERNS = [ { pattern: /<([^<>]*)>/g, open: "<", close: ">" }, { pattern: /\(([^()]*)\)/g, open: "(", close: ")" }, { pattern: /\[([^\[\]]*)\]/g, open: "[", close: "]" }, { pattern: /\{([^{}]*)\}/g, open: "{", close: "}" } ]; var PlaceholderReplacer = class PlaceholderReplacer { placeholder; startDelimiter; endDelimiter; static patternCache = /* @__PURE__ */ new Map(); items = []; index = 0; pattern; constructor(placeholder, startDelimiter, endDelimiter) { this.placeholder = placeholder; this.startDelimiter = startDelimiter; this.endDelimiter = endDelimiter; const cacheKey = `${startDelimiter}${placeholder}${endDelimiter}`; let pattern = PlaceholderReplacer.patternCache.get(cacheKey); if (!pattern) { const escapedStart = this.startDelimiter.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const escapedEnd = this.endDelimiter.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); pattern = new RegExp(`${escapedStart}${this.placeholder}(\\d+)${escapedEnd}`, "g"); PlaceholderReplacer.patternCache.set(cacheKey, pattern); } this.pattern = pattern; } store(item) { this.items[this.index] = item; return `${this.startDelimiter}${this.placeholder}${this.index++}${this.endDelimiter}`; } restore(text) { if (this.index === 0) return text; return text.replace(this.pattern, (_match, index) => { return this.items[parseInt(index, 10)] || ""; }); } }; var Pangu = class { version; constructor() { this.version = "10.2.0"; } spaceText(text) { if (typeof text !== "string") { console.warn(`[pangu] spaceText(text) only accepts string but got ${typeof text}`); return text; } if (text.length <= 1 || !ANY_CJK.test(text)) return text; let newText = text; const backtickManager = new PlaceholderReplacer("BACKTICK_CONTENT_", "", ""); newText = newText.replace(/`([^`]+)`/g, (_match, content) => { return `\`${backtickManager.store(content)}\``; }); const urlManager = new PlaceholderReplacer("HTTP_URL_PLACEHOLDER_", "", ""); newText = newText.replace(HTTP_URL, (match) => { const url = trimHttpUrl(match); return urlManager.store(url) + match.slice(url.length); }); const htmlTagManager = new PlaceholderReplacer("HTML_TAG_PLACEHOLDER_", "", ""); const mentionedTagManager = new PlaceholderReplacer("HTML_TAG_MENTION_", "", ""); let hasHtmlTags = false; if (newText.includes("<")) { hasHtmlTags = true; const HTML_TAG_PATTERN = /<\/?[a-zA-Z][a-zA-Z0-9]*(?:\s+[^>]*)?>/g; const closedTagNames = /* @__PURE__ */ new Set(); for (const closingTag of newText.matchAll(CLOSING_HTML_TAG)) closedTagNames.add(closingTag[1].toLowerCase()); newText = newText.replace(HTML_TAG_PATTERN, (match) => { const bareTag = match.match(BARE_HTML_TAG); if (bareTag) { const tagName = bareTag[1].toLowerCase(); if (!VOID_HTML_TAGS.has(tagName) && !closedTagNames.has(tagName)) return mentionedTagManager.store(match); } const processedTag = match.replace(/(\w+)="([^"]*)"/g, (_attrMatch, attrName, attrValue) => { return `${attrName}="${this.spaceText(attrValue)}"`; }); return htmlTagManager.store(processedTag); }); } newText = newText.replace(DOTS_CJK, "$1 $2"); newText = newText.replace(CJK_PUNCTUATION, "$1$2 "); newText = newText.replace(PUNCTUATION_CJK, "$1 "); newText = newText.replace(CJK_TILDE, "$1$2 "); newText = newText.replace(CJK_TILDE_EQUALS, "$1 $2 "); newText = newText.replace(CJK_PERIOD, "$1$2 "); newText = newText.replace(AN_PERIOD_CJK, "$1$2 $3"); newText = newText.replace(AN_COLON_CJK, "$1$2 $3"); newText = newText.replace(FIX_CJK_COLON_ANS, "$1:$2"); newText = newText.replace(CJK_QUOTE, "$1 $2"); newText = newText.replace(QUOTE_CJK, "$1 $2"); newText = newText.replace(FIX_QUOTE_ANY_QUOTE, "$1$2$3"); newText = newText.replace(QUOTE_AN, "$1 $2"); newText = newText.replace(CJK_QUOTE_AN, "$1$2 $3"); newText = newText.replace(FIX_POSSESSIVE_SINGLE_QUOTE, "$1's"); const singleQuoteCJKManager = new PlaceholderReplacer("SINGLE_QUOTE_CJK_PLACEHOLDER_", "", ""); newText = newText.replace(SINGLE_QUOTE_PURE_CJK, (match) => { return singleQuoteCJKManager.store(match); }); newText = newText.replace(CJK_SINGLE_QUOTE_BUT_POSSESSIVE, "$1 $2"); newText = newText.replace(SINGLE_QUOTE_CJK, "$1 $2"); newText = singleQuoteCJKManager.restore(newText); if (newText.length >= 5) newText = newText.replace(HASH_ANS_CJK_HASH, "$1 $2$3$4 $5"); newText = newText.replace(CJK_HASH, "$1 $2"); newText = newText.replace(HASH_CJK, "$1 $3"); const compoundWordManager = new PlaceholderReplacer("COMPOUND_WORD_PLACEHOLDER_", "", ""); newText = newText.replace(/\b(?:[A-Za-z0-9]*[a-z][A-Za-z0-9]*-[A-Za-z0-9]+|[A-Za-z0-9]+-[A-Za-z0-9]*[a-z][A-Za-z0-9]*|[A-Za-z]+-[0-9]+|[A-Za-z]+[0-9]+-[A-Za-z0-9]+)(?:-[A-Za-z0-9]+)*\b/g, (match) => { return compoundWordManager.store(match); }); newText = newText.replace(SINGLE_LETTER_GRADE_CJK, "$1$2 $3"); newText = newText.replace(CJK_SIGN_DIGIT, "$1 $2$3"); newText = newText.replace(CJK_HYPHEN_FLAG, "$1 $2$3"); newText = newText.replace(DIGIT_PLUS_CJK, "$1$2 $3"); newText = newText.split("\n").map((line) => { return (PLUS_CJK_CONTACT.test(line) ? line.replace(PLUS_SEPARATOR, (_match, offset) => { if (!NAME_SUFFIX_AT_END.test(compoundWordManager.restore(line.slice(0, offset + 1)))) return " + "; return CLOSING_AFTER_SUFFIX.test(line[offset + 1] ?? "") ? "+" : "+ "; }) : line).replace(RIGHT_BRACKET_PLUS_FULL_WIDTH_LEFT_BRACKET, " +"); }).join("\n"); newText = newText.replace(CJK_OPERATOR_ANS, "$1 $2 $3"); newText = newText.replace(ANS_OPERATOR_CJK, "$1 $2 $3"); newText = newText.replace(CJK_LESS_THAN, "$1 $2 $3"); newText = newText.replace(LESS_THAN_CJK, "$1 $2 $3"); newText = newText.replace(CJK_GREATER_THAN, "$1 $2 $3"); newText = newText.replace(GREATER_THAN_CJK, "$1 $2 $3"); newText = newText.replace(CJK_UNIX_ABSOLUTE_FILE_PATH, "$1 $2"); newText = newText.replace(CJK_UNIX_RELATIVE_FILE_PATH, "$1 $2"); newText = newText.replace(CJK_WINDOWS_PATH, "$1 $2"); newText = newText.replace(UNIX_ABSOLUTE_FILE_PATH_SLASH_CJK, "$1 $2"); newText = newText.replace(UNIX_RELATIVE_FILE_PATH_SLASH_CJK, "$1 $2"); newText = newText.split("\n").map((line) => { if (!PIPE_CJK_CONTACT.test(line)) return line; return line.replace(PIPE_SEPARATOR, "$1 $2 "); }).join("\n"); newText = newText.replace(FIX_QUOTE_ANY_QUOTE, "$1$2$3"); newText = compoundWordManager.restore(newText); newText = newText.replace(CJK_LEFT_BRACKET, "$1 $2"); newText = newText.replace(RIGHT_BRACKET_CJK, "$1 $2"); newText = newText.replace(ANS_CJK_LEFT_BRACKET_ANY_RIGHT_BRACKET, "$1 $2$3$4"); newText = newText.replace(LEFT_BRACKET_ANY_RIGHT_BRACKET_ANS_CJK, "$1$2$3 $4"); newText = newText.replace(ANS_CJK_RIGHT_QUOTE_ANY_RIGHT_QUOTE, "$1 $2$3$4"); newText = newText.replace(AN_LEFT_BRACKET, "$1 $2"); newText = newText.replace(RIGHT_BRACKET_AN, "$1 $2"); newText = newText.replace(CJK_ANS, "$1 $2"); newText = newText.replace(ANS_CJK, "$1 $2"); newText = newText.replace(S_A, "$1 $2"); newText = newText.replace(COPYRIGHT_DIGIT, "$1 $2"); newText = newText.replace(MIDDLE_DOT, "・"); newText = this.fixBracketSpacing(newText); if (hasHtmlTags) { newText = newText.replace(CJK_HTML_TAG_MENTION, "$1 "); newText = newText.replace(HTML_TAG_MENTION_CJK, " $1"); newText = mentionedTagManager.restore(newText); newText = htmlTagManager.restore(newText); } newText = newText.replace(CJK_HTTP_URL, "$1 "); newText = urlManager.restore(newText); newText = backtickManager.restore(newText); return newText; } hasProperSpacing(text) { return this.spaceText(text) === text; } fixBracketSpacing(text) { for (const { pattern, open, close } of BRACKET_PATTERNS) text = text.replace(pattern, (_match, innerContent) => { if (!innerContent) return `${open}${close}`; const trimmedContent = innerContent.replace(/^ +| +$/g, ""); return `${open}${trimmedContent}${close}`; }); return text; } }; new Pangu(); //#endregion //#region src/node/index.ts var NodePangu = class extends Pangu { async spaceFile(path) { const data = await readFile(path, "utf8"); return this.spaceText(data); } spaceFileSync(path) { return this.spaceText(readFileSync(path, "utf8")); } }; var pangu = new NodePangu(); //#endregion //#region src/node/cli.ts var usage = ` usage: pangu [-h] [-v] [-t | -f | -c] [text_or_path] pangu.js v${pangu.version} -- Paranoid text spacing for good readability, to automatically insert whitespace between CJK and half-width characters (alphabetical letters, numerical digits and symbols). positional arguments: text_or_path the text or file path to apply spacing; omit it to read stdin when input is piped optional arguments: -h, --help show this help message and exit -v, --version show program's version number and exit -t, --text specify the input value is a text -f, --file specify the input value is a file path (pass - to read from stdin) -c, --check check if text has proper spacing (exit 0 if yes, 1 if no) `.trim(); var [, , ...args] = process.argv; var modeFlags = { "-t": "--text", "--text": "--text", "-f": "--file", "--file": "--file", "-c": "--check", "--check": "--check" }; function wantsStdin(arg) { return arg === "-" || arg === void 0 && !process.stdin.isTTY; } async function readStdin() { return (await text(process.stdin)).replace(/\n$/, ""); } function spaceTextPrinted(text) { if (typeof text === "string") console.log(pangu.spaceText(text)); else { console.log(usage); process.exitCode = 1; } } function spaceFilePrinted(path) { if (path) process.stdout.write(pangu.spaceFileSync(path)); else { console.error("pangu: error: argument --file: expected a file path"); console.log(usage); process.exitCode = 1; } } function checkSpacing(text) { if (typeof text === "string") { const hasProperSpacing = pangu.hasProperSpacing(text); if (!hasProperSpacing) console.error(`Corrected: ${pangu.spaceText(text)}`); process.exitCode = hasProperSpacing ? 0 : 1; } else { console.log(usage); process.exitCode = 1; } } async function main() { const givenModes = new Set(args.filter((arg) => arg in modeFlags).map((flag) => modeFlags[flag])); if (givenModes.size > 1) { const [first, second] = [...givenModes]; console.error(`pangu: error: argument ${second}: not allowed with argument ${first}`); console.log(usage); process.exitCode = 1; return; } if (args.length === 0) { spaceTextPrinted(wantsStdin(void 0) ? await readStdin() : void 0); return; } switch (args[0]) { case "-h": case "--help": console.log(usage); break; case "-v": case "--version": console.log(`pangu.js ${pangu.version}`); break; case "-t": case "--text": spaceTextPrinted(wantsStdin(args[1]) ? await readStdin() : args[1]); break; case "-f": case "--file": if (args[1] === "-") spaceTextPrinted(await readStdin()); else spaceFilePrinted(args[1]); break; case "-c": case "--check": checkSpacing(wantsStdin(args[1]) ? await readStdin() : args[1]); break; case "-": spaceTextPrinted(await readStdin()); break; default: spaceTextPrinted(args[0]); } } await main(); //#endregion //# sourceMappingURL=cli.js.map