juxscript 1.1.315 → 1.1.317
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/lib/components/grid.js +2 -2
- package/dist/lib/components/tag.d.ts.map +1 -1
- package/dist/lib/components/tag.js +50 -1
- package/dist/lib/utils/codeHighlight.d.ts +7 -0
- package/dist/lib/utils/codeHighlight.d.ts.map +1 -0
- package/dist/lib/utils/codeHighlight.js +105 -0
- package/package.json +1 -1
|
@@ -21,7 +21,7 @@ class Grid {
|
|
|
21
21
|
// Resolve columns
|
|
22
22
|
const cols = this.opts.cols;
|
|
23
23
|
let templateCols;
|
|
24
|
-
if (Array.isArray(cols)) {
|
|
24
|
+
if (cols && typeof cols === 'object' && Array.isArray(cols)) {
|
|
25
25
|
this._columns = cols.map(c => ({
|
|
26
26
|
name: c.name,
|
|
27
27
|
width: c.width || '1fr'
|
|
@@ -29,7 +29,7 @@ class Grid {
|
|
|
29
29
|
templateCols = this._columns.map(c => c.width).join(' ');
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
|
-
const count = cols
|
|
32
|
+
const count = typeof cols === 'number' ? cols : 2;
|
|
33
33
|
templateCols = `repeat(${count}, 1fr)`;
|
|
34
34
|
}
|
|
35
35
|
const d = DENSITY_MAP[this.opts.density] || DENSITY_MAP.normal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../../lib/components/tag.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../../lib/components/tag.ts"],"names":[],"mappings":"AAIA,UAAU,UAAU;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,cAAM,GAAG;IACL,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe;IAOjE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC5B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAG1B,QAAQ,IAAI,MAAM;IAClB,UAAU,IAAI,MAAM;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC3B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAE/B,UAAU,IAAI,WAAW,GAAG,IAAI;IAEhC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;CAuBvC;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAKxE;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAqC;AAC7F,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAsC;AAC/F,wBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAmC;AAEzF,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAoDxD;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAqC;AAC7F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAE3F,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAC3B,eAAe,GAAG,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import generateId from '../utils/idgen.js';
|
|
2
2
|
import { pageState } from '../state/pageState.js';
|
|
3
|
+
import highlightCode from '../utils/codeHighlight.js';
|
|
3
4
|
class Tag {
|
|
4
5
|
constructor(id, tagName, options = {}) {
|
|
5
6
|
this._element = null;
|
|
@@ -60,7 +61,55 @@ export function tag(id, tagName, options = {}) {
|
|
|
60
61
|
export function div(id, options = {}) { return tag(id, 'div', options); }
|
|
61
62
|
export function span(id, options = {}) { return tag(id, 'span', options); }
|
|
62
63
|
export function p(id, options = {}) { return tag(id, 'p', options); }
|
|
63
|
-
export function code(id, options = {}) {
|
|
64
|
+
export function code(id, options = {}) {
|
|
65
|
+
// Inject highlight styles once
|
|
66
|
+
if (!document.getElementById('__jux-hl-styles')) {
|
|
67
|
+
const style = document.createElement('style');
|
|
68
|
+
style.id = '__jux-hl-styles';
|
|
69
|
+
style.textContent = `
|
|
70
|
+
.jux-code {
|
|
71
|
+
display: block;
|
|
72
|
+
background: hsl(var(--muted, 0 0% 96%));
|
|
73
|
+
border: 1px solid hsl(var(--border, 0 0% 89.8%));
|
|
74
|
+
border-radius: var(--radius, 6px);
|
|
75
|
+
padding: 12px 16px;
|
|
76
|
+
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
|
|
77
|
+
font-size: 13px;
|
|
78
|
+
line-height: 1.5;
|
|
79
|
+
overflow-x: auto;
|
|
80
|
+
white-space: pre;
|
|
81
|
+
tab-size: 2;
|
|
82
|
+
}
|
|
83
|
+
.jux-hl-keyword { color: hsl(var(--primary, 262 83% 58%)); font-weight: 600; }
|
|
84
|
+
.jux-hl-string { color: hsl(142 71% 45%); }
|
|
85
|
+
.jux-hl-number { color: hsl(25 95% 53%); }
|
|
86
|
+
.jux-hl-comment { color: hsl(var(--muted-foreground, 0 0% 45%)); font-style: italic; }
|
|
87
|
+
.jux-hl-fn { color: hsl(221 83% 53%); }
|
|
88
|
+
.jux-hl-punct { color: hsl(var(--muted-foreground, 0 0% 45%)); }
|
|
89
|
+
.jux-hl-ident { color: hsl(var(--foreground, 0 0% 9%)); }
|
|
90
|
+
`;
|
|
91
|
+
document.head.appendChild(style);
|
|
92
|
+
}
|
|
93
|
+
// Highlight content and render as innerHTML
|
|
94
|
+
const raw = options.content || '';
|
|
95
|
+
const trimmed = raw.replace(/^\n+/, '').replace(/\n+$/, '');
|
|
96
|
+
const highlighted = highlightCode(trimmed);
|
|
97
|
+
// Create as <pre><code> for proper formatting
|
|
98
|
+
const t = new Tag(id, 'pre', {
|
|
99
|
+
...options,
|
|
100
|
+
content: undefined,
|
|
101
|
+
class: `jux-code${options.class ? ' ' + options.class : ''}`
|
|
102
|
+
});
|
|
103
|
+
t.render();
|
|
104
|
+
const el = t.getElement();
|
|
105
|
+
if (el) {
|
|
106
|
+
const codeEl = document.createElement('code');
|
|
107
|
+
codeEl.innerHTML = highlighted;
|
|
108
|
+
el.appendChild(codeEl);
|
|
109
|
+
}
|
|
110
|
+
pageState.__register(t);
|
|
111
|
+
return t;
|
|
112
|
+
}
|
|
64
113
|
export function pre(id, options = {}) { return tag(id, 'pre', options); }
|
|
65
114
|
export function h1(id, options = {}) { return tag(id, 'h1', options); }
|
|
66
115
|
export function h2(id, options = {}) { return tag(id, 'h2', options); }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight syntax highlighter for JS/TS code blocks.
|
|
3
|
+
* Returns HTML string with <span class="jux-hl-xxx"> wrappers.
|
|
4
|
+
*/
|
|
5
|
+
export declare function highlightCode(code: string): string;
|
|
6
|
+
export default highlightCode;
|
|
7
|
+
//# sourceMappingURL=codeHighlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeHighlight.d.ts","sourceRoot":"","sources":["../../../lib/utils/codeHighlight.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmFlD;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight syntax highlighter for JS/TS code blocks.
|
|
3
|
+
* Returns HTML string with <span class="jux-hl-xxx"> wrappers.
|
|
4
|
+
*/
|
|
5
|
+
const KEYWORDS = new Set([
|
|
6
|
+
'const', 'let', 'var', 'function', 'return', 'if', 'else', 'for', 'while', 'do',
|
|
7
|
+
'switch', 'case', 'break', 'continue', 'new', 'delete', 'typeof', 'instanceof',
|
|
8
|
+
'import', 'export', 'from', 'default', 'class', 'extends', 'super', 'this',
|
|
9
|
+
'try', 'catch', 'finally', 'throw', 'async', 'await', 'yield',
|
|
10
|
+
'true', 'false', 'null', 'undefined', 'void', 'of', 'in'
|
|
11
|
+
]);
|
|
12
|
+
function escapeHtml(str) {
|
|
13
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
14
|
+
}
|
|
15
|
+
export function highlightCode(code) {
|
|
16
|
+
const out = [];
|
|
17
|
+
let i = 0;
|
|
18
|
+
const len = code.length;
|
|
19
|
+
while (i < len) {
|
|
20
|
+
const ch = code[i];
|
|
21
|
+
// Single-line comment
|
|
22
|
+
if (ch === '/' && code[i + 1] === '/') {
|
|
23
|
+
let end = code.indexOf('\n', i);
|
|
24
|
+
if (end === -1)
|
|
25
|
+
end = len;
|
|
26
|
+
out.push(`<span class="jux-hl-comment">${escapeHtml(code.slice(i, end))}</span>`);
|
|
27
|
+
i = end;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
// Multi-line comment
|
|
31
|
+
if (ch === '/' && code[i + 1] === '*') {
|
|
32
|
+
let end = code.indexOf('*/', i + 2);
|
|
33
|
+
if (end === -1)
|
|
34
|
+
end = len;
|
|
35
|
+
else
|
|
36
|
+
end += 2;
|
|
37
|
+
out.push(`<span class="jux-hl-comment">${escapeHtml(code.slice(i, end))}</span>`);
|
|
38
|
+
i = end;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Strings (single, double, backtick)
|
|
42
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
43
|
+
const quote = ch;
|
|
44
|
+
let j = i + 1;
|
|
45
|
+
while (j < len) {
|
|
46
|
+
if (code[j] === '\\') {
|
|
47
|
+
j += 2;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (code[j] === quote) {
|
|
51
|
+
j++;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
j++;
|
|
55
|
+
}
|
|
56
|
+
out.push(`<span class="jux-hl-string">${escapeHtml(code.slice(i, j))}</span>`);
|
|
57
|
+
i = j;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// Numbers
|
|
61
|
+
if (/[0-9]/.test(ch) && (i === 0 || !/[a-zA-Z_$]/.test(code[i - 1]))) {
|
|
62
|
+
let j = i;
|
|
63
|
+
while (j < len && /[0-9a-fA-FxXoObB._]/.test(code[j]))
|
|
64
|
+
j++;
|
|
65
|
+
out.push(`<span class="jux-hl-number">${escapeHtml(code.slice(i, j))}</span>`);
|
|
66
|
+
i = j;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// Identifiers / keywords
|
|
70
|
+
if (/[a-zA-Z_$]/.test(ch)) {
|
|
71
|
+
let j = i;
|
|
72
|
+
while (j < len && /[a-zA-Z0-9_$]/.test(code[j]))
|
|
73
|
+
j++;
|
|
74
|
+
const word = code.slice(i, j);
|
|
75
|
+
if (KEYWORDS.has(word)) {
|
|
76
|
+
out.push(`<span class="jux-hl-keyword">${escapeHtml(word)}</span>`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Check if it's a function call
|
|
80
|
+
let k = j;
|
|
81
|
+
while (k < len && code[k] === ' ')
|
|
82
|
+
k++;
|
|
83
|
+
if (code[k] === '(') {
|
|
84
|
+
out.push(`<span class="jux-hl-fn">${escapeHtml(word)}</span>`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
out.push(`<span class="jux-hl-ident">${escapeHtml(word)}</span>`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
i = j;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// Punctuation / operators
|
|
94
|
+
if (/[{}()\[\];,.:?!<>=+\-*/%&|^~@#]/.test(ch)) {
|
|
95
|
+
out.push(`<span class="jux-hl-punct">${escapeHtml(ch)}</span>`);
|
|
96
|
+
i++;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
// Whitespace & everything else
|
|
100
|
+
out.push(escapeHtml(ch));
|
|
101
|
+
i++;
|
|
102
|
+
}
|
|
103
|
+
return out.join('');
|
|
104
|
+
}
|
|
105
|
+
export default highlightCode;
|