juxscript 1.1.45 → 1.1.46
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/index.d.ts.map +1 -1
- package/lib/components/code.d.ts.map +1 -1
- package/lib/components/code.js +4 -8
- package/lib/components/code.ts +6 -11
- package/lib/utils/codeparser.d.ts +35 -3
- package/lib/utils/codeparser.d.ts.map +1 -1
- package/lib/utils/codeparser.js +93 -69
- package/lib/utils/codeparser.ts +110 -79
- package/package.json +1 -1
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAOxD,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,IAAK,SAAQ,aAAa,CAAC,SAAS,CAAC;IAChD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAS;gBAE9B,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAYjD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAIhD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAsBtC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKrC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IASrC;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAOxD,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,IAAK,SAAQ,aAAa,CAAC,SAAS,CAAC;IAChD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAS;gBAE9B,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAYjD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAIhD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAsBtC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKrC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IASrC;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;CAgFnE;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAEhE"}
|
package/lib/components/code.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
-
import {
|
|
2
|
+
import { codeParser } from '../utils/codeparser.js'; // ✅ Default import
|
|
3
3
|
// Event definitions
|
|
4
4
|
const TRIGGER_EVENTS = [];
|
|
5
5
|
const CALLBACK_EVENTS = [];
|
|
@@ -68,7 +68,7 @@ export class Code extends BaseComponent {
|
|
|
68
68
|
* Parse code content into individual lines with tokens
|
|
69
69
|
*/
|
|
70
70
|
_parseLines() {
|
|
71
|
-
return
|
|
71
|
+
return codeParser.parse(this.state.content, this.state.language);
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Rebuild all line elements
|
|
@@ -88,10 +88,6 @@ export class Code extends BaseComponent {
|
|
|
88
88
|
const lineEl = this._createLineElement(parsedLine, lineNumber, isHighlighted);
|
|
89
89
|
codeEl.appendChild(lineEl);
|
|
90
90
|
});
|
|
91
|
-
// Re-run Prism if available
|
|
92
|
-
if (window.Prism && this._codeContainer) {
|
|
93
|
-
window.Prism.highlightAllUnder(this._codeContainer);
|
|
94
|
-
}
|
|
95
91
|
}
|
|
96
92
|
/**
|
|
97
93
|
* Create a single line element with parsed tokens
|
|
@@ -113,7 +109,7 @@ export class Code extends BaseComponent {
|
|
|
113
109
|
// Line content with syntax highlighting
|
|
114
110
|
const lineCode = document.createElement('span');
|
|
115
111
|
lineCode.className = 'jux-code-line-content';
|
|
116
|
-
lineCode.innerHTML =
|
|
112
|
+
lineCode.innerHTML = codeParser.renderLine(parsedLine);
|
|
117
113
|
lineEl.appendChild(lineCode);
|
|
118
114
|
return lineEl;
|
|
119
115
|
}
|
|
@@ -139,7 +135,7 @@ export class Code extends BaseComponent {
|
|
|
139
135
|
if (!Code._syntaxCSSInjected) {
|
|
140
136
|
const style = document.createElement('style');
|
|
141
137
|
style.id = 'jux-code-syntax-css';
|
|
142
|
-
style.textContent =
|
|
138
|
+
style.textContent = codeParser.getCSS();
|
|
143
139
|
document.head.appendChild(style);
|
|
144
140
|
Code._syntaxCSSInjected = true;
|
|
145
141
|
}
|
package/lib/components/code.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
-
import {
|
|
2
|
+
import { codeParser } from '../utils/codeparser.js'; // ✅ Default import
|
|
3
3
|
|
|
4
4
|
// Event definitions
|
|
5
5
|
const TRIGGER_EVENTS = [] as const;
|
|
@@ -103,8 +103,8 @@ export class Code extends BaseComponent<CodeState> {
|
|
|
103
103
|
/**
|
|
104
104
|
* Parse code content into individual lines with tokens
|
|
105
105
|
*/
|
|
106
|
-
private _parseLines(): ReturnType<typeof
|
|
107
|
-
return
|
|
106
|
+
private _parseLines(): ReturnType<typeof codeParser.parse> {
|
|
107
|
+
return codeParser.parse(this.state.content, this.state.language);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
/**
|
|
@@ -124,21 +124,16 @@ export class Code extends BaseComponent<CodeState> {
|
|
|
124
124
|
parsedLines.forEach((parsedLine, index) => {
|
|
125
125
|
const lineNumber = startLine + index;
|
|
126
126
|
const isHighlighted = highlightLines.includes(lineNumber);
|
|
127
|
-
|
|
128
127
|
const lineEl = this._createLineElement(parsedLine, lineNumber, isHighlighted);
|
|
129
128
|
codeEl.appendChild(lineEl);
|
|
130
129
|
});
|
|
131
130
|
|
|
132
|
-
// Re-run Prism if available
|
|
133
|
-
if ((window as any).Prism && this._codeContainer) {
|
|
134
|
-
(window as any).Prism.highlightAllUnder(this._codeContainer);
|
|
135
|
-
}
|
|
136
131
|
}
|
|
137
132
|
|
|
138
133
|
/**
|
|
139
134
|
* Create a single line element with parsed tokens
|
|
140
135
|
*/
|
|
141
|
-
private _createLineElement(parsedLine: ReturnType<typeof
|
|
136
|
+
private _createLineElement(parsedLine: ReturnType<typeof codeParser.parse>[0], lineNumber: number, highlighted: boolean): HTMLElement {
|
|
142
137
|
const lineEl = document.createElement('div');
|
|
143
138
|
lineEl.className = 'jux-code-line';
|
|
144
139
|
lineEl.setAttribute('data-line', String(lineNumber));
|
|
@@ -158,7 +153,7 @@ export class Code extends BaseComponent<CodeState> {
|
|
|
158
153
|
// Line content with syntax highlighting
|
|
159
154
|
const lineCode = document.createElement('span');
|
|
160
155
|
lineCode.className = 'jux-code-line-content';
|
|
161
|
-
lineCode.innerHTML =
|
|
156
|
+
lineCode.innerHTML = codeParser.renderLine(parsedLine);
|
|
162
157
|
lineEl.appendChild(lineCode);
|
|
163
158
|
|
|
164
159
|
return lineEl;
|
|
@@ -189,7 +184,7 @@ export class Code extends BaseComponent<CodeState> {
|
|
|
189
184
|
if (!Code._syntaxCSSInjected) {
|
|
190
185
|
const style = document.createElement('style');
|
|
191
186
|
style.id = 'jux-code-syntax-css';
|
|
192
|
-
style.textContent =
|
|
187
|
+
style.textContent = codeParser.getCSS();
|
|
193
188
|
document.head.appendChild(style);
|
|
194
189
|
Code._syntaxCSSInjected = true;
|
|
195
190
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token type to CSS class mapping
|
|
3
|
+
*/
|
|
4
|
+
export declare const TOKEN_CLASS_MAP: Record<string, string>;
|
|
1
5
|
export interface ParsedToken {
|
|
2
6
|
type: string;
|
|
3
7
|
value: string;
|
|
@@ -12,17 +16,45 @@ export interface ParsedLine {
|
|
|
12
16
|
tokens: ParsedToken[];
|
|
13
17
|
raw: string;
|
|
14
18
|
}
|
|
19
|
+
export declare class CodeParser {
|
|
20
|
+
private static _cache;
|
|
21
|
+
/**
|
|
22
|
+
* Parse code with caching
|
|
23
|
+
*/
|
|
24
|
+
static parse(code: string, language?: string): ParsedLine[];
|
|
25
|
+
private static _parseCode;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get CSS class for a token
|
|
29
|
+
*/
|
|
30
|
+
export declare function getTokenClass(token: any): string;
|
|
15
31
|
/**
|
|
16
|
-
*
|
|
17
|
-
* Returns token-level information for syntax highlighting
|
|
32
|
+
* Check if a word is a JavaScript keyword
|
|
18
33
|
*/
|
|
19
|
-
export declare function
|
|
34
|
+
export declare function isKeyword(word: string): boolean;
|
|
20
35
|
/**
|
|
21
36
|
* Render a parsed line as HTML with spans
|
|
22
37
|
*/
|
|
23
38
|
export declare function renderLineWithTokens(parsedLine: ParsedLine): string;
|
|
39
|
+
/**
|
|
40
|
+
* Escape HTML entities
|
|
41
|
+
*/
|
|
42
|
+
export declare function escapeHtml(text: string): string;
|
|
24
43
|
/**
|
|
25
44
|
* Generate CSS for syntax highlighting
|
|
26
45
|
*/
|
|
27
46
|
export declare function getSyntaxHighlightCSS(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Main parser export with utilities
|
|
49
|
+
*/
|
|
50
|
+
export declare const codeParser: {
|
|
51
|
+
parse: typeof CodeParser.parse;
|
|
52
|
+
renderLine: typeof renderLineWithTokens;
|
|
53
|
+
getCSS: typeof getSyntaxHighlightCSS;
|
|
54
|
+
getTokenClass: typeof getTokenClass;
|
|
55
|
+
isKeyword: typeof isKeyword;
|
|
56
|
+
escapeHtml: typeof escapeHtml;
|
|
57
|
+
TOKEN_CLASS_MAP: Record<string, string>;
|
|
58
|
+
};
|
|
59
|
+
export default CodeParser;
|
|
28
60
|
//# sourceMappingURL=codeparser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeparser.d.ts","sourceRoot":"","sources":["codeparser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codeparser.d.ts","sourceRoot":"","sources":["codeparser.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAqClD,CAAC;AAEF,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAmC;IAExD;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAqB,GAAG,UAAU,EAAE;IAYzE,OAAO,CAAC,MAAM,CAAC,UAAU;CA2E5B;AACD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAUhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAS/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAiCnE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAmB9C;AAID;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;CAQtB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
package/lib/utils/codeparser.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as acorn from 'acorn';
|
|
|
2
2
|
/**
|
|
3
3
|
* Token type to CSS class mapping
|
|
4
4
|
*/
|
|
5
|
-
const TOKEN_CLASS_MAP = {
|
|
5
|
+
export const TOKEN_CLASS_MAP = {
|
|
6
6
|
// Keywords
|
|
7
7
|
'Keyword': 'token-keyword',
|
|
8
8
|
'this': 'token-keyword',
|
|
@@ -36,80 +36,91 @@ const TOKEN_CLASS_MAP = {
|
|
|
36
36
|
'LineComment': 'token-comment',
|
|
37
37
|
'BlockComment': 'token-comment',
|
|
38
38
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
39
|
+
export class CodeParser {
|
|
40
|
+
/**
|
|
41
|
+
* Parse code with caching
|
|
42
|
+
*/
|
|
43
|
+
static parse(code, language = 'javascript') {
|
|
44
|
+
const cacheKey = `${language}:${code}`;
|
|
45
|
+
if (this._cache.has(cacheKey)) {
|
|
46
|
+
return this._cache.get(cacheKey);
|
|
47
|
+
}
|
|
48
|
+
const result = this._parseCode(code, language);
|
|
49
|
+
this._cache.set(cacheKey, result);
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
static _parseCode(code, language) {
|
|
53
|
+
const lines = [];
|
|
54
|
+
const codeLines = code.split('\n');
|
|
55
|
+
try {
|
|
56
|
+
// Parse with Acorn (supports ES2020+)
|
|
57
|
+
const tokens = [];
|
|
58
|
+
acorn.parse(code, {
|
|
59
|
+
ecmaVersion: 2022,
|
|
60
|
+
sourceType: 'module',
|
|
61
|
+
locations: true,
|
|
62
|
+
ranges: true,
|
|
63
|
+
onToken: tokens,
|
|
64
|
+
onComment: (block, text, start, end, startLoc, endLoc) => {
|
|
65
|
+
tokens.push({
|
|
66
|
+
type: block ? 'BlockComment' : 'LineComment',
|
|
67
|
+
value: text,
|
|
68
|
+
start,
|
|
69
|
+
end,
|
|
70
|
+
loc: { start: startLoc, end: endLoc }
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
// Sort tokens by position
|
|
75
|
+
tokens.sort((a, b) => a.start - b.start);
|
|
76
|
+
// Group tokens by line
|
|
77
|
+
const tokensByLine = new Map();
|
|
78
|
+
tokens.forEach(token => {
|
|
79
|
+
const line = token.loc.start.line;
|
|
80
|
+
const parsedToken = {
|
|
81
|
+
type: token.type.label || token.type,
|
|
82
|
+
value: token.value !== undefined ? String(token.value) : code.substring(token.start, token.end),
|
|
83
|
+
start: token.start,
|
|
84
|
+
end: token.end,
|
|
85
|
+
line: token.loc.start.line,
|
|
86
|
+
column: token.loc.start.column,
|
|
87
|
+
className: getTokenClass(token)
|
|
88
|
+
};
|
|
89
|
+
if (!tokensByLine.has(line)) {
|
|
90
|
+
tokensByLine.set(line, []);
|
|
91
|
+
}
|
|
92
|
+
tokensByLine.get(line).push(parsedToken);
|
|
93
|
+
});
|
|
94
|
+
// Build lines with tokens
|
|
95
|
+
codeLines.forEach((lineText, index) => {
|
|
96
|
+
const lineNumber = index + 1;
|
|
97
|
+
const lineTokens = tokensByLine.get(lineNumber) || [];
|
|
98
|
+
lines.push({
|
|
99
|
+
lineNumber,
|
|
100
|
+
tokens: lineTokens,
|
|
101
|
+
raw: lineText
|
|
62
102
|
});
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
// Sort tokens by position
|
|
66
|
-
tokens.sort((a, b) => a.start - b.start);
|
|
67
|
-
// Group tokens by line
|
|
68
|
-
const tokensByLine = new Map();
|
|
69
|
-
tokens.forEach(token => {
|
|
70
|
-
const line = token.loc.start.line;
|
|
71
|
-
const parsedToken = {
|
|
72
|
-
type: token.type.label || token.type,
|
|
73
|
-
value: token.value !== undefined ? String(token.value) : code.substring(token.start, token.end),
|
|
74
|
-
start: token.start,
|
|
75
|
-
end: token.end,
|
|
76
|
-
line: token.loc.start.line,
|
|
77
|
-
column: token.loc.start.column,
|
|
78
|
-
className: getTokenClass(token)
|
|
79
|
-
};
|
|
80
|
-
if (!tokensByLine.has(line)) {
|
|
81
|
-
tokensByLine.set(line, []);
|
|
82
|
-
}
|
|
83
|
-
tokensByLine.get(line).push(parsedToken);
|
|
84
|
-
});
|
|
85
|
-
// Build lines with tokens
|
|
86
|
-
codeLines.forEach((lineText, index) => {
|
|
87
|
-
const lineNumber = index + 1;
|
|
88
|
-
const lineTokens = tokensByLine.get(lineNumber) || [];
|
|
89
|
-
lines.push({
|
|
90
|
-
lineNumber,
|
|
91
|
-
tokens: lineTokens,
|
|
92
|
-
raw: lineText
|
|
93
103
|
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// Fallback: if parsing fails, return plain lines
|
|
107
|
+
console.warn('[CodeParser] Parse failed, using plain text:', error);
|
|
108
|
+
codeLines.forEach((lineText, index) => {
|
|
109
|
+
lines.push({
|
|
110
|
+
lineNumber: index + 1,
|
|
111
|
+
tokens: [],
|
|
112
|
+
raw: lineText
|
|
113
|
+
});
|
|
104
114
|
});
|
|
105
|
-
}
|
|
115
|
+
}
|
|
116
|
+
return lines;
|
|
106
117
|
}
|
|
107
|
-
return lines;
|
|
108
118
|
}
|
|
119
|
+
CodeParser._cache = new Map();
|
|
109
120
|
/**
|
|
110
121
|
* Get CSS class for a token
|
|
111
122
|
*/
|
|
112
|
-
function getTokenClass(token) {
|
|
123
|
+
export function getTokenClass(token) {
|
|
113
124
|
const type = token.type.label || token.type;
|
|
114
125
|
// Check if it's a keyword
|
|
115
126
|
if (type === 'name' && token.value && isKeyword(token.value)) {
|
|
@@ -121,7 +132,7 @@ function getTokenClass(token) {
|
|
|
121
132
|
/**
|
|
122
133
|
* Check if a word is a JavaScript keyword
|
|
123
134
|
*/
|
|
124
|
-
function isKeyword(word) {
|
|
135
|
+
export function isKeyword(word) {
|
|
125
136
|
const keywords = [
|
|
126
137
|
'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
|
|
127
138
|
'default', 'delete', 'do', 'else', 'export', 'extends', 'finally', 'for',
|
|
@@ -165,7 +176,7 @@ export function renderLineWithTokens(parsedLine) {
|
|
|
165
176
|
/**
|
|
166
177
|
* Escape HTML entities
|
|
167
178
|
*/
|
|
168
|
-
function escapeHtml(text) {
|
|
179
|
+
export function escapeHtml(text) {
|
|
169
180
|
return text
|
|
170
181
|
.replace(/&/g, '&')
|
|
171
182
|
.replace(/</g, '<')
|
|
@@ -196,3 +207,16 @@ export function getSyntaxHighlightCSS() {
|
|
|
196
207
|
}
|
|
197
208
|
`;
|
|
198
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Main parser export with utilities
|
|
212
|
+
*/
|
|
213
|
+
export const codeParser = {
|
|
214
|
+
parse: CodeParser.parse,
|
|
215
|
+
renderLine: renderLineWithTokens,
|
|
216
|
+
getCSS: getSyntaxHighlightCSS,
|
|
217
|
+
getTokenClass,
|
|
218
|
+
isKeyword,
|
|
219
|
+
escapeHtml,
|
|
220
|
+
TOKEN_CLASS_MAP
|
|
221
|
+
};
|
|
222
|
+
export default CodeParser;
|
package/lib/utils/codeparser.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as acorn from 'acorn';
|
|
|
3
3
|
/**
|
|
4
4
|
* Token type to CSS class mapping
|
|
5
5
|
*/
|
|
6
|
-
const TOKEN_CLASS_MAP: Record<string, string> = {
|
|
6
|
+
export const TOKEN_CLASS_MAP: Record<string, string> = {
|
|
7
7
|
// Keywords
|
|
8
8
|
'Keyword': 'token-keyword',
|
|
9
9
|
'this': 'token-keyword',
|
|
@@ -58,90 +58,104 @@ export interface ParsedLine {
|
|
|
58
58
|
raw: string;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
61
|
+
export class CodeParser {
|
|
62
|
+
private static _cache = new Map<string, ParsedLine[]>();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parse code with caching
|
|
66
|
+
*/
|
|
67
|
+
static parse(code: string, language: string = 'javascript'): ParsedLine[] {
|
|
68
|
+
const cacheKey = `${language}:${code}`;
|
|
69
|
+
|
|
70
|
+
if (this._cache.has(cacheKey)) {
|
|
71
|
+
return this._cache.get(cacheKey)!;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const result = this._parseCode(code, language);
|
|
75
|
+
this._cache.set(cacheKey, result);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private static _parseCode(code: string, language: string): ParsedLine[] {
|
|
80
|
+
const lines: ParsedLine[] = [];
|
|
81
|
+
const codeLines = code.split('\n');
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// Parse with Acorn (supports ES2020+)
|
|
85
|
+
const tokens: any[] = [];
|
|
86
|
+
|
|
87
|
+
acorn.parse(code, {
|
|
88
|
+
ecmaVersion: 2022,
|
|
89
|
+
sourceType: 'module',
|
|
90
|
+
locations: true,
|
|
91
|
+
ranges: true,
|
|
92
|
+
onToken: tokens,
|
|
93
|
+
onComment: (block, text, start, end, startLoc, endLoc) => {
|
|
94
|
+
tokens.push({
|
|
95
|
+
type: block ? 'BlockComment' : 'LineComment',
|
|
96
|
+
value: text,
|
|
97
|
+
start,
|
|
98
|
+
end,
|
|
99
|
+
loc: { start: startLoc, end: endLoc }
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Sort tokens by position
|
|
105
|
+
tokens.sort((a, b) => a.start - b.start);
|
|
106
|
+
|
|
107
|
+
// Group tokens by line
|
|
108
|
+
const tokensByLine: Map<number, ParsedToken[]> = new Map();
|
|
109
|
+
|
|
110
|
+
tokens.forEach(token => {
|
|
111
|
+
const line = token.loc.start.line;
|
|
112
|
+
const parsedToken: ParsedToken = {
|
|
113
|
+
type: token.type.label || token.type,
|
|
114
|
+
value: token.value !== undefined ? String(token.value) : code.substring(token.start, token.end),
|
|
115
|
+
start: token.start,
|
|
116
|
+
end: token.end,
|
|
117
|
+
line: token.loc.start.line,
|
|
118
|
+
column: token.loc.start.column,
|
|
119
|
+
className: getTokenClass(token)
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
if (!tokensByLine.has(line)) {
|
|
123
|
+
tokensByLine.set(line, []);
|
|
124
|
+
}
|
|
125
|
+
tokensByLine.get(line)!.push(parsedToken);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Build lines with tokens
|
|
129
|
+
codeLines.forEach((lineText, index) => {
|
|
130
|
+
const lineNumber = index + 1;
|
|
131
|
+
const lineTokens = tokensByLine.get(lineNumber) || [];
|
|
132
|
+
|
|
133
|
+
lines.push({
|
|
134
|
+
lineNumber,
|
|
135
|
+
tokens: lineTokens,
|
|
136
|
+
raw: lineText
|
|
86
137
|
});
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Sort tokens by position
|
|
91
|
-
tokens.sort((a, b) => a.start - b.start);
|
|
92
|
-
|
|
93
|
-
// Group tokens by line
|
|
94
|
-
const tokensByLine: Map<number, ParsedToken[]> = new Map();
|
|
95
|
-
|
|
96
|
-
tokens.forEach(token => {
|
|
97
|
-
const line = token.loc.start.line;
|
|
98
|
-
const parsedToken: ParsedToken = {
|
|
99
|
-
type: token.type.label || token.type,
|
|
100
|
-
value: token.value !== undefined ? String(token.value) : code.substring(token.start, token.end),
|
|
101
|
-
start: token.start,
|
|
102
|
-
end: token.end,
|
|
103
|
-
line: token.loc.start.line,
|
|
104
|
-
column: token.loc.start.column,
|
|
105
|
-
className: getTokenClass(token)
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
if (!tokensByLine.has(line)) {
|
|
109
|
-
tokensByLine.set(line, []);
|
|
110
|
-
}
|
|
111
|
-
tokensByLine.get(line)!.push(parsedToken);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Build lines with tokens
|
|
115
|
-
codeLines.forEach((lineText, index) => {
|
|
116
|
-
const lineNumber = index + 1;
|
|
117
|
-
const lineTokens = tokensByLine.get(lineNumber) || [];
|
|
118
|
-
|
|
119
|
-
lines.push({
|
|
120
|
-
lineNumber,
|
|
121
|
-
tokens: lineTokens,
|
|
122
|
-
raw: lineText
|
|
123
138
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
|
|
140
|
+
} catch (error) {
|
|
141
|
+
// Fallback: if parsing fails, return plain lines
|
|
142
|
+
console.warn('[CodeParser] Parse failed, using plain text:', error);
|
|
143
|
+
codeLines.forEach((lineText, index) => {
|
|
144
|
+
lines.push({
|
|
145
|
+
lineNumber: index + 1,
|
|
146
|
+
tokens: [],
|
|
147
|
+
raw: lineText
|
|
148
|
+
});
|
|
134
149
|
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
150
|
+
}
|
|
137
151
|
|
|
138
|
-
|
|
152
|
+
return lines;
|
|
153
|
+
}
|
|
139
154
|
}
|
|
140
|
-
|
|
141
155
|
/**
|
|
142
156
|
* Get CSS class for a token
|
|
143
157
|
*/
|
|
144
|
-
function getTokenClass(token: any): string {
|
|
158
|
+
export function getTokenClass(token: any): string {
|
|
145
159
|
const type = token.type.label || token.type;
|
|
146
160
|
|
|
147
161
|
// Check if it's a keyword
|
|
@@ -156,7 +170,7 @@ function getTokenClass(token: any): string {
|
|
|
156
170
|
/**
|
|
157
171
|
* Check if a word is a JavaScript keyword
|
|
158
172
|
*/
|
|
159
|
-
function isKeyword(word: string): boolean {
|
|
173
|
+
export function isKeyword(word: string): boolean {
|
|
160
174
|
const keywords = [
|
|
161
175
|
'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
|
|
162
176
|
'default', 'delete', 'do', 'else', 'export', 'extends', 'finally', 'for',
|
|
@@ -208,7 +222,7 @@ export function renderLineWithTokens(parsedLine: ParsedLine): string {
|
|
|
208
222
|
/**
|
|
209
223
|
* Escape HTML entities
|
|
210
224
|
*/
|
|
211
|
-
function escapeHtml(text: string): string {
|
|
225
|
+
export function escapeHtml(text: string): string {
|
|
212
226
|
return text
|
|
213
227
|
.replace(/&/g, '&')
|
|
214
228
|
.replace(/</g, '<')
|
|
@@ -240,3 +254,20 @@ export function getSyntaxHighlightCSS(): string {
|
|
|
240
254
|
}
|
|
241
255
|
`;
|
|
242
256
|
}
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Main parser export with utilities
|
|
262
|
+
*/
|
|
263
|
+
export const codeParser = {
|
|
264
|
+
parse: CodeParser.parse,
|
|
265
|
+
renderLine: renderLineWithTokens,
|
|
266
|
+
getCSS: getSyntaxHighlightCSS,
|
|
267
|
+
getTokenClass,
|
|
268
|
+
isKeyword,
|
|
269
|
+
escapeHtml,
|
|
270
|
+
TOKEN_CLASS_MAP
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
export default CodeParser;
|