@ansi-tools/parser 1.0.12 → 1.0.13

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 (48) hide show
  1. package/dist/constants.d.ts +56 -0
  2. package/dist/constants.d.ts.map +1 -0
  3. package/dist/constants.js +55 -0
  4. package/dist/escaped.d.ts +6 -10
  5. package/dist/escaped.d.ts.map +1 -0
  6. package/dist/escaped.js +4 -275
  7. package/dist/index.d.ts +5 -7
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +3 -3
  10. package/dist/parse.d.ts +4 -0
  11. package/dist/parse.d.ts.map +1 -0
  12. package/dist/parse.escaped.d.ts +3 -0
  13. package/dist/parse.escaped.d.ts.map +1 -0
  14. package/dist/parse.escaped.js +5 -0
  15. package/dist/parse.js +109 -0
  16. package/dist/parsers/apc.d.ts +3 -0
  17. package/dist/parsers/apc.d.ts.map +1 -0
  18. package/dist/parsers/apc.js +6 -0
  19. package/dist/parsers/csi.d.ts +3 -0
  20. package/dist/parsers/csi.d.ts.map +1 -0
  21. package/dist/parsers/csi.js +63 -0
  22. package/dist/parsers/dcs.d.ts +3 -0
  23. package/dist/parsers/dcs.d.ts.map +1 -0
  24. package/dist/parsers/dcs.js +26 -0
  25. package/dist/parsers/esc.d.ts +3 -0
  26. package/dist/parsers/esc.d.ts.map +1 -0
  27. package/dist/parsers/esc.js +8 -0
  28. package/dist/parsers/osc.d.ts +3 -0
  29. package/dist/parsers/osc.d.ts.map +1 -0
  30. package/dist/parsers/osc.js +28 -0
  31. package/dist/parsers/pm.d.ts +3 -0
  32. package/dist/parsers/pm.d.ts.map +1 -0
  33. package/dist/parsers/pm.js +6 -0
  34. package/dist/parsers/sos.d.ts +3 -0
  35. package/dist/parsers/sos.d.ts.map +1 -0
  36. package/dist/parsers/sos.js +6 -0
  37. package/dist/tokenize.d.ts +4 -0
  38. package/dist/tokenize.d.ts.map +1 -0
  39. package/dist/tokenize.escaped.d.ts +4 -0
  40. package/dist/tokenize.escaped.d.ts.map +1 -0
  41. package/dist/tokenize.escaped.js +295 -0
  42. package/dist/tokenize.js +314 -0
  43. package/dist/types.d.ts +23 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +1 -0
  46. package/package.json +27 -28
  47. package/dist/parse-BCjxFvJh.js +0 -530
  48. package/dist/parse-BzJl6pBN.d.ts +0 -85
@@ -0,0 +1,314 @@
1
+ import { APC, BACKSLASH, BACKSLASH_CODE, BELL, BELL_CODE, CAN, CSI, CSI_CODE, CSI_OPEN, DCS, ESC, ESC_CODE, OSC, OSC_CODE, OSC_OPEN, PM, SOS, ST, ST_CODE, STRING_OPENERS, SUB, TOKEN_TYPES, } from "./constants.js";
2
+ function isInterrupter(c) {
3
+ return (c === CAN || c === SUB || c === ESC || c === CSI || c === OSC || c === DCS || c === APC || c === PM || c === SOS);
4
+ }
5
+ function isC0Interrupter(c) {
6
+ return c === CAN || c === SUB;
7
+ }
8
+ function isSequenceStart(c) {
9
+ return c === ESC || c === CSI || c === OSC || c === DCS || c === APC || c === PM || c === SOS;
10
+ }
11
+ function is8BitIntroducer(c) {
12
+ return c === CSI || c === OSC || c === DCS || c === APC || c === PM || c === SOS;
13
+ }
14
+ export function* tokenizer(input) {
15
+ let i = 0;
16
+ let state = 0; // 0 = GROUND, 1 = SEQUENCE
17
+ let currentCode = 0;
18
+ const len = input.length;
19
+ while (i < len) {
20
+ if (state === 0) {
21
+ const textStart = i;
22
+ let charCode = input.charCodeAt(i);
23
+ while (i < len && !isSequenceStart(charCode)) {
24
+ charCode = input.charCodeAt(++i);
25
+ }
26
+ if (i > textStart) {
27
+ yield { type: TOKEN_TYPES.TEXT, pos: textStart, raw: input.substring(textStart, i) };
28
+ }
29
+ if (i >= len)
30
+ break;
31
+ if (is8BitIntroducer(charCode)) {
32
+ yield { type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input[i], code: input[i] };
33
+ i++;
34
+ state = 1;
35
+ currentCode = charCode;
36
+ }
37
+ else {
38
+ // ESC
39
+ const nextCode = input.charCodeAt(i + 1);
40
+ if (nextCode === CSI_OPEN) {
41
+ yield { type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, i + 2), code: CSI_CODE };
42
+ i += 2;
43
+ state = 1;
44
+ currentCode = CSI;
45
+ }
46
+ else if (nextCode === OSC_OPEN) {
47
+ yield { type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, i + 2), code: OSC_CODE };
48
+ i += 2;
49
+ state = 1;
50
+ currentCode = OSC;
51
+ }
52
+ else if (i + 1 < len && STRING_OPENERS.has(input[i + 1])) {
53
+ yield { type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, i + 2), code: input[i + 1] };
54
+ i += 2;
55
+ state = 1;
56
+ currentCode = nextCode;
57
+ }
58
+ else if (i + 1 < len) {
59
+ let j = i + 1;
60
+ while (j < len && input.charCodeAt(j) >= 0x20 && input.charCodeAt(j) <= 0x2f)
61
+ j++;
62
+ if (j < len) {
63
+ if (j > i + 1) {
64
+ const intermediate = input.substring(i + 1, j);
65
+ yield { type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, j), code: ESC_CODE, intermediate };
66
+ }
67
+ else {
68
+ yield { type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input[i], code: ESC_CODE };
69
+ }
70
+ i = j;
71
+ state = 1;
72
+ currentCode = ESC;
73
+ }
74
+ else {
75
+ i = j;
76
+ }
77
+ }
78
+ else {
79
+ i++;
80
+ }
81
+ }
82
+ }
83
+ else {
84
+ const pos = i;
85
+ if (currentCode === CSI) {
86
+ const dataStart = i;
87
+ while (i < len) {
88
+ const charCode = input.charCodeAt(i);
89
+ if (isInterrupter(charCode)) {
90
+ if (i > dataStart)
91
+ yield { type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) };
92
+ state = 0;
93
+ if (isC0Interrupter(charCode))
94
+ i++;
95
+ break;
96
+ }
97
+ if (charCode >= 0x40 && charCode <= 0x7e) {
98
+ if (i > dataStart)
99
+ yield { type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) };
100
+ yield { type: TOKEN_TYPES.FINAL, pos: i, raw: input[i] };
101
+ i++;
102
+ state = 0;
103
+ break;
104
+ }
105
+ i++;
106
+ }
107
+ }
108
+ else if (currentCode === ESC) {
109
+ if (i < len) {
110
+ const charCode = input.charCodeAt(i);
111
+ if (isInterrupter(charCode)) {
112
+ state = 0;
113
+ if (isC0Interrupter(charCode))
114
+ i++;
115
+ }
116
+ else {
117
+ yield { type: TOKEN_TYPES.FINAL, pos: i, raw: input[i] };
118
+ i++;
119
+ state = 0;
120
+ }
121
+ }
122
+ }
123
+ else {
124
+ const dataStart = i;
125
+ while (i < len) {
126
+ const charCode = input.charCodeAt(i);
127
+ let terminator;
128
+ if (charCode === ESC && input.charCodeAt(i + 1) === BACKSLASH) {
129
+ terminator = ESC_CODE + BACKSLASH_CODE;
130
+ }
131
+ else if (charCode === ST) {
132
+ terminator = ST_CODE;
133
+ }
134
+ else if (charCode === BELL && currentCode === OSC) {
135
+ terminator = BELL_CODE;
136
+ }
137
+ if (terminator) {
138
+ if (i > dataStart)
139
+ yield { type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) };
140
+ yield { type: TOKEN_TYPES.FINAL, pos: i, raw: terminator };
141
+ i += terminator.length;
142
+ state = 0;
143
+ break;
144
+ }
145
+ if (isInterrupter(charCode)) {
146
+ if (i > dataStart)
147
+ yield { type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) };
148
+ state = 0;
149
+ if (isC0Interrupter(charCode))
150
+ i++;
151
+ break;
152
+ }
153
+ i++;
154
+ }
155
+ }
156
+ if (state === 1)
157
+ state = 0;
158
+ }
159
+ }
160
+ }
161
+ export function tokenize(input) {
162
+ const result = [];
163
+ let i = 0;
164
+ let state = 0;
165
+ let currentCode = 0;
166
+ const len = input.length;
167
+ while (i < len) {
168
+ if (state === 0) {
169
+ const textStart = i;
170
+ let charCode = input.charCodeAt(i);
171
+ while (i < len && !isSequenceStart(charCode)) {
172
+ charCode = input.charCodeAt(++i);
173
+ }
174
+ if (i > textStart) {
175
+ result.push({ type: TOKEN_TYPES.TEXT, pos: textStart, raw: input.substring(textStart, i) });
176
+ }
177
+ if (i >= len)
178
+ break;
179
+ if (is8BitIntroducer(charCode)) {
180
+ result.push({ type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input[i], code: input[i] });
181
+ i++;
182
+ state = 1;
183
+ currentCode = charCode;
184
+ }
185
+ else {
186
+ const nextCode = input.charCodeAt(i + 1);
187
+ if (nextCode === CSI_OPEN) {
188
+ result.push({ type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, i + 2), code: CSI_CODE });
189
+ i += 2;
190
+ state = 1;
191
+ currentCode = CSI;
192
+ }
193
+ else if (nextCode === OSC_OPEN) {
194
+ result.push({ type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, i + 2), code: OSC_CODE });
195
+ i += 2;
196
+ state = 1;
197
+ currentCode = OSC;
198
+ }
199
+ else if (i + 1 < len && STRING_OPENERS.has(input[i + 1])) {
200
+ result.push({ type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input.substring(i, i + 2), code: input[i + 1] });
201
+ i += 2;
202
+ state = 1;
203
+ currentCode = nextCode;
204
+ }
205
+ else if (i + 1 < len) {
206
+ let j = i + 1;
207
+ while (j < len && input.charCodeAt(j) >= 0x20 && input.charCodeAt(j) <= 0x2f)
208
+ j++;
209
+ if (j < len) {
210
+ if (j > i + 1) {
211
+ const intermediate = input.substring(i + 1, j);
212
+ result.push({
213
+ type: TOKEN_TYPES.INTRODUCER,
214
+ pos: i,
215
+ raw: input.substring(i, j),
216
+ code: ESC_CODE,
217
+ intermediate,
218
+ });
219
+ }
220
+ else {
221
+ result.push({ type: TOKEN_TYPES.INTRODUCER, pos: i, raw: input[i], code: ESC_CODE });
222
+ }
223
+ i = j;
224
+ state = 1;
225
+ currentCode = ESC;
226
+ }
227
+ else {
228
+ i = j;
229
+ }
230
+ }
231
+ else {
232
+ i++;
233
+ }
234
+ }
235
+ }
236
+ else {
237
+ const pos = i;
238
+ if (currentCode === CSI) {
239
+ const dataStart = i;
240
+ while (i < len) {
241
+ const charCode = input.charCodeAt(i);
242
+ if (isInterrupter(charCode)) {
243
+ if (i > dataStart)
244
+ result.push({ type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) });
245
+ state = 0;
246
+ if (isC0Interrupter(charCode))
247
+ i++;
248
+ break;
249
+ }
250
+ if (charCode >= 0x40 && charCode <= 0x7e) {
251
+ if (i > dataStart)
252
+ result.push({ type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) });
253
+ result.push({ type: TOKEN_TYPES.FINAL, pos: i, raw: input[i] });
254
+ i++;
255
+ state = 0;
256
+ break;
257
+ }
258
+ i++;
259
+ }
260
+ }
261
+ else if (currentCode === ESC) {
262
+ if (i < len) {
263
+ const charCode = input.charCodeAt(i);
264
+ if (isInterrupter(charCode)) {
265
+ state = 0;
266
+ if (isC0Interrupter(charCode))
267
+ i++;
268
+ }
269
+ else {
270
+ result.push({ type: TOKEN_TYPES.FINAL, pos: i, raw: input[i] });
271
+ i++;
272
+ state = 0;
273
+ }
274
+ }
275
+ }
276
+ else {
277
+ const dataStart = i;
278
+ while (i < len) {
279
+ const charCode = input.charCodeAt(i);
280
+ let terminator;
281
+ if (charCode === ESC && input.charCodeAt(i + 1) === BACKSLASH) {
282
+ terminator = ESC_CODE + BACKSLASH_CODE;
283
+ }
284
+ else if (charCode === ST) {
285
+ terminator = ST_CODE;
286
+ }
287
+ else if (charCode === BELL && currentCode === OSC) {
288
+ terminator = BELL_CODE;
289
+ }
290
+ if (terminator) {
291
+ if (i > dataStart)
292
+ result.push({ type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) });
293
+ result.push({ type: TOKEN_TYPES.FINAL, pos: i, raw: terminator });
294
+ i += terminator.length;
295
+ state = 0;
296
+ break;
297
+ }
298
+ if (isInterrupter(charCode)) {
299
+ if (i > dataStart)
300
+ result.push({ type: TOKEN_TYPES.DATA, pos, raw: input.substring(dataStart, i) });
301
+ state = 0;
302
+ if (isC0Interrupter(charCode))
303
+ i++;
304
+ break;
305
+ }
306
+ i++;
307
+ }
308
+ }
309
+ if (state === 1)
310
+ state = 0;
311
+ }
312
+ }
313
+ return result;
314
+ }
@@ -0,0 +1,23 @@
1
+ import type { CODE_TYPES, TOKEN_TYPES } from "./constants.ts";
2
+ export type TOKEN = {
3
+ type: keyof typeof TOKEN_TYPES;
4
+ pos: number;
5
+ raw: string;
6
+ code?: string;
7
+ intermediate?: string;
8
+ };
9
+ export type CONTROL_CODE_TYPE = Exclude<keyof typeof CODE_TYPES, TEXT["type"]>;
10
+ export type CONTROL_CODE = {
11
+ type: CONTROL_CODE_TYPE;
12
+ command: string;
13
+ raw: string;
14
+ params: string[];
15
+ pos: number;
16
+ };
17
+ export type TEXT = {
18
+ type: "TEXT";
19
+ raw: string;
20
+ pos: number;
21
+ };
22
+ export type CODE = CONTROL_CODE | TEXT;
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE9D,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,OAAO,WAAW,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,MAAM,OAAO,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/E,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG,IAAI,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,9 +1,26 @@
1
1
  {
2
2
  "name": "@ansi-tools/parser",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Tokenize and parse strings containing ANSI escape sequences and control codes",
5
- "main": "./dist/index.js",
5
+ "keywords": [
6
+ "ansi",
7
+ "escape codes",
8
+ "web application"
9
+ ],
10
+ "homepage": "https://github.com/webpro/ANSI.tools/tree/main/packages/parser",
11
+ "bugs": "https://github.com/webpro/ANSI.tools/issues",
12
+ "license": "ISC",
13
+ "author": "Lars Kappert <lars@webpro.nl>",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "github:webpro/ANSI.tools",
17
+ "directory": "packages/parser"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
6
22
  "type": "module",
23
+ "main": "./dist/index.js",
7
24
  "exports": {
8
25
  ".": {
9
26
  "types": "./dist/index.d.ts",
@@ -16,37 +33,19 @@
16
33
  "default": "./dist/escaped.js"
17
34
  }
18
35
  },
19
- "files": [
20
- "dist"
21
- ],
22
- "scripts": {
23
- "prebuild": "pnpm type-check && pnpm test",
24
- "build": "tsdown --dts src/index.ts src/escaped.ts",
25
- "dev": "tsdown --dts src/index.ts src/escaped.ts --watch",
26
- "test": "node --import ./test/assertions.ts --test",
27
- "type-check": "tsc",
28
- "prepack": "pnpm build"
29
- },
30
- "keywords": [
31
- "ansi",
32
- "escape codes",
33
- "web application"
34
- ],
35
- "author": "Lars Kappert <lars@webpro.nl>",
36
- "license": "ISC",
37
36
  "publishConfig": {
38
37
  "access": "public"
39
38
  },
40
- "homepage": "https://github.com/webpro/ANSI.tools/tree/main/packages/parser",
41
- "bugs": "https://github.com/webpro/ANSI.tools/issues",
42
- "repository": {
43
- "type": "git",
44
- "url": "github:webpro/ANSI.tools",
45
- "directory": "packages/parser"
39
+ "scripts": {
40
+ "prebuild": "pnpm test",
41
+ "build": "tsc",
42
+ "dev": "tsc --watch",
43
+ "test": "node --import ./test/assertions.ts --test",
44
+ "prepack": "pnpm build"
46
45
  },
47
46
  "devDependencies": {
48
- "@types/node": "^24.7.2",
49
- "tsdown": "^0.15.7",
47
+ "@types/node": "^24.12.0",
48
+ "mitata": "^1.0.34",
50
49
  "typescript": "^5.9.3"
51
50
  }
52
51
  }