@fuzdev/mdz 0.9.0 → 0.10.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/Mdz.svelte +37 -1
- package/dist/Mdz.svelte.d.ts +35 -0
- package/dist/Mdz.svelte.d.ts.map +1 -1
- package/dist/MdzNodeView.svelte +143 -27
- package/dist/MdzNodeView.svelte.d.ts +13 -1
- package/dist/MdzNodeView.svelte.d.ts.map +1 -1
- package/dist/MdzPrecompiled.svelte.d.ts.map +1 -1
- package/dist/MdzRoot.svelte.d.ts.map +1 -1
- package/dist/MdzStream.svelte.d.ts.map +1 -1
- package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -1
- package/dist/context_helpers.d.ts.map +1 -1
- package/dist/mdz.d.ts +4 -1
- package/dist/mdz.d.ts.map +1 -1
- package/dist/mdz.js +4 -1
- package/dist/mdz_contexts.d.ts +14 -2
- package/dist/mdz_contexts.d.ts.map +1 -1
- package/dist/mdz_debug_work.d.ts.map +1 -1
- package/dist/mdz_helpers.d.ts +57 -7
- package/dist/mdz_helpers.d.ts.map +1 -1
- package/dist/mdz_helpers.js +113 -50
- package/dist/mdz_lexer.d.ts.map +1 -1
- package/dist/mdz_lexer.js +21 -17
- package/dist/mdz_opcodes.d.ts.map +1 -1
- package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -1
- package/dist/mdz_stream_parser.d.ts +16 -3
- package/dist/mdz_stream_parser.d.ts.map +1 -1
- package/dist/mdz_stream_parser.js +16 -3
- package/dist/mdz_stream_parser_block.d.ts +2 -2
- package/dist/mdz_stream_parser_block.d.ts.map +1 -1
- package/dist/mdz_stream_parser_block.js +2 -2
- package/dist/mdz_stream_parser_inline.d.ts.map +1 -1
- package/dist/mdz_stream_parser_inline.js +4 -4
- package/dist/mdz_stream_parser_link.d.ts.map +1 -1
- package/dist/mdz_stream_parser_list.d.ts.map +1 -1
- package/dist/mdz_stream_parser_state.d.ts +32 -12
- package/dist/mdz_stream_parser_state.d.ts.map +1 -1
- package/dist/mdz_stream_parser_state.js +21 -14
- package/dist/mdz_stream_parser_table.d.ts.map +1 -1
- package/dist/mdz_stream_parser_text.d.ts.map +1 -1
- package/dist/mdz_stream_parser_text.js +7 -4
- package/dist/mdz_stream_parser_url.d.ts +3 -2
- package/dist/mdz_stream_parser_url.d.ts.map +1 -1
- package/dist/mdz_stream_parser_url.js +114 -42
- package/dist/mdz_stream_state.svelte.d.ts.map +1 -1
- package/dist/mdz_to_svelte.d.ts.map +1 -1
- package/dist/mdz_token_parser.d.ts.map +1 -1
- package/dist/svelte_preprocess_mdz.d.ts.map +1 -1
- package/dist/svelte_preprocess_mdz.js +8 -0
- package/dist/tsdoc_mdz.d.ts +8 -4
- package/dist/tsdoc_mdz.d.ts.map +1 -1
- package/dist/tsdoc_mdz.js +14 -4
- package/package.json +5 -5
- package/src/lib/mdz.ts +4 -1
- package/src/lib/mdz_contexts.ts +20 -2
- package/src/lib/mdz_helpers.ts +117 -49
- package/src/lib/mdz_lexer.ts +31 -14
- package/src/lib/mdz_stream_parser.ts +16 -3
- package/src/lib/mdz_stream_parser_block.ts +2 -2
- package/src/lib/mdz_stream_parser_inline.ts +4 -4
- package/src/lib/mdz_stream_parser_state.ts +34 -13
- package/src/lib/mdz_stream_parser_text.ts +13 -6
- package/src/lib/mdz_stream_parser_url.ts +130 -49
- package/src/lib/svelte_preprocess_mdz.ts +8 -0
- package/src/lib/tsdoc_mdz.ts +15 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_stream_parser_state.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_stream_parser_state.d.ts","sourceRoot":"","sources":["../src/lib/mdz_stream_parser_state.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ export const create_state = () => ({
|
|
|
18
18
|
stack: [],
|
|
19
19
|
column: 0,
|
|
20
20
|
prev_char: -1,
|
|
21
|
+
before_prev_char: -1,
|
|
21
22
|
active_text_id: null,
|
|
22
23
|
accumulated_text: '',
|
|
23
24
|
accumulated_text_start: 0,
|
|
@@ -442,18 +443,24 @@ export const revert_above = (state, target_idx) => {
|
|
|
442
443
|
state.active_text_id = null;
|
|
443
444
|
};
|
|
444
445
|
/**
|
|
445
|
-
* Revert
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
446
|
+
* Revert one open frame, possibly **mid-stack**, without reverting the frames
|
|
447
|
+
* above it. Two callers:
|
|
448
|
+
*
|
|
449
|
+
* - an open `Italic` whose first closer candidate failed its boundary check
|
|
450
|
+
* (italic is the only inline with closer-boundary rules) — one-shot parsing
|
|
451
|
+
* greedy-rejects the opener at the first invalid closer, so once a failed
|
|
452
|
+
* candidate is seen the optimistic open is known wrong, and reverting
|
|
453
|
+
* immediately keeps chunked output identical to the one-shot parse
|
|
454
|
+
* - the auto-link span resolution (`revert_spans_closed_inside` in
|
|
455
|
+
* `mdz_stream_parser_url.ts`), which reverts `Bold`, `Italic`,
|
|
456
|
+
* `Strikethrough`, `Element`, and `Component` frames whose span the one-shot
|
|
457
|
+
* parse leaves literal, one frame at a time and possibly beneath a `Link`
|
|
458
|
+
* frame that stays open
|
|
459
|
+
*
|
|
460
|
+
* Containers opened above the reverted frame stay open, and the consumers'
|
|
461
|
+
* revert handlers re-parent them identically for every frame type — the
|
|
462
|
+
* reverted node is still its parent's last child, and both handlers work on
|
|
463
|
+
* node ids and children only (see `mdz_opcodes_to_nodes` and
|
|
457
464
|
* `MdzStreamState`).
|
|
458
465
|
*
|
|
459
466
|
* Bypasses `emit` for the opcode push: `emit`'s heading-segment handling
|
|
@@ -481,8 +488,8 @@ export const revert_failed_close = (state, stack_idx) => {
|
|
|
481
488
|
else
|
|
482
489
|
counts.set(entry.tag_name, remaining);
|
|
483
490
|
}
|
|
484
|
-
//
|
|
485
|
-
//
|
|
491
|
+
// Element/Component frames count toward the link/tag nesting depth (Link
|
|
492
|
+
// frames are never reverted here today, but keep the counter honest)
|
|
486
493
|
if (entry.node_type === 'Link' || entry.tag_name !== undefined)
|
|
487
494
|
state.open_link_tag_depth--;
|
|
488
495
|
state.opcodes.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_stream_parser_table.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_stream_parser_table.d.ts","sourceRoot":"","sources":["../src/lib/mdz_stream_parser_table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAQd,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,oBAAoB,EAAE,QAAQ,OAAO,KAAG,SAyC9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,oBAAoB,EAAE,QAAQ,OAAO,KAAG,OAyCjF,CAAC;AA2DF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,oBAAoB,KAAG,IAczD,CAAC;AAEF,yFAAyF;AACzF,MAAM,WAAW,eAAe;IAC/B,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GACpC,OAAO,oBAAoB,EAC3B,cAAc,MAAM,EACpB,eAAe,MAAM,EACrB,QAAQ,OAAO,KACb,eAAe,GAAG,SAAS,GAAG,IAmBhC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAC9B,OAAO,oBAAoB,EAC3B,cAAc,MAAM,EACpB,eAAe,MAAM,EACrB,MAAM,eAAe,KACnB,IAsBF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_stream_parser_text.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_stream_parser_text.d.ts","sourceRoot":"","sources":["../src/lib/mdz_stream_parser_text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,EACN,KAAK,oBAAoB,EAIzB,MAAM,8BAA8B,CAAC;AAGtC;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,oBAAoB,EAAE,WAAW,MAAM,KAAG,IAM1F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,oBAAoB,KAAG,IAqD9D,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { HTTPS_PREFIX_LENGTH,
|
|
6
|
+
import { HTTPS_PREFIX_LENGTH, TEXT_CLASS_NEWLINE, TEXT_CLASS_PATH, TEXT_CLASS_STOP, TEXT_CLASS_URL, TEXT_SCAN_CLASS, is_path_boundary, is_word_char, match_url_prefix_case_insensitive } from './mdz_helpers.js';
|
|
7
7
|
import { accumulate_text, ensure_paragraph, offset } from './mdz_stream_parser_state.js';
|
|
8
8
|
import { mdz_debug_work } from './mdz_debug_work.js';
|
|
9
9
|
/**
|
|
@@ -62,10 +62,11 @@ export const consume_text_run = (state) => {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
else if ((char_class & TEXT_CLASS_PATH) !== 0) {
|
|
65
|
-
// path (`/` or `.`): only break at a plausible path start
|
|
66
|
-
|
|
67
|
-
if (
|
|
65
|
+
// path (`/` or `.`): only break at a plausible path start — the run
|
|
66
|
+
// start's lookbehind is the incoming `prev_char`
|
|
67
|
+
if (is_path_boundary(state.buffer.charCodeAt(state.pos - 1), state.pos - 2 >= start ? state.buffer.charCodeAt(state.pos - 2) : state.prev_char)) {
|
|
68
68
|
break;
|
|
69
|
+
}
|
|
69
70
|
}
|
|
70
71
|
// backslash (or a non-starting path char) — ordinary text
|
|
71
72
|
state.pos++;
|
|
@@ -73,6 +74,8 @@ export const consume_text_run = (state) => {
|
|
|
73
74
|
if (mdz_debug_work.enabled)
|
|
74
75
|
mdz_debug_work.total += state.pos - start;
|
|
75
76
|
accumulate_text(state, state.buffer.slice(start, state.pos), offset(state, start));
|
|
77
|
+
state.before_prev_char =
|
|
78
|
+
state.pos - 2 >= start ? state.buffer.charCodeAt(state.pos - 2) : state.prev_char;
|
|
76
79
|
state.prev_char = state.buffer.charCodeAt(state.pos - 1);
|
|
77
80
|
state.column += state.pos - start;
|
|
78
81
|
};
|
|
@@ -53,8 +53,9 @@ export declare const start_speculative_url: (state: MdzStreamParserState) => voi
|
|
|
53
53
|
export declare const process_url_prefix: (state: MdzStreamParserState) => void;
|
|
54
54
|
/**
|
|
55
55
|
* Process URL/path chars in text-first mode. Scans path chars,
|
|
56
|
-
* accumulates as visible text. Terminates on space/newline/non-path-char
|
|
57
|
-
*
|
|
56
|
+
* accumulates as visible text. Terminates on space/newline/non-path-char —
|
|
57
|
+
* or, for a path opened by `(`, on the `)` matching that opener — and emits
|
|
58
|
+
* a `wrap` opcode.
|
|
58
59
|
*
|
|
59
60
|
* @nodocs
|
|
60
61
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_stream_parser_url.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_stream_parser_url.d.ts","sourceRoot":"","sources":["../src/lib/mdz_stream_parser_url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoBH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,SAAS,EASd,MAAM,8BAA8B,CAAC;AAKtC;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,oBAAoB,KAAG,SAYjE,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,sBAAsB,GAAI,OAAO,oBAAoB,EAAE,gBAAc,KAAG,SAcpF,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,sBAAsB,GAAI,OAAO,oBAAoB,EAAE,gBAAc,KAAG,SAmCpF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC7B,OAAO,oBAAoB,EAC3B,WAAW,UAAU,GAAG,UAAU,KAChC,IAeF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,oBAAoB,KAAG,IAanE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,oBAAoB,KAAG,IAwChE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,oBAAoB,EAAE,QAAQ,OAAO,KAAG,IAoClF,CAAC;AAyEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,oBAAoB,KAAG,IAyDlE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GACjC,OAAO,oBAAoB,EAC3B,WAAW,UAAU,GAAG,UAAU,KAChC,SAkDF,CAAC"}
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @module
|
|
14
14
|
*/
|
|
15
|
-
import { NEWLINE, SPACE, TAB, PERIOD, SLASH, ascii_to_lower, is_valid_path_char, is_word_char, match_url_prefix_case_insensitive, mdz_trim_url_punctuation } from './mdz_helpers.js';
|
|
16
|
-
import { accumulate_text, alloc_id, emit, ensure_paragraph, flush_text, offset } from './mdz_stream_parser_state.js';
|
|
15
|
+
import { NEWLINE, SPACE, TAB, PERIOD, LEFT_PAREN, RIGHT_PAREN, SLASH, ascii_to_lower, is_bare_path_prefix, is_italic_boundary_blocker, scan_uri_chars_end, is_path_boundary, is_valid_path_char, is_word_char, match_url_prefix_case_insensitive, mdz_trim_url_punctuation } from './mdz_helpers.js';
|
|
16
|
+
import { accumulate_text, alloc_id, emit, ensure_paragraph, flush_text, is_run_boundary, offset, revert_failed_close } from './mdz_stream_parser_state.js';
|
|
17
17
|
const HTTPS_PREFIX = 'https://';
|
|
18
18
|
const HTTP_PREFIX = 'http://';
|
|
19
19
|
/**
|
|
@@ -39,13 +39,9 @@ export const try_auto_url_forced = (state) => {
|
|
|
39
39
|
};
|
|
40
40
|
/** @nodocs */
|
|
41
41
|
export const try_auto_path_absolute = (state, forced = false) => {
|
|
42
|
-
// must be at
|
|
43
|
-
if (state.prev_char
|
|
44
|
-
state.prev_char !== SPACE &&
|
|
45
|
-
state.prev_char !== NEWLINE &&
|
|
46
|
-
state.prev_char !== TAB) {
|
|
42
|
+
// must be at a path boundary (start, whitespace, or `(`)
|
|
43
|
+
if (!is_path_boundary(state.prev_char, state.before_prev_char))
|
|
47
44
|
return 'not_match';
|
|
48
|
-
}
|
|
49
45
|
// reject // and /space
|
|
50
46
|
if (state.pos + 1 >= state.buffer.length)
|
|
51
47
|
return forced ? 'not_match' : 'need_more';
|
|
@@ -60,12 +56,9 @@ export const try_auto_path_absolute = (state, forced = false) => {
|
|
|
60
56
|
};
|
|
61
57
|
/** @nodocs */
|
|
62
58
|
export const try_auto_path_relative = (state, forced = false) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
state.prev_char !== NEWLINE &&
|
|
66
|
-
state.prev_char !== TAB) {
|
|
59
|
+
// must be at a path boundary (start, whitespace, or `(`)
|
|
60
|
+
if (!is_path_boundary(state.prev_char, state.before_prev_char))
|
|
67
61
|
return 'not_match';
|
|
68
|
-
}
|
|
69
62
|
// check for ./ or ../
|
|
70
63
|
const remaining = state.buffer.length - state.pos;
|
|
71
64
|
if (remaining < 3)
|
|
@@ -113,7 +106,9 @@ export const start_pending_url = (state, link_type) => {
|
|
|
113
106
|
link_type,
|
|
114
107
|
confirmed: true,
|
|
115
108
|
viable_https: false,
|
|
116
|
-
viable_http: false
|
|
109
|
+
viable_http: false,
|
|
110
|
+
// a path opened by `(` ends at the `)` matching it
|
|
111
|
+
paren_depth: state.prev_char === LEFT_PAREN ? 0 : -1
|
|
117
112
|
};
|
|
118
113
|
// don't advance pos — URL chars start at current position, handled by process_url_content
|
|
119
114
|
};
|
|
@@ -134,7 +129,8 @@ export const start_speculative_url = (state) => {
|
|
|
134
129
|
link_type: 'external',
|
|
135
130
|
confirmed: false,
|
|
136
131
|
viable_https: true,
|
|
137
|
-
viable_http: true
|
|
132
|
+
viable_http: true,
|
|
133
|
+
paren_depth: -1
|
|
138
134
|
};
|
|
139
135
|
};
|
|
140
136
|
/**
|
|
@@ -181,8 +177,9 @@ export const process_url_prefix = (state) => {
|
|
|
181
177
|
};
|
|
182
178
|
/**
|
|
183
179
|
* Process URL/path chars in text-first mode. Scans path chars,
|
|
184
|
-
* accumulates as visible text. Terminates on space/newline/non-path-char
|
|
185
|
-
*
|
|
180
|
+
* accumulates as visible text. Terminates on space/newline/non-path-char —
|
|
181
|
+
* or, for a path opened by `(`, on the `)` matching that opener — and emits
|
|
182
|
+
* a `wrap` opcode.
|
|
186
183
|
*
|
|
187
184
|
* @nodocs
|
|
188
185
|
*/
|
|
@@ -192,34 +189,106 @@ export const process_url_content = (state, forced) => {
|
|
|
192
189
|
process_url_prefix(state);
|
|
193
190
|
return;
|
|
194
191
|
}
|
|
195
|
-
const
|
|
196
|
-
// URL terminator
|
|
197
|
-
if (char_code === SPACE || char_code === NEWLINE || !is_valid_path_char(char_code)) {
|
|
198
|
-
flush_text(state);
|
|
199
|
-
complete_pending_url(state);
|
|
200
|
-
// don't consume terminator — outer loop handles it
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
// scan URL chars
|
|
192
|
+
const pu = state.pending_url;
|
|
204
193
|
const start = state.pos;
|
|
205
|
-
state.pos++;
|
|
206
194
|
while (state.pos < state.buffer.length) {
|
|
207
195
|
const c = state.buffer.charCodeAt(state.pos);
|
|
208
|
-
if (
|
|
196
|
+
if (!is_valid_path_char(c))
|
|
209
197
|
break;
|
|
198
|
+
if (pu.paren_depth !== -1) {
|
|
199
|
+
if (c === LEFT_PAREN)
|
|
200
|
+
pu.paren_depth++;
|
|
201
|
+
else if (c === RIGHT_PAREN) {
|
|
202
|
+
if (pu.paren_depth === 0)
|
|
203
|
+
break;
|
|
204
|
+
pu.paren_depth--;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
210
207
|
state.pos++;
|
|
211
208
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
209
|
+
if (state.pos > start) {
|
|
210
|
+
const text = state.buffer.slice(start, state.pos);
|
|
211
|
+
accumulate_text(state, text, offset(state, start));
|
|
212
|
+
pu.url_text += text;
|
|
213
|
+
state.prev_char = state.buffer.charCodeAt(state.pos - 1);
|
|
214
|
+
state.column += state.pos - start;
|
|
215
|
+
}
|
|
216
|
+
// a terminator in the buffer ends the URL (not consumed — the outer loop
|
|
217
|
+
// handles it); at EOF in forced mode the buffer end does
|
|
218
|
+
if (state.pos < state.buffer.length || forced) {
|
|
219
219
|
flush_text(state);
|
|
220
220
|
complete_pending_url(state);
|
|
221
221
|
}
|
|
222
222
|
};
|
|
223
|
+
// the char at the parse position, or `-1` at the end of the buffer
|
|
224
|
+
const char_after_pos = (state) => state.pos < state.buffer.length ? state.buffer.charCodeAt(state.pos) : -1;
|
|
225
|
+
/**
|
|
226
|
+
* Resolve the open spans whose first closer candidate an auto-link swallowed,
|
|
227
|
+
* the way the one-shot parse does. The lexer pairs each `**`/`~~`/`_` opener
|
|
228
|
+
* with the first occurrence of its delimiter after it
|
|
229
|
+
* (`#tokenize_double_delimiter`, `#tokenize_italic`). Streaming resolves each
|
|
230
|
+
* open span's earlier candidates as they arrive, so a delimiter inside the
|
|
231
|
+
* link's reference is that first occurrence, and the lexer's outcome depends
|
|
232
|
+
* on the span:
|
|
233
|
+
*
|
|
234
|
+
* - `**` and `~~` pair with the occurrence unconditionally; the span's children
|
|
235
|
+
* lex bounded by it, the link overruns it, and the opener stays literal —
|
|
236
|
+
* as does every delimiter, tag, and code opener lexed inside the span (each
|
|
237
|
+
* bounded by the swallowed closer). Markdown links aren't bounded by an
|
|
238
|
+
* enclosing span, so Link frames survive.
|
|
239
|
+
* - `_` first checks the candidate's closing boundary (`is_italic_boundary_blocker`
|
|
240
|
+
* on the char after it). A blocked candidate rejects only the opener — the
|
|
241
|
+
* span's content then lexes unbounded, so inner spans survive — while a
|
|
242
|
+
* valid one pairs and overruns like the doubled delimiters.
|
|
243
|
+
*
|
|
244
|
+
* So: the lowest span in the current run that pairs inside the reference is
|
|
245
|
+
* reverted along with every non-Link frame above it, and an italic below it
|
|
246
|
+
* with a blocked candidate is reverted alone (mid-stack, frames above it kept).
|
|
247
|
+
* Called after the link's `wrap`/`close` is emitted, so a pending wrap never
|
|
248
|
+
* outlives an enclosing revert.
|
|
249
|
+
*
|
|
250
|
+
* @param scanned - the scanned URL/path text, starting with `reference` and
|
|
251
|
+
* including any trimmed tail
|
|
252
|
+
* @param after_scanned - the char code after `scanned`, or `-1` at end of input
|
|
253
|
+
*/
|
|
254
|
+
const revert_spans_closed_inside = (state, reference, scanned, after_scanned) => {
|
|
255
|
+
let run_start = 0;
|
|
256
|
+
for (let i = state.stack.length - 1; i >= 0; i--) {
|
|
257
|
+
if (is_run_boundary(state.stack[i].node_type)) {
|
|
258
|
+
run_start = i + 1;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
let paired = -1; // lowest span pairing inside the reference
|
|
263
|
+
let rejected_italic = -1; // an italic whose candidate's boundary is blocked
|
|
264
|
+
for (let i = run_start; i < state.stack.length && paired === -1; i++) {
|
|
265
|
+
const entry = state.stack[i];
|
|
266
|
+
if (entry.node_type === 'Bold' || entry.node_type === 'Strikethrough') {
|
|
267
|
+
if (reference.includes(entry.delimiter))
|
|
268
|
+
paired = i;
|
|
269
|
+
}
|
|
270
|
+
else if (entry.node_type === 'Italic') {
|
|
271
|
+
const k = reference.indexOf('_');
|
|
272
|
+
if (k === -1)
|
|
273
|
+
continue;
|
|
274
|
+
const after = k + 1 < scanned.length ? scanned.charCodeAt(k + 1) : after_scanned;
|
|
275
|
+
if (after !== -1 && is_italic_boundary_blocker(after))
|
|
276
|
+
rejected_italic = i;
|
|
277
|
+
else
|
|
278
|
+
paired = i;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (paired !== -1) {
|
|
282
|
+
for (let i = state.stack.length - 1; i >= paired; i--) {
|
|
283
|
+
if (state.stack[i].node_type !== 'Link')
|
|
284
|
+
revert_failed_close(state, i);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// below `paired` (or with nothing paired) — indices below it are unchanged
|
|
288
|
+
if (rejected_italic !== -1 && (paired === -1 || rejected_italic < paired)) {
|
|
289
|
+
revert_failed_close(state, rejected_italic);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
223
292
|
/**
|
|
224
293
|
* Complete a pending URL: compute reference with trimmed punctuation,
|
|
225
294
|
* emit a `wrap` opcode to retroactively wrap the text node in a Link.
|
|
@@ -237,6 +306,9 @@ export const complete_pending_url = (state) => {
|
|
|
237
306
|
const reference = mdz_trim_url_punctuation(pu.url_text);
|
|
238
307
|
if (reference.length === 0)
|
|
239
308
|
return; // empty after trimming — text stays as plain text
|
|
309
|
+
// a bare path prefix (`./`, `/`) left after trimming isn't a path — text stays
|
|
310
|
+
if (pu.link_type === 'internal' && is_bare_path_prefix(reference))
|
|
311
|
+
return;
|
|
240
312
|
// for external URLs, must have content after protocol prefix
|
|
241
313
|
if (pu.link_type === 'external') {
|
|
242
314
|
const prefix_len = match_url_prefix_case_insensitive(reference, 0);
|
|
@@ -264,6 +336,7 @@ export const complete_pending_url = (state) => {
|
|
|
264
336
|
trim_id
|
|
265
337
|
});
|
|
266
338
|
state.active_text_id = trim_id;
|
|
339
|
+
revert_spans_closed_inside(state, reference, pu.url_text, char_after_pos(state));
|
|
267
340
|
}
|
|
268
341
|
else {
|
|
269
342
|
emit(state, {
|
|
@@ -277,6 +350,7 @@ export const complete_pending_url = (state) => {
|
|
|
277
350
|
end: url_end
|
|
278
351
|
});
|
|
279
352
|
state.active_text_id = null;
|
|
353
|
+
revert_spans_closed_inside(state, reference, pu.url_text, char_after_pos(state));
|
|
280
354
|
}
|
|
281
355
|
};
|
|
282
356
|
/**
|
|
@@ -286,17 +360,14 @@ export const complete_pending_url = (state) => {
|
|
|
286
360
|
* @nodocs
|
|
287
361
|
*/
|
|
288
362
|
export const scan_auto_link_forced = (state, link_type) => {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const c = state.buffer.charCodeAt(i);
|
|
292
|
-
if (c === SPACE || c === NEWLINE || !is_valid_path_char(c))
|
|
293
|
-
break;
|
|
294
|
-
i++;
|
|
295
|
-
}
|
|
363
|
+
// a path opened by `(` ends at the `)` matching it
|
|
364
|
+
const i = scan_uri_chars_end(state.buffer, state.pos, link_type === 'internal' && state.prev_char === LEFT_PAREN);
|
|
296
365
|
let reference = state.buffer.slice(state.pos, i);
|
|
297
366
|
reference = mdz_trim_url_punctuation(reference);
|
|
298
367
|
if (reference.length === 0)
|
|
299
368
|
return 'not_match';
|
|
369
|
+
if (link_type === 'internal' && is_bare_path_prefix(reference))
|
|
370
|
+
return 'not_match';
|
|
300
371
|
// for external URLs, must have content after protocol prefix
|
|
301
372
|
if (link_type === 'external') {
|
|
302
373
|
const prefix_len = match_url_prefix_case_insensitive(reference, 0);
|
|
@@ -324,5 +395,6 @@ export const scan_auto_link_forced = (state, link_type) => {
|
|
|
324
395
|
state.column += end_pos - state.pos;
|
|
325
396
|
state.prev_char = reference.charCodeAt(reference.length - 1);
|
|
326
397
|
state.pos = end_pos;
|
|
398
|
+
revert_spans_closed_inside(state, reference, state.buffer.slice(link_start - state.base_offset, i), i < state.buffer.length ? state.buffer.charCodeAt(i) : -1);
|
|
327
399
|
return 'consumed';
|
|
328
400
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_stream_state.svelte.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_stream_state.svelte.d.ts","sourceRoot":"","sources":["../src/lib/mdz_stream_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5D;;;GAGG;AACH,qBAAa,aAAa;IACzB,EAAE,EAAE,SAAS,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAc;IAC7B,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,CAAc;IAE5C,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAY;IAC9B,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,CAAY;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4GAA4G;IAC5G,UAAU,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAY;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAC7B,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;gBAEL,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW;CAI5C;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAc;;IAC1B,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,CAAc;IAqCxC;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IA8R9B;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI;CAK5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_to_svelte.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_to_svelte.d.ts","sourceRoot":"","sources":["../src/lib/mdz_to_svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAe3D;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAUtF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IAEf,yDAAyD;IACzD,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IAElE,yEAAyE;IACzE,qBAAqB,EAAE,OAAO,CAAC;CAC/B;AA2CD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAE/C;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACzB,OAAO,KAAK,CAAC,OAAO,CAAC,EACrB,SAAS,kBAAkB,KACzB,iBAmKF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mdz_token_parser.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"mdz_token_parser.d.ts","sourceRoot":"","sources":["../src/lib/mdz_token_parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACX,OAAO,EAeP,MAAM,UAAU,CAAC;AAQlB,OAAO,EACN,KAAK,QAAQ,EAYb,MAAM,gBAAgB,CAAC;AAiBxB;;;GAGG;AACH,qBAAa,cAAc;;gBAId,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;IAInC;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI;IAKpC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC;IAIvB;;;;;;OAMG;IACH,gBAAgB,IAAI,KAAK,CAAC,OAAO,CAAC;CA6jBlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svelte_preprocess_mdz.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"svelte_preprocess_mdz.d.ts","sourceRoot":"","sources":["../src/lib/svelte_preprocess_mdz.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAS,KAAK,iBAAiB,EAAY,MAAM,iBAAiB,CAAC;AAuB1E,OAAO,EAAiB,KAAK,kBAAkB,EAA0B,MAAM,oBAAoB,CAAC;AASpG;;GAEG;AACH,MAAM,WAAW,0BAA0B;IAC1C,gCAAgC;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAEjC;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAEhD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtC;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAEnC;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAEpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CAC3B;AAID;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GACjC,UAAS,0BAA+B,KACtC,iBA6FF,CAAC"}
|
|
@@ -222,10 +222,18 @@ const find_mdz_usages = (ast, mdz_names, context) => {
|
|
|
222
222
|
const inline = inline_attr ? extract_static_boolean(inline_attr.value) : false;
|
|
223
223
|
if (inline === null)
|
|
224
224
|
return; // dynamic inline — fall back to runtime
|
|
225
|
+
// precompiled markup carries no source offsets, so content that asks for
|
|
226
|
+
// them renders at runtime; a static `false` asks for nothing and is dropped
|
|
227
|
+
const source_offsets_attr = find_attribute(node, 'source_offsets');
|
|
228
|
+
if (source_offsets_attr && extract_static_boolean(source_offsets_attr.value) !== false) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
225
231
|
// Collect attributes to exclude from precompiled output
|
|
226
232
|
const exclude_attrs = new Set([content_attr]);
|
|
227
233
|
if (base_attr)
|
|
228
234
|
exclude_attrs.add(base_attr);
|
|
235
|
+
if (source_offsets_attr)
|
|
236
|
+
exclude_attrs.add(source_offsets_attr);
|
|
229
237
|
// Extract static string value
|
|
230
238
|
const content_value = extract_static_string(content_attr.value, context.bindings);
|
|
231
239
|
if (content_value !== null) {
|
package/dist/tsdoc_mdz.d.ts
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
* - `{@link url|text}` → `[text](url)` (markdown link, TSDoc canonical form)
|
|
15
15
|
* - `{@link url text}` → `[text](url)` (TS-lenient space-separated form)
|
|
16
16
|
* - `{@link https://...}` → `https://...` (bare URL, auto-linked by mdz)
|
|
17
|
-
* - `{@link identifier}` →
|
|
17
|
+
* - `{@link identifier}` → the identifier as a code span
|
|
18
18
|
* - Bare URLs → returned as-is
|
|
19
19
|
* - Bare markdown links (`[text](url)` ...) → returned as-is
|
|
20
|
+
* - Content that opens with a backtick (a code span, then description text) → returned as-is
|
|
20
21
|
* - Bare identifiers → wrapped in backticks
|
|
21
|
-
* - `identifier description text` →
|
|
22
|
+
* - `identifier description text` → the first token wrapped in backticks, the rest as written
|
|
22
23
|
*
|
|
23
24
|
* @param content - raw `@see` tag content in TSDoc format
|
|
24
25
|
* @returns mdz-formatted string ready for `Mdz` component
|
|
@@ -34,11 +35,14 @@
|
|
|
34
35
|
* mdz_from_tsdoc('https://fuz.dev')
|
|
35
36
|
* // → 'https://fuz.dev'
|
|
36
37
|
*
|
|
37
|
-
* mdz_from_tsdoc('[svelte-docinfo](https://github.com/
|
|
38
|
-
* // → '[svelte-docinfo](https://github.com/
|
|
38
|
+
* mdz_from_tsdoc('[svelte-docinfo](https://github.com/fuzdev/svelte-docinfo) for the analysis library')
|
|
39
|
+
* // → '[svelte-docinfo](https://github.com/fuzdev/svelte-docinfo) for the analysis library'
|
|
39
40
|
*
|
|
40
41
|
* mdz_from_tsdoc('tome.ts for the documentation system')
|
|
41
42
|
* // → '`tome.ts` for the documentation system'
|
|
43
|
+
*
|
|
44
|
+
* mdz_from_tsdoc('`tome.ts` for the `Tome` type')
|
|
45
|
+
* // → '`tome.ts` for the `Tome` type'
|
|
42
46
|
* ```
|
|
43
47
|
*/
|
|
44
48
|
export declare const mdz_from_tsdoc: (content: string) => string;
|
package/dist/tsdoc_mdz.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsdoc_mdz.d.ts","sourceRoot":"
|
|
1
|
+
{"version":3,"file":"tsdoc_mdz.d.ts","sourceRoot":"","sources":["../src/lib/tsdoc_mdz.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAsDhD,CAAC"}
|
package/dist/tsdoc_mdz.js
CHANGED
|
@@ -17,11 +17,12 @@ const format_reference = (ref) => (mdz_is_url(ref) ? ref : `\`${ref}\``);
|
|
|
17
17
|
* - `{@link url|text}` → `[text](url)` (markdown link, TSDoc canonical form)
|
|
18
18
|
* - `{@link url text}` → `[text](url)` (TS-lenient space-separated form)
|
|
19
19
|
* - `{@link https://...}` → `https://...` (bare URL, auto-linked by mdz)
|
|
20
|
-
* - `{@link identifier}` →
|
|
20
|
+
* - `{@link identifier}` → the identifier as a code span
|
|
21
21
|
* - Bare URLs → returned as-is
|
|
22
22
|
* - Bare markdown links (`[text](url)` ...) → returned as-is
|
|
23
|
+
* - Content that opens with a backtick (a code span, then description text) → returned as-is
|
|
23
24
|
* - Bare identifiers → wrapped in backticks
|
|
24
|
-
* - `identifier description text` →
|
|
25
|
+
* - `identifier description text` → the first token wrapped in backticks, the rest as written
|
|
25
26
|
*
|
|
26
27
|
* @param content - raw `@see` tag content in TSDoc format
|
|
27
28
|
* @returns mdz-formatted string ready for `Mdz` component
|
|
@@ -37,11 +38,14 @@ const format_reference = (ref) => (mdz_is_url(ref) ? ref : `\`${ref}\``);
|
|
|
37
38
|
* mdz_from_tsdoc('https://fuz.dev')
|
|
38
39
|
* // → 'https://fuz.dev'
|
|
39
40
|
*
|
|
40
|
-
* mdz_from_tsdoc('[svelte-docinfo](https://github.com/
|
|
41
|
-
* // → '[svelte-docinfo](https://github.com/
|
|
41
|
+
* mdz_from_tsdoc('[svelte-docinfo](https://github.com/fuzdev/svelte-docinfo) for the analysis library')
|
|
42
|
+
* // → '[svelte-docinfo](https://github.com/fuzdev/svelte-docinfo) for the analysis library'
|
|
42
43
|
*
|
|
43
44
|
* mdz_from_tsdoc('tome.ts for the documentation system')
|
|
44
45
|
* // → '`tome.ts` for the documentation system'
|
|
46
|
+
*
|
|
47
|
+
* mdz_from_tsdoc('`tome.ts` for the `Tome` type')
|
|
48
|
+
* // → '`tome.ts` for the `Tome` type'
|
|
45
49
|
* ```
|
|
46
50
|
*/
|
|
47
51
|
export const mdz_from_tsdoc = (content) => {
|
|
@@ -77,6 +81,12 @@ export const mdz_from_tsdoc = (content) => {
|
|
|
77
81
|
if (trimmed.charCodeAt(0) === 91 /* [ */ && /^\[[^\]]+\]\([^)\s]+\)/.test(trimmed)) {
|
|
78
82
|
return trimmed;
|
|
79
83
|
}
|
|
84
|
+
// Pass through content that opens with a backtick: a leading code span is already mdz,
|
|
85
|
+
// and wrapping it again would leave both spans literal. An unclosed one is returned as
|
|
86
|
+
// written too, since adding a backtick the author didn't write can't make it a span.
|
|
87
|
+
if (trimmed.charCodeAt(0) === 96 /* ` */) {
|
|
88
|
+
return trimmed;
|
|
89
|
+
}
|
|
80
90
|
// Split at first whitespace: first token is the reference, rest is description
|
|
81
91
|
const space_index = trimmed.indexOf(' ');
|
|
82
92
|
if (space_index === -1) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/mdz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "a strict markdown dialect built for streaming, web authoring, docs, and untrusted content",
|
|
5
5
|
"tagline": "markdown for fuz",
|
|
6
6
|
"glyph": "📝",
|
|
@@ -64,12 +64,12 @@
|
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@fuzdev/blake3-wasm": "^0.2.0",
|
|
67
|
-
"@fuzdev/fuz_code": "^0.
|
|
67
|
+
"@fuzdev/fuz_code": "^0.59.0",
|
|
68
68
|
"@fuzdev/fuz_css": "^0.81.0",
|
|
69
69
|
"@fuzdev/fuz_schema": "^0.5.6",
|
|
70
|
-
"@fuzdev/fuz_ui": "^0.
|
|
71
|
-
"@fuzdev/fuz_util": "^0.
|
|
72
|
-
"@fuzdev/gro": "^0.
|
|
70
|
+
"@fuzdev/fuz_ui": "^0.227.0",
|
|
71
|
+
"@fuzdev/fuz_util": "^0.82.0",
|
|
72
|
+
"@fuzdev/gro": "^0.230.0",
|
|
73
73
|
"@ryanatkn/eslint-config": "^0.13.2",
|
|
74
74
|
"@sveltejs/acorn-typescript": "^1.0.10",
|
|
75
75
|
"@sveltejs/adapter-static": "^4.0.0",
|
package/src/lib/mdz.ts
CHANGED
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
*
|
|
15
15
|
* The dialect supports:
|
|
16
16
|
* - inline formatting: `code`, **bold**, _italic_, ~~strikethrough~~
|
|
17
|
-
* - auto-detected links: external URLs (`https://...`)
|
|
17
|
+
* - auto-detected links: external URLs (`https://...`) at the start of input or
|
|
18
|
+
* after any non-word character, and internal paths (`/path`, `./path`, `../path`)
|
|
19
|
+
* at the start of input, after whitespace, or after an opening `(` not preceded
|
|
20
|
+
* by an ASCII letter, digit, or `]` (such a path ends at its matching `)`)
|
|
18
21
|
* - markdown links: `[text](url)` with custom display text
|
|
19
22
|
* - inline code in backticks (creates `Code` nodes; auto-linking to identifiers/modules
|
|
20
23
|
* is handled by the rendering layer via `MdzNodeView.svelte`)
|
package/src/lib/mdz_contexts.ts
CHANGED
|
@@ -81,12 +81,28 @@ export const mdz_elements_context = create_context<() => MdzElements | undefined
|
|
|
81
81
|
*/
|
|
82
82
|
export const mdz_base_context = create_context<() => string | undefined>();
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The source offsets an injected `code` or `codeblock` component receives
|
|
86
|
+
* when `Mdz`'s `source_offsets` is on: its node's `start` and `end` in the
|
|
87
|
+
* parsed source. Named as the attributes, so a component that spreads rest
|
|
88
|
+
* props onto its root element (like `fuz_ui`'s `DocsLink` and `fuz_code`'s
|
|
89
|
+
* `Code`) carries them with no changes; any other can read them as props.
|
|
90
|
+
* Absent (`undefined`) when `source_offsets` is off.
|
|
91
|
+
*/
|
|
92
|
+
// a type literal, not an interface: the implicit index signature keeps the
|
|
93
|
+
// component types assignable from components whose props have index signatures
|
|
94
|
+
// (any spreading `SvelteHTMLElements` rest props, like `DocsLink` and `Code`)
|
|
95
|
+
export type MdzSourceOffsetProps = {
|
|
96
|
+
'data-mdz-start'?: number;
|
|
97
|
+
'data-mdz-end'?: number;
|
|
98
|
+
};
|
|
99
|
+
|
|
84
100
|
/**
|
|
85
101
|
* Component that renders an inline `` `code` `` span. Receives the raw span
|
|
86
102
|
* content as `reference` — the prop name matches `fuz_ui`'s `DocsLink`, so it
|
|
87
103
|
* can be injected directly to auto-link backticked API identifiers.
|
|
88
104
|
*/
|
|
89
|
-
export type MdzCodeComponent = Component<{ reference: string }>;
|
|
105
|
+
export type MdzCodeComponent = Component<{ reference: string } & MdzSourceOffsetProps>;
|
|
90
106
|
|
|
91
107
|
/**
|
|
92
108
|
* Context for overriding how inline `` `code` `` spans render, via a getter
|
|
@@ -99,7 +115,9 @@ export const mdz_code_context = create_context<() => MdzCodeComponent | undefine
|
|
|
99
115
|
* matching `@fuzdev/fuz_code`'s `Code`, so it can be injected directly for
|
|
100
116
|
* syntax highlighting.
|
|
101
117
|
*/
|
|
102
|
-
export type MdzCodeblockComponent = Component<
|
|
118
|
+
export type MdzCodeblockComponent = Component<
|
|
119
|
+
{ lang: string | null; content: string } & MdzSourceOffsetProps
|
|
120
|
+
>;
|
|
103
121
|
|
|
104
122
|
/**
|
|
105
123
|
* Context for overriding how fenced code blocks render, via a getter function.
|