@fuzdev/fuz_ui 0.198.1 → 0.199.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/dist/ApiIndex.svelte +2 -2
- package/dist/ApiModule.svelte +1 -1
- package/dist/LibraryDetail.svelte +14 -16
- package/dist/LibraryDetail.svelte.d.ts.map +1 -1
- package/dist/LibrarySummary.svelte +12 -12
- package/dist/Mdz.svelte +2 -2
- package/dist/MdzNodeView.svelte +8 -6
- package/dist/MdzNodeView.svelte.d.ts.map +1 -1
- package/dist/MdzRoot.svelte +30 -0
- package/dist/MdzRoot.svelte.d.ts +12 -0
- package/dist/MdzRoot.svelte.d.ts.map +1 -0
- package/dist/MdzStream.svelte +32 -0
- package/dist/MdzStream.svelte.d.ts +12 -0
- package/dist/MdzStream.svelte.d.ts.map +1 -0
- package/dist/MdzStreamNodeView.svelte +106 -0
- package/dist/MdzStreamNodeView.svelte.d.ts +9 -0
- package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -0
- package/dist/declaration.svelte.js +2 -2
- package/dist/library.svelte.d.ts +9 -70
- package/dist/library.svelte.d.ts.map +1 -1
- package/dist/library.svelte.js +24 -18
- package/dist/library_helpers.d.ts +3 -3
- package/dist/library_helpers.js +3 -3
- package/dist/mdz.d.ts.map +1 -1
- package/dist/mdz.js +37 -29
- package/dist/mdz_components.d.ts +37 -23
- package/dist/mdz_components.d.ts.map +1 -1
- package/dist/mdz_components.js +16 -4
- package/dist/mdz_helpers.d.ts +46 -14
- package/dist/mdz_helpers.d.ts.map +1 -1
- package/dist/mdz_helpers.js +189 -56
- package/dist/mdz_lexer.d.ts.map +1 -1
- package/dist/mdz_lexer.js +18 -22
- package/dist/mdz_opcodes.d.ts +174 -0
- package/dist/mdz_opcodes.d.ts.map +1 -0
- package/dist/mdz_opcodes.js +14 -0
- package/dist/mdz_opcodes_to_nodes.d.ts +20 -0
- package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -0
- package/dist/mdz_opcodes_to_nodes.js +332 -0
- package/dist/mdz_stream_parser.d.ts +80 -0
- package/dist/mdz_stream_parser.d.ts.map +1 -0
- package/dist/mdz_stream_parser.js +354 -0
- package/dist/mdz_stream_parser_block.d.ts +76 -0
- package/dist/mdz_stream_parser_block.d.ts.map +1 -0
- package/dist/mdz_stream_parser_block.js +458 -0
- package/dist/mdz_stream_parser_inline.d.ts +52 -0
- package/dist/mdz_stream_parser_inline.d.ts.map +1 -0
- package/dist/mdz_stream_parser_inline.js +378 -0
- package/dist/mdz_stream_parser_link.d.ts +22 -0
- package/dist/mdz_stream_parser_link.d.ts.map +1 -0
- package/dist/mdz_stream_parser_link.js +215 -0
- package/dist/mdz_stream_parser_state.d.ts +187 -0
- package/dist/mdz_stream_parser_state.d.ts.map +1 -0
- package/dist/mdz_stream_parser_state.js +398 -0
- package/dist/mdz_stream_parser_text.d.ts +14 -0
- package/dist/mdz_stream_parser_text.d.ts.map +1 -0
- package/dist/mdz_stream_parser_text.js +50 -0
- package/dist/mdz_stream_parser_url.d.ts +60 -0
- package/dist/mdz_stream_parser_url.d.ts.map +1 -0
- package/dist/mdz_stream_parser_url.js +307 -0
- package/dist/mdz_stream_state.svelte.d.ts +44 -0
- package/dist/mdz_stream_state.svelte.d.ts.map +1 -0
- package/dist/mdz_stream_state.svelte.js +357 -0
- package/dist/mdz_token_parser.d.ts.map +1 -1
- package/dist/mdz_token_parser.js +8 -39
- package/dist/module.svelte.js +1 -1
- package/dist/site.svelte.d.ts +13 -0
- package/dist/site.svelte.d.ts.map +1 -1
- package/dist/site.svelte.js +8 -2
- package/dist/tsdoc_mdz.d.ts +2 -2
- package/dist/tsdoc_mdz.js +2 -2
- package/dist/vite_plugin_pkg_json.d.ts +63 -0
- package/dist/vite_plugin_pkg_json.d.ts.map +1 -0
- package/dist/vite_plugin_pkg_json.js +126 -0
- package/package.json +6 -5
- package/src/lib/declaration.svelte.ts +2 -2
- package/src/lib/library.svelte.ts +37 -20
- package/src/lib/library_helpers.ts +3 -3
- package/src/lib/mdz.ts +38 -29
- package/src/lib/mdz_components.ts +40 -19
- package/src/lib/mdz_helpers.ts +199 -56
- package/src/lib/mdz_lexer.ts +18 -20
- package/src/lib/mdz_opcodes.ts +205 -0
- package/src/lib/mdz_opcodes_to_nodes.ts +375 -0
- package/src/lib/mdz_stream_parser.ts +415 -0
- package/src/lib/mdz_stream_parser_block.ts +532 -0
- package/src/lib/mdz_stream_parser_inline.ts +414 -0
- package/src/lib/mdz_stream_parser_link.ts +271 -0
- package/src/lib/mdz_stream_parser_state.ts +539 -0
- package/src/lib/mdz_stream_parser_text.ts +77 -0
- package/src/lib/mdz_stream_parser_url.ts +365 -0
- package/src/lib/mdz_stream_state.svelte.ts +387 -0
- package/src/lib/mdz_token_parser.ts +13 -40
- package/src/lib/module.svelte.ts +1 -1
- package/src/lib/site.svelte.ts +17 -2
- package/src/lib/tsdoc_mdz.ts +2 -2
- package/src/lib/vite_plugin_pkg_json.ts +142 -0
- package/dist/package_helpers.d.ts +0 -150
- package/dist/package_helpers.d.ts.map +0 -1
- package/dist/package_helpers.js +0 -179
- package/src/lib/package_helpers.ts +0 -186
package/dist/mdz_helpers.js
CHANGED
|
@@ -51,6 +51,47 @@ export const MIN_CODEBLOCK_BACKTICKS = 3; // Code blocks require minimum 3 backt
|
|
|
51
51
|
export const MAX_HEADING_LEVEL = 6; // Headings support levels 1-6
|
|
52
52
|
export const HTTPS_PREFIX_LENGTH = 8; // Length of "https://"
|
|
53
53
|
export const HTTP_PREFIX_LENGTH = 7; // Length of "http://"
|
|
54
|
+
export const H_LOWER = 104; // h
|
|
55
|
+
export const H_UPPER = 72; // H
|
|
56
|
+
/**
|
|
57
|
+
* Lowercase an ASCII letter code; passes other chars through.
|
|
58
|
+
* Mirrors the `[A-Z] → [a-z]` shift without touching non-ASCII.
|
|
59
|
+
*/
|
|
60
|
+
export const ascii_to_lower = (char_code) => char_code >= A_UPPER && char_code <= Z_UPPER ? char_code + 32 : char_code;
|
|
61
|
+
/**
|
|
62
|
+
* Case-insensitive URL scheme prefix check. Returns the prefix length
|
|
63
|
+
* (8 for `https://`, 7 for `http://`) or 0 if neither matches at `pos`.
|
|
64
|
+
*
|
|
65
|
+
* URI schemes are case-insensitive per RFC 3986 §3.1, and mobile keyboards
|
|
66
|
+
* routinely auto-capitalize the first letter of a sentence, producing
|
|
67
|
+
* `Https://` etc. The original case is preserved in the emitted reference —
|
|
68
|
+
* browsers normalize schemes themselves.
|
|
69
|
+
*/
|
|
70
|
+
export const match_url_prefix_case_insensitive = (s, pos) => {
|
|
71
|
+
if (pos + HTTP_PREFIX_LENGTH > s.length)
|
|
72
|
+
return 0;
|
|
73
|
+
// h | H
|
|
74
|
+
if (ascii_to_lower(s.charCodeAt(pos)) !== H_LOWER)
|
|
75
|
+
return 0;
|
|
76
|
+
// 'ttps://' (7 chars) or 'ttp://' (6 chars)
|
|
77
|
+
if (ascii_to_lower(s.charCodeAt(pos + 1)) === 116 /* t */ &&
|
|
78
|
+
ascii_to_lower(s.charCodeAt(pos + 2)) === 116 /* t */ &&
|
|
79
|
+
ascii_to_lower(s.charCodeAt(pos + 3)) === 112 /* p */) {
|
|
80
|
+
if (pos + HTTPS_PREFIX_LENGTH <= s.length &&
|
|
81
|
+
ascii_to_lower(s.charCodeAt(pos + 4)) === 115 /* s */ &&
|
|
82
|
+
s.charCodeAt(pos + 5) === COLON &&
|
|
83
|
+
s.charCodeAt(pos + 6) === SLASH &&
|
|
84
|
+
s.charCodeAt(pos + 7) === SLASH) {
|
|
85
|
+
return HTTPS_PREFIX_LENGTH;
|
|
86
|
+
}
|
|
87
|
+
if (s.charCodeAt(pos + 4) === COLON &&
|
|
88
|
+
s.charCodeAt(pos + 5) === SLASH &&
|
|
89
|
+
s.charCodeAt(pos + 6) === SLASH) {
|
|
90
|
+
return HTTP_PREFIX_LENGTH;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return 0;
|
|
94
|
+
};
|
|
54
95
|
/**
|
|
55
96
|
* Check if character code is a letter (A-Z, a-z).
|
|
56
97
|
*/
|
|
@@ -66,22 +107,19 @@ export const is_tag_name_char = (char_code) => is_letter(char_code) ||
|
|
|
66
107
|
* Check if character is part of a word for word boundary detection.
|
|
67
108
|
* Used to prevent intraword emphasis with `_` and `~` delimiters.
|
|
68
109
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
110
|
+
* Only alphanumeric characters (A-Z, a-z, 0-9) are word characters.
|
|
111
|
+
* Formatting delimiters (`*`, `_`, `~`) fall outside all three ranges,
|
|
112
|
+
* so they're naturally excluded without explicit checks.
|
|
71
113
|
*
|
|
72
114
|
* This prevents false positives with snake_case identifiers while allowing
|
|
73
115
|
* adjacent formatting like `**bold**_italic_`.
|
|
74
116
|
*/
|
|
75
|
-
export const is_word_char = (char_code) =>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return ((char_code >= A_UPPER && char_code <= Z_UPPER) ||
|
|
79
|
-
(char_code >= A_LOWER && char_code <= Z_LOWER) ||
|
|
80
|
-
(char_code >= ZERO && char_code <= NINE));
|
|
81
|
-
};
|
|
117
|
+
export const is_word_char = (char_code) => (char_code >= A_UPPER && char_code <= Z_UPPER) ||
|
|
118
|
+
(char_code >= A_LOWER && char_code <= Z_LOWER) ||
|
|
119
|
+
(char_code >= ZERO && char_code <= NINE);
|
|
82
120
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
121
|
+
* Lookup table for valid URI path characters per RFC 3986.
|
|
122
|
+
* Replaces a 16-comparison chain with a single array access.
|
|
85
123
|
*
|
|
86
124
|
* Valid characters:
|
|
87
125
|
* - unreserved: A-Z a-z 0-9 - . _ ~
|
|
@@ -90,41 +128,59 @@ export const is_word_char = (char_code) => {
|
|
|
90
128
|
* - separators: / ? #
|
|
91
129
|
* - percent-encoding: %
|
|
92
130
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
131
|
+
const PATH_CHAR_TABLE = (() => {
|
|
132
|
+
const t = new Uint8Array(128);
|
|
133
|
+
for (let i = A_UPPER; i <= Z_UPPER; i++)
|
|
134
|
+
t[i] = 1;
|
|
135
|
+
for (let i = A_LOWER; i <= Z_LOWER; i++)
|
|
136
|
+
t[i] = 1;
|
|
137
|
+
for (let i = ZERO; i <= NINE; i++)
|
|
138
|
+
t[i] = 1;
|
|
139
|
+
// unreserved: - . _ ~
|
|
140
|
+
t[HYPHEN] = 1;
|
|
141
|
+
t[PERIOD] = 1;
|
|
142
|
+
t[UNDERSCORE] = 1;
|
|
143
|
+
t[TILDE] = 1;
|
|
144
|
+
// sub-delims: ! $ & ' ( ) * + , ; =
|
|
145
|
+
t[EXCLAMATION] = 1;
|
|
146
|
+
t[DOLLAR] = 1;
|
|
147
|
+
t[AMPERSAND] = 1;
|
|
148
|
+
t[APOSTROPHE] = 1;
|
|
149
|
+
t[LEFT_PAREN] = 1;
|
|
150
|
+
t[RIGHT_PAREN] = 1;
|
|
151
|
+
t[ASTERISK] = 1;
|
|
152
|
+
t[PLUS] = 1;
|
|
153
|
+
t[COMMA] = 1;
|
|
154
|
+
t[SEMICOLON] = 1;
|
|
155
|
+
t[EQUALS] = 1;
|
|
156
|
+
// path allowed: : @
|
|
157
|
+
t[COLON] = 1;
|
|
158
|
+
t[AT] = 1;
|
|
159
|
+
// separators: / ? #
|
|
160
|
+
t[SLASH] = 1;
|
|
161
|
+
t[QUESTION] = 1;
|
|
162
|
+
t[HASH] = 1;
|
|
163
|
+
// percent-encoding: %
|
|
164
|
+
t[PERCENT] = 1;
|
|
165
|
+
return t;
|
|
166
|
+
})();
|
|
167
|
+
export const is_valid_path_char = (char_code) => char_code < 128 && PATH_CHAR_TABLE[char_code] === 1;
|
|
117
168
|
/**
|
|
118
169
|
* Trim trailing punctuation from URL/path per RFC 3986 and GFM rules.
|
|
119
170
|
* - Trims simple trailing: .,;:!?]
|
|
120
171
|
* - Balanced logic for () only (valid in path components)
|
|
121
|
-
*
|
|
172
|
+
*
|
|
173
|
+
* Note on `]`: the mdz parsers (`mdz.ts`, `mdz_stream_parser_url.ts`,
|
|
174
|
+
* `mdz_lexer.ts`) scan URL/path chars through `is_valid_path_char`, which
|
|
175
|
+
* already rejects `]` — so it can never reach this function via parser flow.
|
|
176
|
+
* The `]` branch here is for external callers using this helper directly on
|
|
177
|
+
* arbitrary URL-ish input (it is part of the published `@fuzdev/fuz_ui`
|
|
178
|
+
* surface, see `mdz_helpers.test.ts` for direct coverage).
|
|
122
179
|
*
|
|
123
180
|
* Optimized to avoid O(n²) string slicing - tracks end index and slices once at the end.
|
|
124
181
|
*/
|
|
125
182
|
export const trim_trailing_punctuation = (url) => {
|
|
126
183
|
let end = url.length;
|
|
127
|
-
// Trim simple trailing punctuation (] as fallback - whitelist should prevent it)
|
|
128
184
|
while (end > 0) {
|
|
129
185
|
const last_char = url.charCodeAt(end - 1);
|
|
130
186
|
if (last_char === PERIOD ||
|
|
@@ -141,25 +197,28 @@ export const trim_trailing_punctuation = (url) => {
|
|
|
141
197
|
}
|
|
142
198
|
}
|
|
143
199
|
// Handle balanced parentheses ONLY (parens are valid in URI path components)
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
while (end > 0 && close_count > open_count) {
|
|
156
|
-
const last_char = url.charCodeAt(end - 1);
|
|
157
|
-
if (last_char === RIGHT_PAREN) {
|
|
158
|
-
end--;
|
|
159
|
-
close_count--;
|
|
200
|
+
// Only count parens when the trimmed URL ends with ')' — otherwise the
|
|
201
|
+
// trailing-paren loop below can't trim anything.
|
|
202
|
+
if (end > 0 && url.charCodeAt(end - 1) === RIGHT_PAREN) {
|
|
203
|
+
let open_count = 0;
|
|
204
|
+
let close_count = 0;
|
|
205
|
+
for (let i = 0; i < end; i++) {
|
|
206
|
+
const char = url.charCodeAt(i);
|
|
207
|
+
if (char === LEFT_PAREN)
|
|
208
|
+
open_count++;
|
|
209
|
+
if (char === RIGHT_PAREN)
|
|
210
|
+
close_count++;
|
|
160
211
|
}
|
|
161
|
-
|
|
162
|
-
|
|
212
|
+
// Trim unmatched trailing closing parens
|
|
213
|
+
while (end > 0 && close_count > open_count) {
|
|
214
|
+
const last_char = url.charCodeAt(end - 1);
|
|
215
|
+
if (last_char === RIGHT_PAREN) {
|
|
216
|
+
end--;
|
|
217
|
+
close_count--;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
163
222
|
}
|
|
164
223
|
}
|
|
165
224
|
// Return original string if no trimming, otherwise slice once
|
|
@@ -228,13 +287,26 @@ export const mdz_text_content = (nodes) => nodes
|
|
|
228
287
|
* For case-preserving IDs (e.g. API declarations), see `docs_slugify` in `docs_helpers.svelte.ts`.
|
|
229
288
|
*/
|
|
230
289
|
export const mdz_heading_id = (nodes) => slugify(mdz_text_content(nodes), false);
|
|
290
|
+
/**
|
|
291
|
+
* Generates a lowercase slug id for a heading from plain text content.
|
|
292
|
+
* Used by the streaming parser which tracks text content directly
|
|
293
|
+
* rather than building `MdzNode[]` trees.
|
|
294
|
+
*/
|
|
295
|
+
export const mdz_heading_id_from_text = (text) => slugify(text, false);
|
|
231
296
|
/**
|
|
232
297
|
* Check if a string is a URL (`https://` or `http://`).
|
|
233
298
|
* Requires at least one valid character after the protocol.
|
|
234
299
|
* Rejects whitespace and characters that can't start a valid hostname.
|
|
235
300
|
*/
|
|
236
|
-
const URL_PATTERN = /^https?:\/\/[^\s)\]}<>.,:/?#!]
|
|
301
|
+
const URL_PATTERN = /^https?:\/\/[^\s)\]}<>.,:/?#!]/i;
|
|
237
302
|
export const mdz_is_url = (s) => URL_PATTERN.test(s);
|
|
303
|
+
/**
|
|
304
|
+
* Check if a link reference is safe to use as an `href` attribute.
|
|
305
|
+
* References without a colon are always safe (paths, fragments, queries).
|
|
306
|
+
* References with a colon must use `http(s)://` — rejects `javascript:`, `data:`, etc.
|
|
307
|
+
*/
|
|
308
|
+
const SAFE_PROTOCOL_PATTERN = /^https?:\/\//i;
|
|
309
|
+
export const mdz_is_safe_reference = (reference) => !reference.includes(':') || SAFE_PROTOCOL_PATTERN.test(reference);
|
|
238
310
|
/**
|
|
239
311
|
* Resolves a relative path (`./` or `../`) against a base path.
|
|
240
312
|
* The base is treated as a directory regardless of trailing slash
|
|
@@ -269,6 +341,67 @@ export const resolve_relative_path = (reference, base) => {
|
|
|
269
341
|
segments.push('');
|
|
270
342
|
return segments.join('/');
|
|
271
343
|
};
|
|
344
|
+
/**
|
|
345
|
+
* Push a node into a children array, coalescing with the previous Text node.
|
|
346
|
+
* Mutates `prev.content` and `prev.end` when both are Text, avoiding array growth
|
|
347
|
+
* and an extra allocation. Callers must own `dest` and not retain references to
|
|
348
|
+
* the prior last element across the call.
|
|
349
|
+
*/
|
|
350
|
+
export const mdz_push_merging_text = (dest, node) => {
|
|
351
|
+
if (node.type === 'Text') {
|
|
352
|
+
const last = dest[dest.length - 1];
|
|
353
|
+
if (last?.type === 'Text') {
|
|
354
|
+
last.content += node.content;
|
|
355
|
+
last.end = node.end;
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
dest.push(node);
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Return a new array with adjacent Text nodes merged into single nodes.
|
|
363
|
+
* Fast path: returns the original array when no merging is needed.
|
|
364
|
+
*/
|
|
365
|
+
export const mdz_merge_adjacent_text = (nodes) => {
|
|
366
|
+
if (nodes.length <= 1)
|
|
367
|
+
return nodes;
|
|
368
|
+
let needs_merge = false;
|
|
369
|
+
for (let i = 1; i < nodes.length; i++) {
|
|
370
|
+
if (nodes[i - 1].type === 'Text' && nodes[i].type === 'Text') {
|
|
371
|
+
needs_merge = true;
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (!needs_merge)
|
|
376
|
+
return nodes;
|
|
377
|
+
const merged = [];
|
|
378
|
+
let pending = null;
|
|
379
|
+
for (const node of nodes) {
|
|
380
|
+
if (node.type === 'Text') {
|
|
381
|
+
if (pending) {
|
|
382
|
+
pending = {
|
|
383
|
+
type: 'Text',
|
|
384
|
+
content: pending.content + node.content,
|
|
385
|
+
start: pending.start,
|
|
386
|
+
end: node.end,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
pending = { ...node };
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
if (pending) {
|
|
395
|
+
merged.push(pending);
|
|
396
|
+
pending = null;
|
|
397
|
+
}
|
|
398
|
+
merged.push(node);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (pending)
|
|
402
|
+
merged.push(pending);
|
|
403
|
+
return merged;
|
|
404
|
+
};
|
|
272
405
|
export const extract_single_tag = (nodes) => {
|
|
273
406
|
let tag = null;
|
|
274
407
|
for (const node of nodes) {
|
package/dist/mdz_lexer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_lexer.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyCH,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,QAAQ,GACjB,YAAY,GACZ,YAAY,GACZ,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,GACnB,yBAAyB,GACzB,0BAA0B,GAC1B,oBAAoB,GACpB,qBAAqB,GACrB,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,UAAU,GACV,eAAe,GACf,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,sBAAsB,CAAC;AAE1B,MAAM,WAAW,YAAa,SAAQ,YAAY;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACtD,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACtD,IAAI,EAAE,YAAY,CAAC;CACnB;AAED,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACvD,IAAI,EAAE,aAAa,CAAC;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACxD,IAAI,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,yBAA0B,SAAQ,YAAY;IAC9D,IAAI,EAAE,oBAAoB,CAAC;CAC3B;AAED,MAAM,WAAW,0BAA2B,SAAQ,YAAY;IAC/D,IAAI,EAAE,qBAAqB,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACzD,IAAI,EAAE,gBAAgB,CAAC;CACvB;AAED,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IAC1D,IAAI,EAAE,iBAAiB,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACpD,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;CACnC;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;CACnC;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACzD,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC/C,IAAI,EAAE,IAAI,CAAC;CACX;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACpD,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACzD,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACvD,IAAI,EAAE,aAAa,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,YAAY;IAC3D,IAAI,EAAE,iBAAiB,CAAC;CACxB;AAMD,qBAAa,QAAQ;;gBAMR,IAAI,EAAE,MAAM;IAIxB,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"mdz_lexer.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_lexer.ts"],"names":[],"mappings":"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"}
|
package/dist/mdz_lexer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import { mdz_is_url, is_letter, is_tag_name_char, is_word_char, is_valid_path_char, trim_trailing_punctuation, BACKTICK, ASTERISK, UNDERSCORE, TILDE, NEWLINE, HYPHEN, HASH, SPACE, TAB, LEFT_ANGLE, RIGHT_ANGLE, SLASH, PERIOD, LEFT_BRACKET, LEFT_PAREN, RIGHT_PAREN, RIGHT_BRACKET, A_UPPER, Z_UPPER, HR_HYPHEN_COUNT, MIN_CODEBLOCK_BACKTICKS, MAX_HEADING_LEVEL,
|
|
9
|
+
import { mdz_is_url, mdz_is_safe_reference, is_letter, is_tag_name_char, is_word_char, is_valid_path_char, trim_trailing_punctuation, BACKTICK, ASTERISK, UNDERSCORE, TILDE, NEWLINE, HYPHEN, HASH, SPACE, TAB, LEFT_ANGLE, RIGHT_ANGLE, SLASH, PERIOD, LEFT_BRACKET, LEFT_PAREN, RIGHT_PAREN, RIGHT_BRACKET, A_UPPER, Z_UPPER, HR_HYPHEN_COUNT, MIN_CODEBLOCK_BACKTICKS, MAX_HEADING_LEVEL, match_url_prefix_case_insensitive, is_at_absolute_path, is_at_relative_path, } from './mdz_helpers.js';
|
|
10
10
|
//
|
|
11
11
|
// Lexer
|
|
12
12
|
//
|
|
@@ -480,6 +480,12 @@ export class MdzLexer {
|
|
|
480
480
|
return;
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
|
+
// Reject unsafe protocols (javascript:, data:, etc.) — `is_valid_path_char`
|
|
484
|
+
// permits `:` so we need an explicit filter here.
|
|
485
|
+
if (!mdz_is_safe_reference(reference)) {
|
|
486
|
+
this.#revert_tokens_from_link_open(start);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
483
489
|
this.#index = close_paren + 1;
|
|
484
490
|
const link_type = mdz_is_url(reference) ? 'external' : 'internal';
|
|
485
491
|
this.#tokens.push({
|
|
@@ -629,7 +635,7 @@ export class MdzLexer {
|
|
|
629
635
|
}
|
|
630
636
|
}
|
|
631
637
|
// Check for URL or internal path mid-text (char code guard avoids startsWith on every char)
|
|
632
|
-
if ((char_code === 104 /* h */ && this.#is_at_url()) ||
|
|
638
|
+
if (((char_code === 104 /* h */ || char_code === 72) /* H */ && this.#is_at_url()) ||
|
|
633
639
|
(char_code === SLASH && is_at_absolute_path(this.#text, this.#index)) ||
|
|
634
640
|
(char_code === PERIOD && is_at_relative_path(this.#text, this.#index))) {
|
|
635
641
|
break;
|
|
@@ -646,13 +652,8 @@ export class MdzLexer {
|
|
|
646
652
|
// -- Auto-link tokenizers --
|
|
647
653
|
#tokenize_auto_link_url() {
|
|
648
654
|
const start = this.#index;
|
|
649
|
-
// Consume protocol
|
|
650
|
-
|
|
651
|
-
this.#index += HTTPS_PREFIX_LENGTH;
|
|
652
|
-
}
|
|
653
|
-
else if (this.#match('http://')) {
|
|
654
|
-
this.#index += HTTP_PREFIX_LENGTH;
|
|
655
|
-
}
|
|
655
|
+
// Consume protocol (case-insensitive match; original casing preserved in reference)
|
|
656
|
+
this.#index += match_url_prefix_case_insensitive(this.#text, this.#index);
|
|
656
657
|
// Collect URL characters
|
|
657
658
|
while (this.#index < this.#text.length) {
|
|
658
659
|
const char_code = this.#text.charCodeAt(this.#index);
|
|
@@ -706,19 +707,14 @@ export class MdzLexer {
|
|
|
706
707
|
return false;
|
|
707
708
|
}
|
|
708
709
|
#is_at_url() {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
return false;
|
|
718
|
-
const next_char = this.#text.charCodeAt(this.#index + HTTP_PREFIX_LENGTH);
|
|
719
|
-
return next_char !== SPACE && next_char !== NEWLINE;
|
|
720
|
-
}
|
|
721
|
-
return false;
|
|
710
|
+
// Scheme matching is case-insensitive (RFC 3986).
|
|
711
|
+
const prefix_len = match_url_prefix_case_insensitive(this.#text, this.#index);
|
|
712
|
+
if (prefix_len === 0)
|
|
713
|
+
return false;
|
|
714
|
+
if (this.#index + prefix_len >= this.#text.length)
|
|
715
|
+
return false;
|
|
716
|
+
const next_char = this.#text.charCodeAt(this.#index + prefix_len);
|
|
717
|
+
return next_char !== SPACE && next_char !== NEWLINE;
|
|
722
718
|
}
|
|
723
719
|
#is_at_word_boundary(index, check_before, check_after) {
|
|
724
720
|
if (check_before && index > 0) {
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opcode types for the mdz streaming parser.
|
|
3
|
+
*
|
|
4
|
+
* Opcodes are serializable rendering instructions emitted by `MdzStreamParser`.
|
|
5
|
+
* They tell a renderer what to do next — open a container, append text, close it,
|
|
6
|
+
* or revert an optimistic assumption. Target-agnostic: works for HTML, Svelte, PDF, etc.
|
|
7
|
+
*
|
|
8
|
+
* The parser makes optimistic assumptions about ambiguous syntax (e.g., `**` is probably bold)
|
|
9
|
+
* and emits `revert` opcodes to correct when wrong. This enables true streaming rendering
|
|
10
|
+
* without ever re-parsing.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Unique monotonic identifier for each node created by the parser.
|
|
16
|
+
* IDs are never reused within a parser instance.
|
|
17
|
+
*/
|
|
18
|
+
export type MdzNodeId = number;
|
|
19
|
+
/** Node types that can be opened as containers. */
|
|
20
|
+
export type MdzContainerNodeType = 'Paragraph' | 'Bold' | 'Italic' | 'Strikethrough' | 'Link' | 'Heading' | 'Element' | 'Component' | 'Codeblock' | 'Code';
|
|
21
|
+
/** Node types for self-contained leaf elements. */
|
|
22
|
+
export type MdzVoidNodeType = 'Hr';
|
|
23
|
+
/** Discriminant for leaf text nodes. */
|
|
24
|
+
export type MdzTextNodeType = 'Text' | 'Code';
|
|
25
|
+
/**
|
|
26
|
+
* Open a container node. The renderer starts a new element/wrapper.
|
|
27
|
+
* Children are subsequent opcodes until the matching `close`.
|
|
28
|
+
*/
|
|
29
|
+
export interface MdzOpcodeOpen {
|
|
30
|
+
type: 'open';
|
|
31
|
+
id: MdzNodeId;
|
|
32
|
+
node_type: MdzContainerNodeType;
|
|
33
|
+
/** Byte offset in the full input where the opening delimiter begins. */
|
|
34
|
+
start: number;
|
|
35
|
+
/** Heading level (1-6). Present when `node_type` is `'Heading'`. */
|
|
36
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
37
|
+
/** Tag name. Present when `node_type` is `'Element'` or `'Component'`. */
|
|
38
|
+
name?: string;
|
|
39
|
+
/** Language hint. Present when `node_type` is `'Codeblock'`. */
|
|
40
|
+
lang?: string | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Close a previously opened container node.
|
|
44
|
+
* Carries deferred metadata that wasn't known at open time.
|
|
45
|
+
*/
|
|
46
|
+
export interface MdzOpcodeClose {
|
|
47
|
+
type: 'close';
|
|
48
|
+
id: MdzNodeId;
|
|
49
|
+
/** Byte offset in the full input immediately after the closing delimiter. */
|
|
50
|
+
end: number;
|
|
51
|
+
/** Link URL/path, resolved when `](url)` completes. */
|
|
52
|
+
reference?: string;
|
|
53
|
+
/** Link type, resolved alongside `reference`. */
|
|
54
|
+
link_type?: 'external' | 'internal';
|
|
55
|
+
/** Heading slug, computed from full heading content. */
|
|
56
|
+
heading_id?: string;
|
|
57
|
+
/**
|
|
58
|
+
* If true, consumer drops this node and its descendants from the tree.
|
|
59
|
+
* Used for whitespace-only paragraphs that match nothing in `mdz_parse`'s
|
|
60
|
+
* output — the streaming parser emits open/text speculatively, then
|
|
61
|
+
* retroactively drops the empty wrapper at close.
|
|
62
|
+
*/
|
|
63
|
+
discard?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a leaf text or code node.
|
|
67
|
+
* The parent is implicit — the innermost open container on the renderer's stack.
|
|
68
|
+
*/
|
|
69
|
+
export interface MdzOpcodeText {
|
|
70
|
+
type: 'text';
|
|
71
|
+
id: MdzNodeId;
|
|
72
|
+
content: string;
|
|
73
|
+
text_type: MdzTextNodeType;
|
|
74
|
+
/** Byte offset where this node begins (for Code, the opening backtick). */
|
|
75
|
+
start: number;
|
|
76
|
+
/** Byte offset immediately after this node ends (for Code, after the closing backtick). */
|
|
77
|
+
end: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Append content to an existing text node.
|
|
81
|
+
* Streaming optimization — avoids creating a new node per chunk
|
|
82
|
+
* during plain text runs.
|
|
83
|
+
*/
|
|
84
|
+
export interface MdzOpcodeAppendText {
|
|
85
|
+
type: 'append_text';
|
|
86
|
+
id: MdzNodeId;
|
|
87
|
+
content: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Trim `count` characters from the end of an existing text node.
|
|
91
|
+
* If trimming empties the node, the consumer removes it from its parent.
|
|
92
|
+
*
|
|
93
|
+
* Used by paragraph/codeblock close to drop the trailing newline that
|
|
94
|
+
* separates inline content from the block boundary. Emitted instead of
|
|
95
|
+
* retroactively mutating the prior `text`/`append_text` opcode, so the
|
|
96
|
+
* opcode stream is append-only.
|
|
97
|
+
*/
|
|
98
|
+
export interface MdzOpcodeTrimText {
|
|
99
|
+
type: 'trim_text';
|
|
100
|
+
id: MdzNodeId;
|
|
101
|
+
count: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a self-contained leaf node (e.g., horizontal rule).
|
|
105
|
+
* Inserted as a child of the innermost open container, or at root level.
|
|
106
|
+
*/
|
|
107
|
+
export interface MdzOpcodeVoid {
|
|
108
|
+
type: 'void';
|
|
109
|
+
id: MdzNodeId;
|
|
110
|
+
node_type: MdzVoidNodeType;
|
|
111
|
+
/** Byte offset in the full input where this element begins. */
|
|
112
|
+
start: number;
|
|
113
|
+
/** Byte offset immediately after this element ends. */
|
|
114
|
+
end: number;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Undo an optimistic open. Removes the container wrapper,
|
|
118
|
+
* inserts `replacement_text` as literal text at the container's position,
|
|
119
|
+
* and re-parents the container's children to the grandparent.
|
|
120
|
+
*
|
|
121
|
+
* When `wrap_node_type` and `wrap_id` are set, the replacement text and
|
|
122
|
+
* re-parented children are wrapped in a new container of the given type
|
|
123
|
+
* instead of being placed directly at the grandparent level. The wrapper
|
|
124
|
+
* is pushed onto the consumer's stack (open for future content). This is
|
|
125
|
+
* used for block-level reverts (e.g., codeblock → paragraph) where the
|
|
126
|
+
* grandparent is root and content needs a container.
|
|
127
|
+
*/
|
|
128
|
+
export interface MdzOpcodeRevert {
|
|
129
|
+
type: 'revert';
|
|
130
|
+
id: MdzNodeId;
|
|
131
|
+
/** The delimiter text to emit as literal content (e.g., `"**"`, `"["`, `"<Tag>"`). */
|
|
132
|
+
replacement_text: string;
|
|
133
|
+
/** Byte offset of the original opening delimiter in the full input. */
|
|
134
|
+
start: number;
|
|
135
|
+
/** Wrap replacement text and re-parented children in a new container of this type. */
|
|
136
|
+
wrap_node_type?: MdzContainerNodeType;
|
|
137
|
+
/** ID for the wrapper node. Required when `wrap_node_type` is set. */
|
|
138
|
+
wrap_id?: MdzNodeId;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Retroactively wrap an existing text node in a container.
|
|
142
|
+
* Used for text-first auto-links: URL/path text streams as plain text,
|
|
143
|
+
* then gets wrapped in a Link when the URL boundary is found.
|
|
144
|
+
*
|
|
145
|
+
* When `trim_end` is set, trailing characters (punctuation) are trimmed
|
|
146
|
+
* from the target text node and placed in a new sibling Text node after
|
|
147
|
+
* the Link wrapper, identified by `trim_id`.
|
|
148
|
+
*/
|
|
149
|
+
export interface MdzOpcodeWrap {
|
|
150
|
+
type: 'wrap';
|
|
151
|
+
/** ID for the new Link container node. */
|
|
152
|
+
id: MdzNodeId;
|
|
153
|
+
/** Container type to wrap in (always `'Link'` for now). */
|
|
154
|
+
node_type: 'Link';
|
|
155
|
+
/** ID of the existing text node to wrap. */
|
|
156
|
+
target_id: MdzNodeId;
|
|
157
|
+
/** Resolved URL or path reference. */
|
|
158
|
+
reference: string;
|
|
159
|
+
/** Whether the link is external (URL) or internal (path). */
|
|
160
|
+
link_type: 'external' | 'internal';
|
|
161
|
+
/** Byte offset where the URL/path begins. */
|
|
162
|
+
start: number;
|
|
163
|
+
/** Byte offset immediately after the URL/path (before any trimmed punctuation). */
|
|
164
|
+
end: number;
|
|
165
|
+
/** Number of trailing chars to trim from target and place after the link. */
|
|
166
|
+
trim_end?: number;
|
|
167
|
+
/** ID for the trimmed-text sibling node. Required when `trim_end` > 0. */
|
|
168
|
+
trim_id?: MdzNodeId;
|
|
169
|
+
}
|
|
170
|
+
/** All node types that can appear in the mdz tree. */
|
|
171
|
+
export type MdzNodeType = MdzContainerNodeType | MdzVoidNodeType | MdzTextNodeType;
|
|
172
|
+
/** Discriminated union of all mdz opcodes. */
|
|
173
|
+
export type MdzOpcode = MdzOpcodeOpen | MdzOpcodeClose | MdzOpcodeText | MdzOpcodeAppendText | MdzOpcodeTrimText | MdzOpcodeVoid | MdzOpcodeRevert | MdzOpcodeWrap;
|
|
174
|
+
//# sourceMappingURL=mdz_opcodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdz_opcodes.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_opcodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opcode types for the mdz streaming parser.
|
|
3
|
+
*
|
|
4
|
+
* Opcodes are serializable rendering instructions emitted by `MdzStreamParser`.
|
|
5
|
+
* They tell a renderer what to do next — open a container, append text, close it,
|
|
6
|
+
* or revert an optimistic assumption. Target-agnostic: works for HTML, Svelte, PDF, etc.
|
|
7
|
+
*
|
|
8
|
+
* The parser makes optimistic assumptions about ambiguous syntax (e.g., `**` is probably bold)
|
|
9
|
+
* and emits `revert` opcodes to correct when wrong. This enables true streaming rendering
|
|
10
|
+
* without ever re-parsing.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a stream of mdz opcodes to the `MdzNode[]` tree representation.
|
|
3
|
+
*
|
|
4
|
+
* Stack-based replay: `open` pushes a frame, `close` pops and builds the node,
|
|
5
|
+
* `text`/`void` create leaf nodes, `append_text` extends the last text node,
|
|
6
|
+
* `revert` undoes an optimistic open and re-parents children.
|
|
7
|
+
*
|
|
8
|
+
* The output is identical to `mdz_parse()` from `mdz.ts`, enabling
|
|
9
|
+
* validation of the streaming parser against the existing fixture suite.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import type { MdzNode } from './mdz.js';
|
|
14
|
+
import type { MdzOpcode } from './mdz_opcodes.js';
|
|
15
|
+
/**
|
|
16
|
+
* Convert an array of mdz opcodes to the `MdzNode[]` tree.
|
|
17
|
+
* Produces output identical to `mdz_parse()`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const mdz_opcodes_to_nodes: (opcodes: Array<MdzOpcode>) => Array<MdzNode>;
|
|
20
|
+
//# sourceMappingURL=mdz_opcodes_to_nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdz_opcodes_to_nodes.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_opcodes_to_nodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAC,OAAO,EAAwD,MAAM,UAAU,CAAC;AAC7F,OAAO,KAAK,EAAC,SAAS,EAAY,MAAM,kBAAkB,CAAC;AAwB3D;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,KAAK,CAAC,SAAS,CAAC,KAAG,KAAK,CAAC,OAAO,CAkN7E,CAAC"}
|