@peteanderson/ansi 0.2.2 → 0.2.4

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.
Files changed (58) hide show
  1. package/README.md +30 -65
  2. package/ansi.js +28 -0
  3. package/package.json +20 -13
  4. package/dist/ansi.d.ts +0 -12
  5. package/dist/ansi.js +0 -21
  6. package/dist/caret.d.ts +0 -25
  7. package/dist/caret.js +0 -40
  8. package/dist/erase.d.ts +0 -14
  9. package/dist/erase.js +0 -15
  10. package/dist/index.d.ts +0 -106
  11. package/dist/index.js +0 -2
  12. package/dist/scroll.d.ts +0 -2
  13. package/dist/scroll.js +0 -8
  14. package/dist/sgr/color.d.ts +0 -62
  15. package/dist/sgr/color.js +0 -111
  16. package/dist/sgr/index.d.ts +0 -59
  17. package/dist/sgr/index.js +0 -6
  18. package/dist/sgr/reset.d.ts +0 -1
  19. package/dist/sgr/reset.js +0 -3
  20. package/dist/sgr/sgr.d.ts +0 -14
  21. package/dist/sgr/sgr.js +0 -47
  22. package/dist/sgr/style.d.ts +0 -13
  23. package/dist/sgr/style.js +0 -16
  24. package/dist/sgr/utils.d.ts +0 -2
  25. package/dist/sgr/utils.js +0 -16
  26. package/dist/simplify/atom.d.ts +0 -3
  27. package/dist/simplify/atom.js +0 -28
  28. package/dist/simplify/index.d.ts +0 -2
  29. package/dist/simplify/index.js +0 -2
  30. package/dist/simplify/lookup.d.ts +0 -5
  31. package/dist/simplify/lookup.js +0 -77
  32. package/dist/simplify/simplify.d.ts +0 -1
  33. package/dist/simplify/simplify.js +0 -24
  34. package/dist/simplify/state.d.ts +0 -10
  35. package/dist/simplify/state.js +0 -57
  36. package/dist/simplify/utils.d.ts +0 -2
  37. package/dist/simplify/utils.js +0 -31
  38. package/dist/strip.d.ts +0 -11
  39. package/dist/strip.js +0 -58
  40. package/src/ansi.js +0 -26
  41. package/src/caret.js +0 -49
  42. package/src/erase.js +0 -17
  43. package/src/index.js +0 -1
  44. package/src/scroll.js +0 -10
  45. package/src/sgr/color.js +0 -130
  46. package/src/sgr/index.js +0 -5
  47. package/src/sgr/reset.js +0 -3
  48. package/src/sgr/sgr.js +0 -66
  49. package/src/sgr/style.js +0 -19
  50. package/src/sgr/utils.js +0 -20
  51. package/src/simplify/atom.js +0 -34
  52. package/src/simplify/index.js +0 -1
  53. package/src/simplify/lookup.js +0 -86
  54. package/src/simplify/simplify.js +0 -33
  55. package/src/simplify/state.js +0 -73
  56. package/src/simplify/types.d.ts +0 -28
  57. package/src/simplify/utils.js +0 -41
  58. package/src/strip.js +0 -69
package/src/sgr/color.js DELETED
@@ -1,130 +0,0 @@
1
- "use strict";
2
-
3
- const {sgr} = require("./sgr");
4
-
5
- /** @type {(r: number, g: number, b: number, open: number, close: number) => (text: string) => string} */
6
- const rgb = (r, g, b, open, close) => sgr([open, 2, r, g, b], close);
7
-
8
- /**
9
- * @overload
10
- * @param {number} code
11
- * @param {number} open
12
- * @param {number} close
13
- * @returns {(text: string) => string}
14
- *//**
15
- * @overload
16
- * @param {number} r
17
- * @param {number} g
18
- * @param {number} b
19
- * @param {number} open
20
- * @param {number} close
21
- * @returns {(text: string) => string}
22
- *//**
23
- @type {
24
- (
25
- ...args: [number, number, number] | [number, number, number, number, number]
26
- ) => (text: string) => string}
27
- */
28
- function x256(...args) {
29
- if (args.length === 3)
30
- return sgr([args[1], 5, args[0]], args[2]);
31
-
32
- const [r, g, b, open, close] = args;
33
- if (r === g && g === b) {
34
- // grayscale
35
- return sgr([open, 5, 232 + Math.floor(r * 24 / 256)], close);
36
- }
37
-
38
- // 6x6x6 color cube
39
- return sgr(
40
- [
41
- open,
42
- 5,
43
- 16 +
44
- Math.floor(r * 6 / 256) * 36 +
45
- Math.floor(g * 6 / 256) * 6 +
46
- Math.floor(b * 6 / 256)
47
- ],
48
- close,
49
- );
50
- }
51
-
52
- const fg = {
53
- black : sgr(30, 39),
54
- red : sgr(31, 39),
55
- green : sgr(32, 39),
56
- yellow : sgr(33, 39),
57
- blue : sgr(34, 39),
58
- magenta : sgr(35, 39),
59
- cyan : sgr(36, 39),
60
- white : sgr(37, 39),
61
-
62
- brightBlack : sgr(90, 39),
63
- brightRed : sgr(91, 39),
64
- brightGreen : sgr(92, 39),
65
- brightYellow : sgr(93, 39),
66
- brightBlue : sgr(94, 39),
67
- brightMagenta : sgr(95, 39),
68
- brightCyan : sgr(96, 39),
69
- brightWhite : sgr(97, 39),
70
-
71
- default : "\x1b[39m",
72
-
73
- /** @type {(r: number, g: number, b: number) => (text: string) => string} */
74
- rgb : (r, g, b) => rgb(r, g, b, 38, 39),
75
-
76
- /**
77
- * @overload
78
- * @param {number} code
79
- * @returns {(text: string) => string}
80
- *//**
81
- * @param {number} r
82
- * @param {number} g
83
- * @param {number} b
84
- * @returns {(text: string) => string}
85
- *//** @type {(arg0: number, arg1?: number, arg2?: number) => (text: string) => string} */
86
- x256 : (arg0, arg1, arg2) => arg1 === undefined || arg2 === undefined
87
- ? x256(arg0 , 38, 39)
88
- : x256(arg0, arg1, arg2, 38, 39),
89
- };
90
-
91
- const bg = {
92
- black : sgr(40, 49),
93
- red : sgr(41, 49),
94
- green : sgr(42, 49),
95
- yellow : sgr(43, 49),
96
- blue : sgr(44, 49),
97
- magenta : sgr(45, 49),
98
- cyan : sgr(46, 49),
99
- white : sgr(47, 49),
100
-
101
- brightBlack : sgr(100, 49),
102
- brightRed : sgr(101, 49),
103
- brightGreen : sgr(102, 49),
104
- brightYellow : sgr(103, 49),
105
- brightBlue : sgr(104, 49),
106
- brightMagenta : sgr(105, 49),
107
- brightCyan : sgr(106, 49),
108
- brightWhite : sgr(107, 49),
109
-
110
- default : "\x1b[49m",
111
-
112
- /** @type {(r: number, g: number, b: number) => (text: string) => string} */
113
- rgb : (r, g, b) => rgb(r, g, b, 48, 49),
114
-
115
- /**
116
- * @overload
117
- * @param {number} code
118
- * @returns {(text: string) => string}
119
- *//**
120
- * @param {number} r
121
- * @param {number} g
122
- * @param {number} b
123
- * @returns {(text: string) => string}
124
- *//** @type {(arg0: number, arg1?: number, arg2?: number) => (text: string) => string} */
125
- x256 : (arg0, arg1, arg2) => arg1 === undefined || arg2 === undefined
126
- ? x256(arg0 , 48, 49)
127
- : x256(arg0, arg1, arg2, 48, 49),
128
- };
129
-
130
- module.exports = {fg, bg};
package/src/sgr/index.js DELETED
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- ...require("./reset"),
3
- ...require("./style"),
4
- ...require("./color"),
5
- };
package/src/sgr/reset.js DELETED
@@ -1,3 +0,0 @@
1
- const reset = "\x1b[0m";
2
-
3
- module.exports = {reset};
package/src/sgr/sgr.js DELETED
@@ -1,66 +0,0 @@
1
- "use strict";
2
-
3
- const $codes = Symbol();
4
-
5
- /**
6
- @typedef {number | number[]} Code
7
- @typedef {{
8
- (text: string): string;
9
- open : string;
10
- close : string;
11
- [$codes] : {open: Code, close: Code};
12
- combine : (...styles: SGR[]) => SGR;
13
- }} SGR
14
- */
15
-
16
- /** @type {(code: Code, codes: Code[]) => Code} */
17
- function combine(code, codes, ) {
18
- if (!codes.length)
19
- return code;
20
-
21
- const rtn = Array.isArray(code) ? [...code] : [code];
22
-
23
- for (const c of codes) {
24
- if (Array.isArray(c))
25
- rtn.push(...c);
26
- else
27
- rtn.push(c);
28
- }
29
-
30
- return rtn;
31
- }
32
-
33
- /** @type {(code: Code) => string | number} */
34
- const codeSequence = code => Array.isArray(code) ? code.join(';') : code;
35
-
36
- /** @type {(open: Code, close: Code, reset?: boolean) => SGR} */
37
- function sgr(open, close, reset = false) {
38
- const openCode = codeSequence(open);
39
- const closeCode = codeSequence(close);
40
- const openSequence = `\x1b[${openCode}m`;
41
- const closeSequence = `\x1b[${closeCode}m`;
42
- const reopenCode = reset ? `${closeCode};${openCode}` : openCode;
43
-
44
- const rxClose = new RegExp(
45
- `(?<start>\\x1b\\[(?:\\d+;)*)${closeCode}(?<end>(?:;\\d+)*m)`,
46
- "g"
47
- );
48
- const replace = `$<start>${reopenCode}$<end>`;
49
-
50
- /** @type {(text: string) => string} */
51
- const func = s => openSequence + s.replace(rxClose, replace) + closeSequence
52
-
53
- return Object.assign(func, {
54
- [$codes] : {open, close},
55
- open : openSequence,
56
- close : closeSequence,
57
-
58
- /** @type {(...styles: SGR[]) => SGR} */
59
- combine: (...styles) => sgr(
60
- combine(open, styles.map(s => s[$codes].open)),
61
- combine(close, styles.map(s => s[$codes].close)),
62
- ),
63
- });
64
- }
65
-
66
- module.exports = {sgr};
package/src/sgr/style.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
-
3
- const {sgr} = require("./sgr");
4
-
5
- const style = {
6
- bold : sgr(1, 22, true),
7
- dim : sgr(2, 22, true),
8
- italic : sgr(3, 23),
9
- underline : sgr(4, 24),
10
- inverse : sgr(7, 27),
11
- hidden : sgr(8, 28),
12
- strikethrough : sgr(9, 29),
13
- doubleUnderline : sgr(21, 24),
14
- frame : sgr(51, 54),
15
- encircle : sgr(52, 54),
16
- overline : sgr(53, 55),
17
- };
18
-
19
- module.exports = {style};
package/src/sgr/utils.js DELETED
@@ -1,20 +0,0 @@
1
- /** @typedef {number | number[]} Code */
2
-
3
- /** @type {(code: Code, codes: Code[]) => Code} */
4
- function combine(code, codes, ) {
5
- if (!codes.length)
6
- return code;
7
-
8
- const rtn = Array.isArray(code) ? [...code] : [code];
9
-
10
- for (const c of codes) {
11
- if (Array.isArray(c))
12
- rtn.push(...c);
13
- else
14
- rtn.push(c);
15
- }
16
-
17
- return rtn;
18
- }
19
-
20
- module.exports = {combine};
@@ -1,34 +0,0 @@
1
- "use strict";
2
-
3
- /** @typedef {import("./types").BuildAtom} BuildAtom */
4
-
5
- /** @type {BuildAtom} */
6
- function buildExtendedColorAtom(attribute, codes, index) {
7
- switch (codes[index + 1]) {
8
- case 2:
9
- if (index + 5 >= codes.length)
10
- return {attribute, code: codes.slice(index), skip: codes.length - index - 1};
11
- return {attribute, code: codes.slice(index, index + 5), skip: 4};
12
- case 5:
13
- if (index + 3 >= codes.length)
14
- return {attribute, code: codes.slice(index), skip: codes.length - index - 1};
15
- return {attribute, code: codes.slice(index, index + 3), skip: 2};
16
- default:
17
- return {attribute, code: codes.slice(index, index + 2), skip: 1};
18
- }
19
- }
20
-
21
- /** @type {BuildAtom} */
22
- function buildIntensityAtom(attribute, codes, index, state) {
23
- const code = codes[index];
24
- if (code === 22)
25
- return {attribute, code: [code]};
26
-
27
- const current = state.get("intensity");
28
- if (!current || current.length == 1 && current[0] === code || current[0] === 22)
29
- return {attribute, code: [code]};
30
-
31
- return {attribute, code: [1, 2]};
32
- }
33
-
34
- module.exports = {buildExtendedColorAtom, buildIntensityAtom};
@@ -1 +0,0 @@
1
- module.exports = require("./simplify");
@@ -1,86 +0,0 @@
1
- "use strict";
2
-
3
- const {buildExtendedColorAtom, buildIntensityAtom} = require("./atom");
4
-
5
- /** @typedef {import("./types").Atom} Atom */
6
- /** @typedef {import("./types").Attribute} Attribute */
7
- /** @typedef {import("./types").AttributeMap} AttributeMap */
8
- /** @typedef {import("./types").BuildAtom} BuildAtom */
9
-
10
- /** @type {Record<number, [attribute: Attribute, buildAtom?: BuildAtom]>} */
11
- const codeMap = {
12
- 0 : ["reset"],
13
- 1 : ["intensity", buildIntensityAtom],
14
- 2 : ["intensity", buildIntensityAtom],
15
- 3 : ["italic"],
16
- 4 : ["underline"],
17
- 7 : ["inverse"],
18
- 8 : ["hidden"],
19
- 9 : ["strikethrough"],
20
- 21 : ["underline"],
21
- 22 : ["intensity", buildIntensityAtom],
22
- 23 : ["italic"],
23
- 24 : ["underline"],
24
- 27 : ["inverse"],
25
- 28 : ["hidden"],
26
- 29 : ["strikethrough"],
27
- 30 : ["fg"],
28
- 31 : ["fg"],
29
- 32 : ["fg"],
30
- 33 : ["fg"],
31
- 34 : ["fg"],
32
- 35 : ["fg"],
33
- 36 : ["fg"],
34
- 37 : ["fg"],
35
- 38 : ["fg", buildExtendedColorAtom],
36
- 39 : ["fg"],
37
- 40 : ["bg"],
38
- 41 : ["bg"],
39
- 42 : ["bg"],
40
- 43 : ["bg"],
41
- 44 : ["bg"],
42
- 45 : ["bg"],
43
- 46 : ["bg"],
44
- 47 : ["bg"],
45
- 48 : ["bg", buildExtendedColorAtom],
46
- 49 : ["bg"],
47
- 51 : ["frame"],
48
- 52 : ["frame"],
49
- 53 : ["overline"],
50
- 54 : ["frame"],
51
- 55 : ["overline"],
52
- 90 : ["fg"],
53
- 91 : ["fg"],
54
- 92 : ["fg"],
55
- 93 : ["fg"],
56
- 94 : ["fg"],
57
- 95 : ["fg"],
58
- 96 : ["fg"],
59
- 97 : ["fg"],
60
- 100 : ["bg"],
61
- 101 : ["bg"],
62
- 102 : ["bg"],
63
- 103 : ["bg"],
64
- 104 : ["bg"],
65
- 105 : ["bg"],
66
- 106 : ["bg"],
67
- 107 : ["bg"],
68
- };
69
-
70
- /** @type {(codes: number[], index: number, state: AttributeMap) => Atom} */
71
- function lookUpAtom(codes, index, state) {
72
- const code = codes[index];
73
- const entry = codeMap[code];
74
-
75
- if (!entry)
76
- return {attribute: code, code: [code]};
77
-
78
- const [attribute, buildAtom] = entry;
79
-
80
- if (buildAtom)
81
- return buildAtom(attribute, codes, index, state);
82
-
83
- return {attribute, code: [code]};
84
- }
85
-
86
- module.exports = {lookUpAtom};
@@ -1,33 +0,0 @@
1
- "use strict";
2
-
3
- const {State} = require("./state");
4
-
5
- const rxSGR = /\x1b\[([0-9;]+)m/;
6
-
7
- /** @type {(text: string) => string} */
8
- function simplify(text) {
9
- const parts = text.split(rxSGR);
10
-
11
- const state = new State();
12
- let result = parts[0];
13
-
14
- for (let i = 1; i < parts.length; ) {
15
- let codes = parts[i++].split(";").map(Number);
16
- let chunk = parts[i++];
17
-
18
- while (!chunk && i < parts.length) {
19
- // Merge consecutive SGR sequences.
20
- codes.push(...parts[i++].split(";").map(Number));
21
- chunk = parts[i++];
22
- }
23
-
24
- codes = state.update(codes);
25
- if (codes.length)
26
- result += `\x1b[${codes.join(";")}m`;
27
- result += chunk;
28
- }
29
-
30
- return result;
31
- }
32
-
33
- module.exports = {simplify};
@@ -1,73 +0,0 @@
1
- "use strict";
2
-
3
- const {lookUpAtom} = require("./lookup");
4
- const {arraysEqual, transitionIntensity} = require("./utils");
5
-
6
- /** @typedef {import("./types").Attribute} Attribute */
7
- /** @typedef {import("./types").AttributeMap} AttributeMap */
8
-
9
- /** @type {Map<Attribute, number[]>} */
10
- const defaultCodes = new Map([
11
- ["intensity", [22]],
12
- ["italic", [23]],
13
- ["underline", [24]],
14
- ["inverse", [27]],
15
- ["hidden", [28]],
16
- ["strikethrough",[29]],
17
- ["fg", [39]],
18
- ["bg", [49]],
19
- ["frame", [54]],
20
- ["overline", [55]],
21
- ]);
22
-
23
- /** @type {AttributeMap} */
24
- class State extends Map {
25
- /** @type {(codes: number[]) => number[]} */
26
- update(codes) {
27
- /** @type {AttributeMap} */
28
- let snapshot = new Map(this);
29
-
30
- /** @type {Set<Attribute>} */
31
- const attributes = new Set();
32
-
33
- for (let i = 0; i < codes.length; i++) {
34
- const {attribute, code, skip} = lookUpAtom(codes, i, this);
35
-
36
- if (attribute === "reset") {
37
- attributes.clear();
38
- this.clear();
39
- attributes.add("reset");
40
- for (const [attr, defaultCode] of defaultCodes)
41
- this.set(attr, defaultCode);
42
-
43
- snapshot = new Map(this);
44
- continue;
45
- }
46
-
47
- attributes.add(attribute);
48
- this.set(attribute, code);
49
-
50
- if (skip)
51
- i += skip;
52
- }
53
-
54
- return Array.from(attributes).flatMap(attribute => {
55
- if (attribute === "reset")
56
- return [0];
57
-
58
- const code = this.get(attribute);
59
-
60
- if (arraysEqual(code, snapshot.get(attribute)))
61
- return [];
62
-
63
- if (attribute === "intensity") {
64
- const previous = snapshot.get(attribute);
65
- return transitionIntensity(previous, code);
66
- }
67
-
68
- return code;
69
- });
70
- }
71
- }
72
-
73
- module.exports = {State};
@@ -1,28 +0,0 @@
1
- export type Attribute =
2
- | "intensity"
3
- | "italic"
4
- | "underline"
5
- | "inverse"
6
- | "hidden"
7
- | "strikethrough"
8
- | "fg"
9
- | "bg"
10
- | "frame"
11
- | "overline"
12
- | "reset"
13
- | number;
14
-
15
- type AttributeMap = Map<Attribute, number[]>;
16
-
17
- export interface Atom {
18
- attribute : Attribute;
19
- code : number[];
20
- skip? : number;
21
- }
22
-
23
- export type BuildAtom = (
24
- attribute: Attribute,
25
- codes : number[],
26
- index : number,
27
- state : AttributeMap,
28
- ) => Atom;
@@ -1,41 +0,0 @@
1
- "use strict";
2
-
3
- /** @type {<T>(a: T[] | undefined, b: T[] | undefined) => boolean} */
4
- function arraysEqual(a, b) {
5
- if (a === b)
6
- return true;
7
-
8
- if (!a || !b || a.length !== b.length)
9
- return false;
10
-
11
- for (let i = 0; i < a.length; i++) {
12
- if (a[i] !== b[i])
13
- return false;
14
- }
15
-
16
- return true;
17
- }
18
-
19
- /** @type {(previous: number[] | undefined, current: number[]) => number[]} */
20
- function transitionIntensity(previous, current) {
21
- if (!previous || previous[0] === 22 || current[0] === 22)
22
- return current;
23
-
24
- const oldBold = previous[0] === 1;
25
- const newBold = current[0] === 1;
26
- const oldDim = previous[previous.length - 1] === 2;
27
- const newDim = current[current.length - 1] === 2;
28
-
29
- const result = [];
30
-
31
- if (oldBold && !newBold || oldDim && !newDim)
32
- result.push(22);
33
- if (newBold && (!oldBold || result[0] === 22))
34
- result.push(1);
35
- if (newDim && (!oldDim || result[0] === 22))
36
- result.push(2);
37
-
38
- return result;
39
- }
40
-
41
- module.exports = {arraysEqual, transitionIntensity};
package/src/strip.js DELETED
@@ -1,69 +0,0 @@
1
- "use strict";
2
-
3
- const {reset} = require("./sgr");
4
-
5
- const rxCSI = /\x1b\[[0-?]*[ -/]*[@-~]/g;
6
- const rxUnsafe = /\x1b\[[0-?]*[ -/]*[@-ln-~]/g; // Everything except SGR codes (m).
7
-
8
- /**
9
- * Remove all ANSI escape codes from the given text.
10
- * @type {(text: string) => string}
11
- */
12
- const strip = text => text.replace(rxCSI, '');
13
-
14
- /**
15
- * Remove all ANSI escape codes except SGR codes (m), which are used for color and styling.
16
- * @type {(text: string) => string}
17
- */
18
- const sanitize = text => text.replace(rxUnsafe, '');
19
-
20
- /** @type {(text: string, start: number, end: number) => string} */
21
- function slice(text, start, end) {
22
- if (start < 0 || end < 0) {
23
- const visibleLength = strip(text).length;
24
- if (start < 0)
25
- start = Math.max(0, visibleLength + start);
26
- if (end < 0)
27
- end = Math.max(0, visibleLength + end);
28
- }
29
- if (start > end)
30
- return "";
31
-
32
- let visibleIndex = 0;
33
- let startIndex = 0;
34
-
35
- while (startIndex < text.length && visibleIndex < start) {
36
- if (text[startIndex] === "\x1b") {
37
- rxCSI.lastIndex = startIndex;
38
- const match = rxCSI.exec(text);
39
- if (match?.index === startIndex) {
40
- startIndex += match[0].length;
41
- continue;
42
- }
43
- }
44
-
45
- startIndex++;
46
- visibleIndex++;
47
- }
48
-
49
- let endIndex = startIndex;
50
- let hasAnsi = false;
51
- while (endIndex < text.length && visibleIndex < end) {
52
- if (text[endIndex] === "\x1b") {
53
- rxCSI.lastIndex = endIndex;
54
- const match = rxCSI.exec(text);
55
- if (match?.index === endIndex) {
56
- endIndex += match[0].length;
57
- hasAnsi = true;
58
- continue;
59
- }
60
- }
61
-
62
- endIndex++;
63
- visibleIndex++;
64
- }
65
-
66
- return text.slice(startIndex, endIndex) + (hasAnsi ? reset : "");
67
- };
68
-
69
- module.exports = {strip, sanitize, slice};