@principal-ai/principal-view-react 0.16.45 → 0.16.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/dist/subsystem/ComponentDeclaration.d.ts +3 -1
- package/dist/subsystem/ComponentDeclaration.d.ts.map +1 -1
- package/dist/subsystem/ComponentDeclaration.js +49 -75
- package/dist/subsystem/ComponentDeclaration.js.map +1 -1
- package/dist/subsystem/formatDeclaration.d.ts +11 -0
- package/dist/subsystem/formatDeclaration.d.ts.map +1 -0
- package/dist/subsystem/formatDeclaration.js +96 -0
- package/dist/subsystem/formatDeclaration.js.map +1 -0
- package/dist/subsystem/model.d.ts +11 -0
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/tokenizeComponent.d.ts +19 -0
- package/dist/subsystem/tokenizeComponent.d.ts.map +1 -0
- package/dist/subsystem/tokenizeComponent.js +61 -0
- package/dist/subsystem/tokenizeComponent.js.map +1 -0
- package/dist/subsystem/tokenizeFormatted.d.ts +15 -0
- package/dist/subsystem/tokenizeFormatted.d.ts.map +1 -0
- package/dist/subsystem/tokenizeFormatted.js +84 -0
- package/dist/subsystem/tokenizeFormatted.js.map +1 -0
- package/package.json +3 -2
- package/src/stories/ComponentDeclarationAudit.stories.tsx +290 -0
- package/src/subsystem/ComponentDeclaration.tsx +61 -269
- package/src/subsystem/formatDeclaration.ts +116 -0
- package/src/subsystem/model.ts +24 -0
- package/src/subsystem/tokenizeComponent.ts +70 -0
- package/src/subsystem/tokenizeFormatted.ts +92 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tokenize a formatted TypeScript declaration string into SubsystemDeclToken[]
|
|
3
|
+
* using highlight.js.
|
|
4
|
+
*
|
|
5
|
+
* highlight.js produces HTML with `<span class="hljs-...">` wrappers. This
|
|
6
|
+
* module parses that output into our token format so the renderer stays
|
|
7
|
+
* language-agnostic.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import hljs from 'highlight.js/lib/core';
|
|
11
|
+
import typescript from 'highlight.js/lib/languages/typescript';
|
|
12
|
+
import type { SubsystemDeclToken, SubsystemDeclTokenKind } from './model';
|
|
13
|
+
|
|
14
|
+
// Register once — safe to call multiple times.
|
|
15
|
+
try {
|
|
16
|
+
hljs.registerLanguage('typescript', typescript);
|
|
17
|
+
} catch {
|
|
18
|
+
// Already registered.
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// hljs class → our token kind
|
|
22
|
+
const CLASS_MAP: Record<string, SubsystemDeclTokenKind> = {
|
|
23
|
+
'hljs-keyword': 'keyword',
|
|
24
|
+
'hljs-title': 'name',
|
|
25
|
+
'hljs-title.function_': 'name',
|
|
26
|
+
'hljs-params': 'member',
|
|
27
|
+
'hljs-type': 'type',
|
|
28
|
+
'hljs-built_in': 'type',
|
|
29
|
+
'hljs-string': 'string',
|
|
30
|
+
'hljs-number': 'string',
|
|
31
|
+
'hljs-comment': 'punctuation',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Tokenize a formatted TypeScript string into SubsystemDeclToken[].
|
|
36
|
+
* The input should already be formatted by Prettier (or be valid TS).
|
|
37
|
+
*/
|
|
38
|
+
export function tokenizeFormatted(code: string): SubsystemDeclToken[] {
|
|
39
|
+
const result = hljs.highlight(code, { language: 'typescript' });
|
|
40
|
+
return parseHighlightedHtml(result.value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// HTML parser — walks the hljs output and extracts tokens
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
function unescapeHtml(text: string): string {
|
|
48
|
+
return text
|
|
49
|
+
.replace(/"/g, '"')
|
|
50
|
+
.replace(/</g, '<')
|
|
51
|
+
.replace(/>/g, '>')
|
|
52
|
+
.replace(/&/g, '&')
|
|
53
|
+
.replace(/'/g, "'");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function parseHighlightedHtml(html: string): SubsystemDeclToken[] {
|
|
57
|
+
const tokens: SubsystemDeclToken[] = [];
|
|
58
|
+
// Regex matches either `<span class="hljs-...">`, `</span>`, or text content.
|
|
59
|
+
const re = /<span class="([^"]+)">|<\/span>|[^<]+/g;
|
|
60
|
+
const classStack: string[] = [];
|
|
61
|
+
let match: RegExpExecArray | null;
|
|
62
|
+
|
|
63
|
+
while ((match = re.exec(html)) !== null) {
|
|
64
|
+
const chunk = match[0];
|
|
65
|
+
|
|
66
|
+
if (chunk.startsWith('<span')) {
|
|
67
|
+
// Opening tag — push class onto stack.
|
|
68
|
+
classStack.push(match[1]);
|
|
69
|
+
} else if (chunk === '</span>') {
|
|
70
|
+
// Closing tag — pop class.
|
|
71
|
+
classStack.pop();
|
|
72
|
+
} else {
|
|
73
|
+
// Text content — emit tokens for each line segment.
|
|
74
|
+
const currentClass = classStack[classStack.length - 1] ?? '';
|
|
75
|
+
const kind = CLASS_MAP[currentClass] ?? 'punctuation';
|
|
76
|
+
const text = chunk;
|
|
77
|
+
|
|
78
|
+
// Split on newlines so each line becomes its own token set.
|
|
79
|
+
const lines = text.split('\n');
|
|
80
|
+
for (let i = 0; i < lines.length; i++) {
|
|
81
|
+
if (i > 0) {
|
|
82
|
+
tokens.push({ text: '', kind: 'newline' });
|
|
83
|
+
}
|
|
84
|
+
if (lines[i]) {
|
|
85
|
+
tokens.push({ text: unescapeHtml(lines[i]), kind });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return tokens;
|
|
92
|
+
}
|