chinese-numbering
Version:
format numbers as chinese words
170 lines (144 loc) • 5.22 kB
JavaScript
var ChineseNumbering = (function (exports) {
'use strict';
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);
}
exports.normalizeChineseType = normalizeChineseType;
exports.normalizeOptions = normalizeOptions;
exports.numberToChinese = numberToChinese;
exports.numberToChineseOrdinal = numberToChineseOrdinal;
exports.numberToChineseOrdinalWithArabic = numberToChineseOrdinalWithArabic;
return exports;
}({}));
//# sourceMappingURL=iife.js.map