UNPKG

chinese-numbering

Version:
159 lines (136 loc) 4.42 kB
const DEFAULT_OPTIONS = Object.freeze({ chineseType: "simplified", keepOne: false }); function normalizeChineseType(type) { switch (type) { case "s": return "simplified"; case "t": return "traditional"; default: return type; } } function normalizeOptions(opts) { if (typeof opts === "boolean") { return { chineseType: opts ? "traditional" : "simplified", keepOne: DEFAULT_OPTIONS.keepOne }; } else if (typeof opts === "string") { return { chineseType: normalizeChineseType(opts), keepOne: DEFAULT_OPTIONS.keepOne }; } else if (typeof opts === "object" && opts !== null) { return { chineseType: typeof opts.chineseType === "string" ? normalizeChineseType(opts.chineseType) : DEFAULT_OPTIONS.chineseType, keepOne: typeof opts.keepOne === "undefined" ? DEFAULT_OPTIONS.keepOne : !!opts.keepOne }; } else { return DEFAULT_OPTIONS; } } const labels = { digits: ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"], units: ["", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千", "兆", "十", "百", "千", "京", "十", "百", "千", "垓"], ordinal: "第", point: "点", minus: "负" }; const labels$1 = { digits: ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"], units: ["", "十", "百", "千", "萬", "十", "百", "千", "億", "十", "百", "千", "兆", "十", "百", "千", "京", "十", "百", "千", "垓"], ordinal: "第", point: "點", minus: "負" }; var labels$2 = /*#__PURE__*/Object.freeze({ __proto__: null, simplified: labels, traditional: labels$1 }); function getLabels(opts) { return labels$2[opts.chineseType]; } const regexps = new WeakMap(); function getRegexps(labels) { const r = regexps.get(labels); if (r) { return r; } const { digits, units } = labels; const smallUnit = units[1] + units[2] + units[3]; const bigUnit = units[4] + units[8] + units[12] + units[16] + units[20]; const zero = digits[0]; const v = { // 零千,零百,零十 keeps 零 onlyZero: [new RegExp(`(${zero})[${smallUnit}]`, "g"), "$1"], //大數中間沒細數,補零 zeroBetweenBigUnits: [new RegExp(`([${bigUnit}])[^${smallUnit}]+([${bigUnit}])`, "g"), "$1" + zero], zeroBetweenSmallAndBigUnits: [new RegExp(`([${smallUnit}])${zero}+([${bigUnit}])`, "g"), "$1$2" + zero], //group 零 groupZero: [new RegExp(`(${digits[0]})+`, "g"), "$1"], // remove tail zero removeTailZero: [new RegExp(zero + "+$"), ""], // 一十 => 十 removeOne: [new RegExp(`^${digits[1]}${units[1]}`), units[1]] }; regexps.set(labels, v); return v; } function parseIntPart(num, labels, keepOne) { const { digits, units, minus } = labels; const regexps = getRegexps(labels); let n = Math.floor(Math.abs(num)); // 0 if (n < 1) return (num < 0 ? minus : "") + digits[0]; let str = ""; let unitIndex = 0; while (n > 0) { str = digits[n % 10] + units[unitIndex] + str; n = Math.floor(n / 10); unitIndex++; } str = str.replace(...regexps.onlyZero).replace(...regexps.zeroBetweenBigUnits).replace(...regexps.zeroBetweenSmallAndBigUnits).replace(...regexps.groupZero).replace(...regexps.removeTailZero); if (keepOne != true) { str = str.replace(...regexps.removeOne); } return (num < 0 ? minus : "") + str; } function parseFloatPart(num, labels) { if (num % 1 === 0) return ""; num = Math.abs(num); const { digits, point } = labels; let numStr = num.toString(); numStr = numStr.slice(numStr.indexOf(".") + 1); let str = ""; for (const d of numStr) { str = str + digits[parseInt(d)]; } return point + str; } function numberToChinese(num, options) { const opts = normalizeOptions(options); const labels = getLabels(opts); return parseIntPart(num, labels, opts.keepOne) + parseFloatPart(num, labels); } function numberToChineseOrdinalWithArabic(num, options) { return getLabels(normalizeOptions(options)).ordinal + num.toString(10); } function numberToChineseOrdinal(num, options) { const opts = normalizeOptions(options); return getLabels(opts).ordinal + numberToChinese(num, opts); } export { normalizeChineseType, normalizeOptions, numberToChinese, numberToChineseOrdinal, numberToChineseOrdinalWithArabic }; //# sourceMappingURL=es.js.map