| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 |
1x
1x
1x
1x
1x
1x
1x
30x
30x
30x
30x
30x
30x
30x
30x
30x
30x
26x
26x
20x
49x
25x
25x
24x
24x
49x
20x
1x
2x
30x
4x
4x
4x
4x
1x
3x
4x
3x
2x
| /**
* @module libs/sys/xlog
* @createdAt 2016-07-15
*
* @copyright Copyright (c) 2016 Zhonglei Qiu
* @license Licensed under the MIT license.
*/
var util = require('util')
var extend = require('./extendFormat')
var clog = require('./clog')
var cliTextSize = require('../tty/cliTextSize')
/**
* 输出带样式的字符串,拥有 {@link module:libs/sys/clog} 的所有功能
*
* FORMAT | EXPLAIN
* --------|-----------
* %d | 格式化成整数,使用了 parseInt
* %\d*f | 格式化成浮点数,使用了 parseFloat,中间的数字表示保存的小数位数
* %j, %o | 格式化成对象,使用了原生的 util.format('%j', val)
* %c | 格式化成颜色,使用了 {@link module:libs/sys/clog.format}
* %...s | 格式化字符串,支持对齐,参数复杂,用 ... 表示省略,说情参看 {@link module:libs/sys/xlog.align}
*
* @param {String} template 模板
* @param {...*} [arg] 模板的参数
* @param {String} [template] 第二个模板,后面可以继续接 ...arg, template, ...arg, ...
*
* @example
* xlog('price %2f$', 100) => 'price 100.00$'
*
* xlog('%5:<.>s', 'a') => '<<a>>'
* xlog('%5:<.>s', 'abc') => '<abc>'
*
* @method
* @author Zhonglei Qiu
* @since 2.0.0
*/
module.exports = xlog
exports = module.exports
/**
* 对齐 str 字符串
*
* @type {Function}
* @param {String} str 要对齐的字符串
* @param {String} format 对齐规则,规则如下
*
* EXAMPLE | EXPLAIN
* -----------|----------------
* 3 | 至少有3个字符,没有的话在左边补【默认字符】
* .3 | 至少有3个字符,没有的话在右边补【默认字符】
* 1.2 | 至少3个字符,不足的话左右两边填充【默认字符】,先填左,再填右,再填右
* 1.2:_ | 至少3个字符,没有的话在左边补 _,在右边补【默认字符】
* 1.2:.0 | 至少3个字符,没有的话在左边补【默认字符】,在右边补 0
* 1.2:_.0 | 至少3个字符,没有的话在左边补 _,在右边补 0
*
* @param {Object} opts 配置选项
* @param {String} [opts.leftPad=" "] 左侧填充的【默认字符】
* @param {String} [opts.rightPad=" "] 右侧填充的【默认字符】
*
* @return {String} 对齐后的 str
*/
exports.align = function(str, format, opts) {
opts = opts || {}
var lLen, rLen, lPad, rPad, i, diff
var flag = true
var parts = format.split(':')
var lens = parts.shift().split('.')
var pads = parts.join(':').split('.')
lLen = parseInt(lens[0] || '0', 10)
rLen = parseInt(lens[1] || '0', 10)
lPad = pads[0] || opts.leftPad || ' '
rPad = pads[1] || opts.rightPad || ' '
if (lLen === 0 && rLen === 0) return str
diff = lLen + rLen - cliTextSize(str)
if (diff <= 0) return str
for (i = 0; i < diff; i++) {
if ((flag || rLen === 0) && lLen > 0) {
str = lPad + str
lLen--
} else {
str += rPad
rLen--
}
flag = !flag
}
return str
}
/**
* {@link module:libs/sys/xlog} 使用的 format 函数,类似于 console.log 使用了 util.format 函数
*
* @method
* @return {String} 格式化后的字符串
*/
exports.format = extend([
clog.colorMatcher,
{
match: /%[jo]/,
order: 1,
handle: function(val) {
return util.format('%j', val)
}
},
{
match: /%(?:\d+)?\.?(?:\d+)?(?::.\.?.?)?s/,
order: 1,
handle: function(val, format) {
return exports.align(String(val), format.slice(1, -1))
}
},
{
match: /%d/,
order: 2,
handle: function(val) {
return parseInt(val, 10)
}
},
{
match: /%\d*f/,
order: 2,
handle: function(val, format) {
var fixed = parseInt(format.substr(1), 10)
val = parseFloat(val)
return fixed ? val.toFixed(fixed) : val.toString()
}
}
]);
// @FIXME 这些字段无法生成 jsdoc
['autoResetAtEnd', 'autoResetAtGroupEnd', 'NAMED_COLORS'].forEach(function(k) {
Object.defineProperty(xlog, k, {
enumerable: true,
configurable: true,
set: function(val) { clog[k] = val },
get: function() { return clog[k] }
})
})
function xlog() {
console.log(exports.format.apply(null, arguments))
}
|