|
1
|
|
|
"use strict"; |
|
2
|
|
|
|
|
3
|
|
|
const ansiEscapeCode = '[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]' |
|
4
|
|
|
, zeroWidthCharacterExceptNewline = '\u0000-\u0008\u000B-\u0019\u001b\u009b\u00ad\u200b\u2028\u2029\ufeff' |
|
5
|
|
|
, zeroWidthCharacter = '\n' + zeroWidthCharacterExceptNewline |
|
6
|
|
|
, zeroWidthCharactersExceptNewline = new RegExp ('(?:' + ansiEscapeCode + ')|[' + zeroWidthCharacterExceptNewline + ']', 'g') |
|
7
|
|
|
, zeroWidthCharacters = new RegExp ('(?:' + ansiEscapeCode + ')|[' + zeroWidthCharacter + ']', 'g') |
|
8
|
|
|
, partition = new RegExp ('((?:' + ansiEscapeCode + ')|[\t' + zeroWidthCharacter + '])?([^\t' + zeroWidthCharacter + ']*)', 'g') |
|
9
|
|
|
|
|
10
|
|
|
module.exports = { |
|
11
|
|
|
|
|
12
|
|
|
zeroWidthCharacters, |
|
13
|
|
|
|
|
14
|
|
|
ansiEscapeCodes: new RegExp (ansiEscapeCode, 'g'), |
|
15
|
|
|
|
|
16
|
|
|
strlen: s => s.replace (zeroWidthCharacters, '') |
|
17
|
|
|
.length, |
|
18
|
|
|
|
|
19
|
|
|
isBlank: s => s.replace (zeroWidthCharacters, '') |
|
20
|
|
|
.replace (/\s/g, '') |
|
21
|
|
|
.length === 0, |
|
22
|
|
|
|
|
23
|
|
|
blank: s => s.replace (zeroWidthCharactersExceptNewline, '') |
|
24
|
|
|
.replace (/[^\t\n]/g, ' '), |
|
25
|
|
|
|
|
26
|
|
|
partition (s) { |
|
27
|
|
|
for (var m, spans = []; (partition.lastIndex !== s.length) && (m = partition.exec (s));) { spans.push ([m[1] || '', m[2]]) } |
|
28
|
|
|
partition.lastIndex = 0 // reset |
|
29
|
|
|
return spans |
|
30
|
|
|
}, |
|
31
|
|
|
|
|
32
|
|
|
first (s, n) { |
|
33
|
|
|
|
|
34
|
|
|
let result = '', length = 0 |
|
35
|
|
|
|
|
36
|
|
|
for (const [nonPrintable, printable] of module.exports.partition (s)) { |
|
37
|
|
|
const text = printable.substr (0, n - length) |
|
38
|
|
|
result += nonPrintable + text |
|
39
|
|
|
length += text.length |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
return result |
|
43
|
|
|
} |
|
44
|
|
|
} |