UNPKG

mora-scripts

Version:
79 lines (68 loc) 8.04 kB
/** * @module libs/tty/cliTextSize * @createdAt 2016-07-17 * * @copyright Copyright (c) 2016 Zhonglei Qiu * @license Licensed under the MIT license. * * 可以参考: eastasianwidth string-width */ var stripAnsi = require('./stripAnsi') var isWin = require('../sys/isWin') var ucs2decode = require('./_helper').ucs2decode // Window 对不支持的字符都使用了默认的占一个位置的字符替代 // 中国的 window 用户大多是 cp936 编码 (但是最近听说 window 也将支持 Linux shell) /* eslint-disable */ var sizeRangesMap = {"0":[[0,7],[11,31],[768,879],[1155,1161],[1425,1469],[1471],[1473,1474],[1476,1477],[1479],[1552,1562],[1611,1631],[1648],[1750,1756],[1759,1764],[1767,1768],[1770,1773],[1809],[1840,1866],[1958,1968],[2027,2035],[2070,2073],[2075,2083],[2085,2087],[2089,2093],[2137,2139],[2304,2307],[2362,2364],[2366,2383],[2385,2391],[2402,2403],[2433,2435],[2492],[2494,2500],[2503,2504],[2507,2509],[2519],[2530,2531],[2561,2563],[2620],[2622,2626],[2631,2632],[2635,2637],[2641],[2672,2673],[2677],[2689,2691],[2748],[2750,2757],[2759,2761],[2763,2765],[2786,2787],[2817,2819],[2876],[2878,2884],[2887,2888],[2891,2893],[2902,2903],[2914,2915],[2946],[3006,3010],[3014,3016],[3018,3021],[3031],[3073,3075],[3134,3140],[3142,3144],[3146,3149],[3157,3158],[3170,3171],[3202,3203],[3260],[3262,3268],[3270,3272],[3274,3277],[3285,3286],[3298,3299],[3330,3331],[3390,3396],[3398,3400],[3402,3405],[3415],[3426,3427],[3458,3459],[3530],[3535,3540],[3542],[3544,3551],[3570,3571],[3633],[3636,3642],[3655,3662],[3761],[3764,3769],[3771,3772],[3784,3789],[3864,3865],[3893],[3895],[3897],[3902,3903],[3953,3972],[3974,3975],[3981,3991],[3993,4028],[4038],[4139,4158],[4182,4185],[4190,4192],[4194,4196],[4199,4205],[4209,4212],[4226,4237],[4239],[4250,4253],[4957,4959],[5906,5908],[5938,5940],[5970,5971],[6002,6003],[6070,6099],[6109],[6155,6157],[6313],[6432,6443],[6448,6459],[6576,6592],[6600,6601],[6679,6683],[6741,6750],[6752,6780],[6783],[6912,6916],[6964,6980],[7019,7027],[7040,7042],[7073,7082],[7142,7155],[7204,7223],[7376,7378],[7380,7400],[7405],[7410],[7616,7654],[7676,7679],[8203,8205],[8400,8432],[11503,11505],[11647],[11744,11775],[12330,12335],[12441,12442],[42607,42610],[42620,42621],[42736,42737],[43010],[43014],[43019],[43043,43047],[43136,43137],[43188,43204],[43232,43249],[43302,43309],[43335,43347],[43392,43395],[43443,43456],[43561,43574],[43587],[43596,43597],[43643],[43696],[43698,43700],[43703,43704],[43710,43711],[43713],[44003,44010],[44012,44013],[64286],[65024,65039],[65056,65062],[65279]],"2":[[4352,4447],[4515,4519],[4602,4607],[9001,9002],[11904,11929],[11931,12019],[12032,12245],[12272,12283],[12288,12329],[12336,12350],[12353,12438],[12443,12543],[12549,12589],[12593,12686],[12688,12730],[12736,12771],[12784,12830],[12832,12871],[12880,13054],[13056,19903],[19968,42124],[42128,42182],[43360,43388],[44032,55203],[55216,55238],[55243,55291],[63744,64255],[65040,65049],[65072,65106],[65108,65126],[65128,65131],[65281,65376],[65504,65510],[110592,110593],[119134,119135],[119227,119228],[127488,127490],[127504,127546],[127552,127560],[127568,127569],[131072,196605],[196608,262141]],"3":[[119136,119140],[119229,119232]]} var ambRanges = [[161],[164],[167,168],[170],[173,174],[176,180],[182,186],[188,191],[198],[208],[215,216],[222,225],[230],[232,234],[236,237],[240],[242,243],[247,250],[252],[254],[257],[273],[275],[283],[294,295],[299],[305,307],[312],[319,322],[324],[328,331],[333],[338,339],[358,359],[363],[462],[464],[466],[468],[470],[472],[474],[476],[593],[609],[708],[711],[713,715],[717],[720],[728,731],[733],[735],[903],[913,929],[931,937],[945,961],[963,969],[1025],[1040,1103],[1105],[8126],[8189],[8208],[8211,8214],[8216,8217],[8220,8221],[8224,8226],[8228,8231],[8240],[8242,8243],[8245],[8251],[8254],[8308],[8319],[8321,8324],[8364],[8451],[8453],[8457],[8467],[8470],[8481,8482],[8486],[8531,8532],[8539,8542],[8544,8555],[8560,8569],[8585],[8592,8601],[8632,8633],[8658],[8660],[8679],[8704],[8706,8707],[8711,8712],[8715],[8719],[8721],[8725],[8730],[8733,8736],[8739],[8741],[8743,8748],[8750],[8756,8759],[8764,8765],[8776],[8780],[8786],[8800,8801],[8804,8807],[8810,8811],[8814,8815],[8834,8835],[8838,8839],[8853],[8857],[8869],[8895],[8978],[9312,9449],[9451,9547],[9552,9587],[9600,9615],[9618,9621],[9632,9633],[9635,9641],[9650,9651],[9654,9655],[9660,9661],[9664,9665],[9670,9672],[9675],[9678,9681],[9698,9701],[9711],[9733,9734],[9737],[9742,9743],[9748,9749],[9756],[9758],[9792],[9794],[9824,9825],[9827,9829],[9831,9834],[9836,9837],[9839],[9886,9887],[9918,9919],[9924,9933],[9935,9953],[9955],[9960,9983],[10045],[10071],[10102,10111],[11093,11097],[12872,12879],[55296,61439],[61444,63743],[65533],[127232,127242],[127248,127277],[127280,127337],[127344,127386],[917760,917999],[983040,1048573],[1048576,1114109]] var cp936Ranges = [[0,127],[164],[167,168],[176,177],[183],[215],[224,225],[232,234],[236,237],[242,243],[247],[249,250],[252],[257],[275],[283],[299],[324],[328],[333],[363],[462],[464],[466],[468],[470],[472],[474],[476],[593],[609],[711],[713,715],[729],[913,929],[931,937],[945,961],[963,969],[1025],[1040,1103],[1105],[8208],[8211,8214],[8216,8217],[8220,8221],[8229,8230],[8240],[8242,8243],[8245],[8251],[8364],[8451],[8453],[8457],[8470],[8481],[8544,8555],[8560,8569],[8592,8595],[8598,8601],[8712],[8719],[8721],[8725],[8730],[8733,8736],[8739],[8741],[8743,8747],[8750],[8756,8759],[8765],[8776],[8780],[8786],[8800,8801],[8804,8807],[8814,8815],[8853],[8857],[8869],[8895],[8978],[9312,9321],[9332,9371],[9472,9547],[9552,9587],[9601,9615],[9619,9621],[9632,9633],[9650,9651],[9660,9661],[9670,9671],[9675],[9678,9679],[9698,9701],[9733,9734],[9737],[9792],[9794],[12288,12291],[12293,12311],[12317,12318],[12321,12329],[12353,12435],[12443,12446],[12449,12534],[12540,12542],[12549,12585],[12832,12841],[12849],[12963],[13198,13199],[13212,13214],[13217],[13252],[13262],[13265,13266],[13269],[19968,40869],[63788],[63865],[63893],[63975],[63985],[64012,64015],[64017],[64019,64020],[64024],[64031,64033],[64035,64036],[64039,64041],[65072,65073],[65075,65092],[65097,65106],[65108,65111],[65113,65126],[65128,65131],[65281,65374],[65504,65509]] /* eslint-enable */ var sizes = Object.keys(sizeRangesMap).map(function(s) { return parseInt(s, 10) }) /** * 计算 Unicode 字符串在终端上的长度 * * @param {String} str 将会显示在终端上的字符串 * @return {Number} * * @example * cliTextSize('中国') // => 4 * cliTextSize('ab') // => 2 * * @see [tty-text-size@1.0.0]{@link https://github.com/qiu8310/tty-text-size/tree/1.0.0} * @throws {Error} 当包含 \t, \r, \v, \f, \n 这些无法计算长度的字符时 * * @since 2.0.0 * @author Zhonglei Qiu */ module.exports = function(str) { str = stripAnsi(str) return ucs2decode(str).reduce(function(size, cp) { return size + getCodePointCliSize(cp) }, 0) } function getCodePointCliSize(cp) { // 特殊字符无法知道它的 size if ([9, 10, 11, 12, 13].indexOf(cp) >= 0) { // throw new Error('Code point ' + cp + ' not allowed, its size is not predictable.') return cp === 9 ? 6 : 0 // tab Mac iTerm 上占了 6 个字符 } // window 对不支持的字符都使用了默认的占一个位置的字符替代 if (isWin && !inRanges(cp, cp936Ranges)) return 1 // Linux 很多终端此值都是 1,但用户可以修改,但程序不好获取用户修改的值 // 所以取默认值 if (inRanges(cp, ambRanges)) return isWin ? 2 : 1 for (var i = 0; i < sizes.length; i++) { // console.log(cp, sizeRangesMap[sizes[i]], inRanges(cp, sizeRangesMap[sizes[i]])) if (inRanges(cp, sizeRangesMap[sizes[i]])) { // window 不会超过 2 个字符 return isWin ? Math.min(2, sizes[i]) : sizes[i] } } return 1 } function inRanges(cp, ranges) { return ranges.some(function(range) { if (range.length === 1) return cp === range[0] return cp >= range[0] && cp <= range[1] }) }