@peteanderson/ansi 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/ansi.d.ts +2 -0
- package/dist/ansi.js +45 -0
- package/package.json +1 -1
- package/src/ansi.js +54 -0
package/README.md
CHANGED
|
@@ -16,7 +16,8 @@ const ansi = require("@peteanderson/ansi");
|
|
|
16
16
|
console.log(ansi.fg.red + "error: something went wrong" + ansi.fg.default);
|
|
17
17
|
console.log(ansi.bg.blue + ansi.fg.white + "highlighted" + ansi.fg.default + ansi.bg.default);
|
|
18
18
|
console.log(ansi.erase.screen);
|
|
19
|
-
console.log(ansi.
|
|
19
|
+
console.log(ansi.slice(coloredText, 0, 10)); // slice by visible characters
|
|
20
|
+
console.log(ansi.strip(coloredText)); // remove ANSI codes
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
## API
|
|
@@ -55,6 +56,11 @@ Raw sequences:
|
|
|
55
56
|
|
|
56
57
|
Removes ANSI CSI sequences from a string.
|
|
57
58
|
|
|
59
|
+
### `slice(text, start, end)`
|
|
60
|
+
|
|
61
|
+
Slices a string by visible characters, ignoring ANSI sequences. Works like `String.prototype.slice`
|
|
62
|
+
but counts only visible characters.
|
|
63
|
+
|
|
58
64
|
## License
|
|
59
65
|
|
|
60
66
|
MIT
|
package/dist/ansi.d.ts
CHANGED
package/dist/ansi.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const rxCSI = /\x1b\[[0-?]*[ -/]*[@-~]/g;
|
|
2
3
|
/** @type {(r: number, g: number, b: number, code: number) => string} */
|
|
3
4
|
function rgb(r, g, b, code) {
|
|
4
5
|
if (r === g && g === b) {
|
|
@@ -71,5 +72,49 @@ const ansi = {
|
|
|
71
72
|
scrollUp: lines => `\x1b[${lines}S`,
|
|
72
73
|
/** @type {(lines: number) => string} */
|
|
73
74
|
scrollDown: lines => `\x1b[${lines}T`,
|
|
75
|
+
/** @type {(text: string) => string} */
|
|
76
|
+
strip: text => text.replace(rxCSI, ''),
|
|
77
|
+
/** @type {(text: string, start: number, end: number) => string} */
|
|
78
|
+
slice(text, start, end) {
|
|
79
|
+
if (start < 0 || end < 0) {
|
|
80
|
+
const visibleLength = ansi.strip(text).length;
|
|
81
|
+
if (start < 0)
|
|
82
|
+
start = Math.max(0, visibleLength + start);
|
|
83
|
+
if (end < 0)
|
|
84
|
+
end = Math.max(0, visibleLength + end);
|
|
85
|
+
}
|
|
86
|
+
if (start > end)
|
|
87
|
+
return "";
|
|
88
|
+
let visibleIndex = 0;
|
|
89
|
+
let startIndex = 0;
|
|
90
|
+
while (startIndex < text.length && visibleIndex < start) {
|
|
91
|
+
if (text[startIndex] === "\x1b") {
|
|
92
|
+
rxCSI.lastIndex = startIndex;
|
|
93
|
+
const match = rxCSI.exec(text);
|
|
94
|
+
if (match?.index === startIndex) {
|
|
95
|
+
startIndex += match[0].length;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
startIndex++;
|
|
100
|
+
visibleIndex++;
|
|
101
|
+
}
|
|
102
|
+
let endIndex = startIndex;
|
|
103
|
+
let hasAnsi = false;
|
|
104
|
+
while (endIndex < text.length && visibleIndex < end) {
|
|
105
|
+
if (text[endIndex] === "\x1b") {
|
|
106
|
+
rxCSI.lastIndex = endIndex;
|
|
107
|
+
const match = rxCSI.exec(text);
|
|
108
|
+
if (match?.index === endIndex) {
|
|
109
|
+
endIndex += match[0].length;
|
|
110
|
+
hasAnsi = true;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
endIndex++;
|
|
115
|
+
visibleIndex++;
|
|
116
|
+
}
|
|
117
|
+
return text.slice(startIndex, endIndex) + (hasAnsi ? ansi.reset : "");
|
|
118
|
+
},
|
|
74
119
|
};
|
|
75
120
|
module.exports = ansi;
|
package/package.json
CHANGED
package/src/ansi.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const rxCSI = /\x1b\[[0-?]*[ -/]*[@-~]/g;
|
|
4
|
+
|
|
3
5
|
/** @type {(r: number, g: number, b: number, code: number) => string} */
|
|
4
6
|
function rgb(r, g, b, code) {
|
|
5
7
|
if (r === g && g === b) {
|
|
@@ -84,6 +86,58 @@ const ansi = {
|
|
|
84
86
|
scrollUp : lines => `\x1b[${lines}S`,
|
|
85
87
|
/** @type {(lines: number) => string} */
|
|
86
88
|
scrollDown : lines => `\x1b[${lines}T`,
|
|
89
|
+
|
|
90
|
+
/** @type {(text: string) => string} */
|
|
91
|
+
strip: text => text.replace(rxCSI, ''),
|
|
92
|
+
|
|
93
|
+
/** @type {(text: string, start: number, end: number) => string} */
|
|
94
|
+
slice(text, start, end) {
|
|
95
|
+
if (start < 0 || end < 0) {
|
|
96
|
+
const visibleLength = ansi.strip(text).length;
|
|
97
|
+
if (start < 0)
|
|
98
|
+
start = Math.max(0, visibleLength + start);
|
|
99
|
+
if (end < 0)
|
|
100
|
+
end = Math.max(0, visibleLength + end);
|
|
101
|
+
}
|
|
102
|
+
if (start > end)
|
|
103
|
+
return "";
|
|
104
|
+
|
|
105
|
+
let visibleIndex = 0;
|
|
106
|
+
let startIndex = 0;
|
|
107
|
+
|
|
108
|
+
while (startIndex < text.length && visibleIndex < start) {
|
|
109
|
+
if (text[startIndex] === "\x1b") {
|
|
110
|
+
rxCSI.lastIndex = startIndex;
|
|
111
|
+
const match = rxCSI.exec(text);
|
|
112
|
+
if (match?.index === startIndex) {
|
|
113
|
+
startIndex += match[0].length;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
startIndex++;
|
|
119
|
+
visibleIndex++;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let endIndex = startIndex;
|
|
123
|
+
let hasAnsi = false;
|
|
124
|
+
while (endIndex < text.length && visibleIndex < end) {
|
|
125
|
+
if (text[endIndex] === "\x1b") {
|
|
126
|
+
rxCSI.lastIndex = endIndex;
|
|
127
|
+
const match = rxCSI.exec(text);
|
|
128
|
+
if (match?.index === endIndex) {
|
|
129
|
+
endIndex += match[0].length;
|
|
130
|
+
hasAnsi = true;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
endIndex++;
|
|
136
|
+
visibleIndex++;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return text.slice(startIndex, endIndex) + (hasAnsi ? ansi.reset : "");
|
|
140
|
+
},
|
|
87
141
|
};
|
|
88
142
|
|
|
89
143
|
module.exports = ansi;
|