@alcalzone/ansi-tokenize 0.1.2 → 0.2.0

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 CHANGED
@@ -231,6 +231,15 @@ This automatically figures out the least amount of escape codes necessary to ach
231
231
  Placeholder for next release:
232
232
  ### __WORK IN PROGRESS__
233
233
  -->
234
+ ### 0.2.0 (2025-04-24)
235
+
236
+ - Breaking: Require Node.js 18+
237
+ - Fix: Detect emojis as being full width
238
+
239
+ ### 0.1.3 (2023-09-07)
240
+
241
+ - Fix: Support links
242
+
234
243
  ### 0.1.2 (2023-08-07)
235
244
 
236
245
  - Fix: Reduce minimum Node.js version to `14.13.1`
@@ -1,5 +1,11 @@
1
1
  import type { AnsiCode } from "./tokenize.js";
2
2
  export declare const ESCAPES: Set<number>;
3
3
  export declare const endCodesSet: Set<string>;
4
+ export declare const linkStartCodePrefix = "\u001B]8;;";
5
+ export declare const linkStartCodePrefixCharCodes: number[];
6
+ export declare const linkCodeSuffix = "\u0007";
7
+ export declare const linkCodeSuffixCharCode: number;
8
+ export declare const linkEndCode: string;
9
+ export declare function getLinkStartCode(url: string): string;
4
10
  export declare function getEndCode(code: string): string;
5
11
  export declare function ansiCodesToString(codes: AnsiCode[]): string;
@@ -6,11 +6,23 @@ for (const [start, end] of ansiStyles.codes) {
6
6
  endCodesSet.add(ansiStyles.color.ansi(end));
7
7
  endCodesMap.set(ansiStyles.color.ansi(start), ansiStyles.color.ansi(end));
8
8
  }
9
+ export const linkStartCodePrefix = "\x1B]8;;";
10
+ export const linkStartCodePrefixCharCodes = linkStartCodePrefix
11
+ .split("")
12
+ .map((char) => char.charCodeAt(0));
13
+ export const linkCodeSuffix = "\x07";
14
+ export const linkCodeSuffixCharCode = linkCodeSuffix.charCodeAt(0);
15
+ export const linkEndCode = `\x1B]8;;${linkCodeSuffix}`;
16
+ export function getLinkStartCode(url) {
17
+ return `${linkStartCodePrefix}${url}${linkCodeSuffix}`;
18
+ }
9
19
  export function getEndCode(code) {
10
20
  if (endCodesSet.has(code))
11
21
  return code;
12
22
  if (endCodesMap.has(code))
13
23
  return endCodesMap.get(code);
24
+ if (code.startsWith(linkStartCodePrefix))
25
+ return linkEndCode;
14
26
  code = code.slice(2);
15
27
  if (code.includes(";")) {
16
28
  code = code[0] + "0";
@@ -1 +1 @@
1
- {"version":3,"file":"ansiCodes.js","sourceRoot":"","sources":["../src/ansiCodes.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAGrC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB;AAE3D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;AAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC9C,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,EAAE;IAC5C,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IAEzD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QACvB,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;KACrB;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACrD,IAAI,GAAG,EAAE;QACR,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KAClC;SAAM;QACN,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;KAC7B;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IAClD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"ansiCodes.js","sourceRoot":"","sources":["../src/ansiCodes.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAGrC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB;AAE3D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;AAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC9C,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,EAAE;IAC5C,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB;KAC7D,KAAK,CAAC,EAAE,CAAC;KACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,sBAAsB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,cAAc,EAAE,CAAC;AAEvD,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC3C,OAAO,GAAG,mBAAmB,GAAG,GAAG,GAAG,cAAc,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IAEzD,IAAI,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAAE,OAAO,WAAW,CAAC;IAE7D,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QACvB,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;KACrB;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACrD,IAAI,GAAG,EAAE;QACR,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KAClC;SAAM;QACN,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;KAC7B;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IAClD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC"}
package/build/tokenize.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import isFullwidthCodePoint from "is-fullwidth-code-point";
2
- import { ESCAPES, getEndCode } from "./ansiCodes.js";
2
+ import { ESCAPES, getEndCode, linkStartCodePrefix, linkStartCodePrefixCharCodes, } from "./ansiCodes.js";
3
3
  function findNumberIndex(str) {
4
4
  for (let index = 0; index < str.length; index++) {
5
5
  const charCode = str.charCodeAt(index);
@@ -9,6 +9,19 @@ function findNumberIndex(str) {
9
9
  }
10
10
  return -1;
11
11
  }
12
+ function parseLinkCode(string, offset) {
13
+ string = string.slice(offset);
14
+ for (let index = 1; index < linkStartCodePrefixCharCodes.length; index++) {
15
+ if (string.charCodeAt(index) !== linkStartCodePrefixCharCodes[index]) {
16
+ return undefined;
17
+ }
18
+ }
19
+ // This is a link code (with or without the URL part). Find the end of it.
20
+ const endIndex = string.indexOf("\x07", linkStartCodePrefix.length);
21
+ if (endIndex === -1)
22
+ return undefined;
23
+ return string.slice(0, endIndex + 1);
24
+ }
12
25
  function parseAnsiCode(string, offset) {
13
26
  string = string.slice(offset, offset + 19);
14
27
  const startIndex = findNumberIndex(string);
@@ -27,7 +40,8 @@ export function tokenize(str, endChar = Number.POSITIVE_INFINITY) {
27
40
  while (index < str.length) {
28
41
  const codePoint = str.codePointAt(index);
29
42
  if (ESCAPES.has(codePoint)) {
30
- const code = parseAnsiCode(str, index);
43
+ // TODO: We should probably decide on the next character ("[" or "]") which code path to take.
44
+ const code = parseLinkCode(str, index) || parseAnsiCode(str, index);
31
45
  if (code) {
32
46
  ret.push({
33
47
  type: "ansi",
@@ -1 +1 @@
1
- {"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAgBrD,SAAS,eAAe,CAAC,GAAW;IACnC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,EAAE,EAAE;YACrC,OAAO,KAAK,CAAC;SACb;KACD;IAED,OAAO,CAAC,CAAC,CAAC;AACX,CAAC;AAED,SAAS,aAAa,CAAC,MAAc,EAAE,MAAc;IACpD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE;QACtB,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE;YACpB,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;SACzB;QAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;KACrC;AACF,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,UAAkB,MAAM,CAAC,iBAAiB;IAC/E,MAAM,GAAG,GAAY,EAAE,CAAC;IAExB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE;QAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAE,CAAC;QAE1C,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAC3B,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACvC,IAAI,IAAI,EAAE;gBACT,GAAG,CAAC,IAAI,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI;oBACJ,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC;iBACzB,CAAC,CAAC;gBACH,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;gBACrB,SAAS;aACT;SACD;QAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAElD,GAAG,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;YAChB,SAAS;SACT,CAAC,CAAC;QAEH,KAAK,IAAI,SAAS,CAAC,MAAM,CAAC;QAC1B,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;QAE5C,IAAI,OAAO,IAAI,OAAO,EAAE;YACvB,MAAM;SACN;KACD;IAED,OAAO,GAAG,CAAC;AACZ,CAAC"}
1
+ {"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alcalzone/ansi-tokenize",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Efficiently modify strings containing ANSI escape codes",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,7 +24,7 @@
24
24
  "build"
25
25
  ],
26
26
  "engines": {
27
- "node": ">=14.13.1"
27
+ "node": ">=18"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@alcalzone/release-script": "~3.5.9",
@@ -40,26 +40,24 @@
40
40
  "prettier": "^2.8.4",
41
41
  "source-map-support": "^0.5.21",
42
42
  "ts-node": "^10.9.1",
43
+ "tsx": "^3.12.8",
43
44
  "typescript": "^5.0.2"
44
45
  },
45
46
  "dependencies": {
46
47
  "ansi-styles": "^6.2.1",
47
- "is-fullwidth-code-point": "^4.0.0"
48
+ "is-fullwidth-code-point": "^5.0.0"
48
49
  },
49
50
  "scripts": {
50
51
  "prepare": "tsc -p tsconfig.build.json",
51
52
  "build": "tsc -p tsconfig.build.json",
52
- "test": "ava",
53
+ "test": "NODE_OPTIONS='--loader tsx' ava",
53
54
  "lint": "eslint .",
54
55
  "release": "release-script"
55
56
  },
56
57
  "ava": {
57
58
  "extensions": {
58
59
  "ts": "module"
59
- },
60
- "nodeArguments": [
61
- "--loader=ts-node/esm"
62
- ]
60
+ }
63
61
  },
64
62
  "packageManager": "yarn@3.5.0"
65
63
  }