@fuzdev/mdz 0.3.0 → 0.4.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/README.md +4 -0
- package/dist/Mdz.svelte +8 -7
- package/dist/Mdz.svelte.d.ts.map +1 -1
- package/dist/MdzNodeView.svelte +20 -12
- package/dist/MdzNodeView.svelte.d.ts +1 -2
- package/dist/MdzNodeView.svelte.d.ts.map +1 -1
- package/dist/MdzPrecompiled.svelte +3 -3
- package/dist/MdzPrecompiled.svelte.d.ts.map +1 -1
- package/dist/MdzRoot.svelte +3 -3
- package/dist/MdzRoot.svelte.d.ts.map +1 -1
- package/dist/MdzStream.svelte +3 -3
- package/dist/MdzStream.svelte.d.ts.map +1 -1
- package/dist/MdzStreamNodeView.svelte +21 -13
- package/dist/MdzStreamNodeView.svelte.d.ts +1 -2
- package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -1
- package/dist/context_helpers.js +1 -1
- 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.map +1 -1
- package/dist/mdz_helpers.js +2 -2
- package/dist/mdz_lexer.d.ts.map +1 -1
- package/dist/mdz_lexer.js +27 -17
- package/dist/mdz_opcodes.d.ts.map +1 -1
- package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -1
- package/dist/mdz_opcodes_to_nodes.js +22 -17
- package/dist/mdz_stream_parser.d.ts.map +1 -1
- package/dist/mdz_stream_parser.js +8 -8
- package/dist/mdz_stream_parser_block.js +5 -5
- package/dist/mdz_stream_parser_inline.js +4 -4
- package/dist/mdz_stream_parser_link.js +3 -3
- package/dist/mdz_stream_parser_list.d.ts.map +1 -1
- package/dist/mdz_stream_parser_list.js +13 -7
- package/dist/mdz_stream_parser_state.d.ts.map +1 -1
- package/dist/mdz_stream_parser_state.js +7 -7
- package/dist/mdz_stream_parser_table.d.ts.map +1 -1
- package/dist/mdz_stream_parser_table.js +8 -8
- package/dist/mdz_stream_parser_text.js +2 -2
- package/dist/mdz_stream_parser_url.js +7 -7
- package/dist/mdz_stream_state.svelte.d.ts.map +1 -1
- package/dist/mdz_to_svelte.d.ts +1 -1
- package/dist/mdz_to_svelte.d.ts.map +1 -1
- package/dist/mdz_token_parser.js +9 -9
- package/dist/svelte_preprocess_mdz.d.ts +2 -2
- package/dist/svelte_preprocess_mdz.d.ts.map +1 -1
- package/dist/svelte_preprocess_mdz.js +11 -11
- package/package.json +24 -39
- package/src/lib/context_helpers.ts +2 -2
- package/src/lib/mdz.ts +2 -2
- package/src/lib/mdz_contexts.ts +5 -5
- package/src/lib/mdz_debug_work.ts +1 -1
- package/src/lib/mdz_helpers.ts +39 -33
- package/src/lib/mdz_lexer.ts +77 -67
- package/src/lib/mdz_opcodes.ts +1 -1
- package/src/lib/mdz_opcodes_to_nodes.ts +35 -30
- package/src/lib/mdz_stream_parser.ts +17 -17
- package/src/lib/mdz_stream_parser_block.ts +14 -14
- package/src/lib/mdz_stream_parser_inline.ts +18 -18
- package/src/lib/mdz_stream_parser_link.ts +13 -13
- package/src/lib/mdz_stream_parser_list.ts +31 -25
- package/src/lib/mdz_stream_parser_state.ts +27 -27
- package/src/lib/mdz_stream_parser_table.ts +31 -31
- package/src/lib/mdz_stream_parser_text.ts +3 -3
- package/src/lib/mdz_stream_parser_url.ts +11 -11
- package/src/lib/mdz_stream_state.svelte.ts +8 -8
- package/src/lib/mdz_to_svelte.ts +16 -16
- package/src/lib/mdz_token_parser.ts +38 -38
- package/src/lib/svelte_preprocess_mdz.ts +62 -58
- package/src/lib/tsdoc_mdz.ts +1 -1
package/dist/mdz_token_parser.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import { has_non_whitespace, mdz_extract_single_tag, mdz_heading_id, mdz_merge_adjacent_text, mdz_push_merging_text
|
|
9
|
+
import { has_non_whitespace, mdz_extract_single_tag, mdz_heading_id, mdz_merge_adjacent_text, mdz_push_merging_text } from './mdz_helpers.js';
|
|
10
10
|
import {} from './mdz_lexer.js';
|
|
11
11
|
/**
|
|
12
12
|
* Whether a token type ends the current inline context — the block-boundary
|
|
@@ -101,7 +101,7 @@ export class MdzTokenParser {
|
|
|
101
101
|
lang: token.lang,
|
|
102
102
|
content: token.content,
|
|
103
103
|
start: token.start,
|
|
104
|
-
end: token.end
|
|
104
|
+
end: token.end
|
|
105
105
|
});
|
|
106
106
|
this.#index++;
|
|
107
107
|
continue;
|
|
@@ -256,7 +256,7 @@ export class MdzTokenParser {
|
|
|
256
256
|
start_number: children[0]?.number ?? 1,
|
|
257
257
|
children,
|
|
258
258
|
start: open.start,
|
|
259
|
-
end
|
|
259
|
+
end
|
|
260
260
|
};
|
|
261
261
|
}
|
|
262
262
|
return { type: 'List', ordered: false, children, start: open.start, end };
|
|
@@ -306,7 +306,7 @@ export class MdzTokenParser {
|
|
|
306
306
|
lang: t.lang,
|
|
307
307
|
content: t.content,
|
|
308
308
|
start: t.start,
|
|
309
|
-
end: t.end
|
|
309
|
+
end: t.end
|
|
310
310
|
});
|
|
311
311
|
this.#index++;
|
|
312
312
|
continue;
|
|
@@ -378,7 +378,7 @@ export class MdzTokenParser {
|
|
|
378
378
|
type: 'Text',
|
|
379
379
|
content: `(${token.reference})`,
|
|
380
380
|
start: token.start,
|
|
381
|
-
end: token.end
|
|
381
|
+
end: token.end
|
|
382
382
|
};
|
|
383
383
|
case 'tag_close':
|
|
384
384
|
this.#index++;
|
|
@@ -386,7 +386,7 @@ export class MdzTokenParser {
|
|
|
386
386
|
type: 'Text',
|
|
387
387
|
content: `</${token.name}>`,
|
|
388
388
|
start: token.start,
|
|
389
|
-
end: token.end
|
|
389
|
+
end: token.end
|
|
390
390
|
};
|
|
391
391
|
default:
|
|
392
392
|
this.#index++;
|
|
@@ -440,7 +440,7 @@ export class MdzTokenParser {
|
|
|
440
440
|
children,
|
|
441
441
|
link_type: ref_token.link_type,
|
|
442
442
|
start,
|
|
443
|
-
end: ref_token.end
|
|
443
|
+
end: ref_token.end
|
|
444
444
|
};
|
|
445
445
|
}
|
|
446
446
|
// No link_ref - treat as text
|
|
@@ -464,7 +464,7 @@ export class MdzTokenParser {
|
|
|
464
464
|
children: [{ type: 'Text', content: token.reference, start: token.start, end: token.end }],
|
|
465
465
|
link_type: token.link_type,
|
|
466
466
|
start: token.start,
|
|
467
|
-
end: token.end
|
|
467
|
+
end: token.end
|
|
468
468
|
};
|
|
469
469
|
}
|
|
470
470
|
#parse_tag_node() {
|
|
@@ -541,7 +541,7 @@ export class MdzTokenParser {
|
|
|
541
541
|
type: 'Paragraph',
|
|
542
542
|
children: merged,
|
|
543
543
|
start: merged[0].start,
|
|
544
|
-
end: merged[merged.length - 1].end
|
|
544
|
+
end: merged[merged.length - 1].end
|
|
545
545
|
};
|
|
546
546
|
}
|
|
547
547
|
}
|
|
@@ -23,7 +23,7 @@ export interface SveltePreprocessMdzOptions {
|
|
|
23
23
|
/**
|
|
24
24
|
* Component import mapping for mdz content.
|
|
25
25
|
* Key: component name as used in mdz (e.g., 'Alert').
|
|
26
|
-
* Value: import path (e.g., '
|
|
26
|
+
* Value: import path (e.g., '#lib/Alert.svelte').
|
|
27
27
|
*
|
|
28
28
|
* If mdz content references a component not in this map,
|
|
29
29
|
* that `Mdz` usage is skipped (left as runtime).
|
|
@@ -74,7 +74,7 @@ export interface SveltePreprocessMdzOptions {
|
|
|
74
74
|
* Creates a Svelte preprocessor that compiles static `Mdz` content at build time.
|
|
75
75
|
*
|
|
76
76
|
* @param options - configuration for component/element resolution and file filtering
|
|
77
|
-
* @returns a Svelte `PreprocessorGroup` for
|
|
77
|
+
* @returns a Svelte `PreprocessorGroup` for a `preprocess` option, like `sveltekit({preprocess})` in `vite.config.ts`
|
|
78
78
|
*/
|
|
79
79
|
export declare const svelte_preprocess_mdz: (options?: SveltePreprocessMdzOptions) => PreprocessorGroup;
|
|
80
80
|
//# sourceMappingURL=svelte_preprocess_mdz.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svelte_preprocess_mdz.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte_preprocess_mdz.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"svelte_preprocess_mdz.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte_preprocess_mdz.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAS,KAAK,iBAAiB,EAAY,MAAM,iBAAiB,CAAC;AA+B1E;;GAEG;AACH,MAAM,WAAW,0BAA0B;IAC1C,gCAAgC;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAEjC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;;;;;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"}
|
|
@@ -17,7 +17,7 @@ import { parse } from 'svelte/compiler';
|
|
|
17
17
|
import MagicString from 'magic-string';
|
|
18
18
|
import { walk } from 'zimmerframe';
|
|
19
19
|
import { should_exclude_path } from '@fuzdev/fuz_util/path.ts';
|
|
20
|
-
import { find_attribute, extract_static_string, try_extract_conditional_chain, build_static_bindings, resolve_component_names, has_identifier_in_tree, find_import_insert_position, generate_import_lines, remove_variable_declaration, remove_import_declaration, remove_import_specifier, handle_preprocess_error
|
|
20
|
+
import { find_attribute, extract_static_string, try_extract_conditional_chain, build_static_bindings, resolve_component_names, has_identifier_in_tree, find_import_insert_position, generate_import_lines, remove_variable_declaration, remove_import_declaration, remove_import_specifier, handle_preprocess_error } from '@fuzdev/fuz_util/svelte_preprocess_helpers.ts';
|
|
21
21
|
import { mdz_parse } from './mdz.js';
|
|
22
22
|
import { mdz_to_svelte } from './mdz_to_svelte.js';
|
|
23
23
|
const PRECOMPILED_NAME = 'MdzPrecompiled';
|
|
@@ -25,10 +25,10 @@ const PRECOMPILED_NAME = 'MdzPrecompiled';
|
|
|
25
25
|
* Creates a Svelte preprocessor that compiles static `Mdz` content at build time.
|
|
26
26
|
*
|
|
27
27
|
* @param options - configuration for component/element resolution and file filtering
|
|
28
|
-
* @returns a Svelte `PreprocessorGroup` for
|
|
28
|
+
* @returns a Svelte `PreprocessorGroup` for a `preprocess` option, like `sveltekit({preprocess})` in `vite.config.ts`
|
|
29
29
|
*/
|
|
30
30
|
export const svelte_preprocess_mdz = (options = {}) => {
|
|
31
|
-
const { exclude = [], components = {}, elements = {}, mdz_component_imports = ['@fuzdev/mdz/Mdz.svelte'], compiled_component_import = '@fuzdev/mdz/MdzPrecompiled.svelte', code_component_import, codeblock_component_import, on_error = process.env.CI === 'true' ? 'throw' : 'log'
|
|
31
|
+
const { exclude = [], components = {}, elements = {}, mdz_component_imports = ['@fuzdev/mdz/Mdz.svelte'], compiled_component_import = '@fuzdev/mdz/MdzPrecompiled.svelte', code_component_import, codeblock_component_import, on_error = process.env.CI === 'true' ? 'throw' : 'log' } = options;
|
|
32
32
|
return {
|
|
33
33
|
name: 'fuz-mdz',
|
|
34
34
|
markup: ({ content, filename }) => {
|
|
@@ -60,7 +60,7 @@ export const svelte_preprocess_mdz = (options = {}) => {
|
|
|
60
60
|
bindings,
|
|
61
61
|
on_error,
|
|
62
62
|
code_component_import,
|
|
63
|
-
codeblock_component_import
|
|
63
|
+
codeblock_component_import
|
|
64
64
|
});
|
|
65
65
|
if (transformations.length === 0) {
|
|
66
66
|
return { code: content };
|
|
@@ -77,9 +77,9 @@ export const svelte_preprocess_mdz = (options = {}) => {
|
|
|
77
77
|
manage_imports(s, ast, transformations, removable_imports, compiled_component_import, content);
|
|
78
78
|
return {
|
|
79
79
|
code: s.toString(),
|
|
80
|
-
map: s.generateMap({ hires: true })
|
|
80
|
+
map: s.generateMap({ hires: true })
|
|
81
81
|
};
|
|
82
|
-
}
|
|
82
|
+
}
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
85
|
/**
|
|
@@ -152,7 +152,7 @@ const render_static_mdz = (content, base, context) => {
|
|
|
152
152
|
elements: context.elements,
|
|
153
153
|
base,
|
|
154
154
|
code_component_import: context.code_component_import,
|
|
155
|
-
codeblock_component_import: context.codeblock_component_import
|
|
155
|
+
codeblock_component_import: context.codeblock_component_import
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
158
|
catch (error) {
|
|
@@ -216,7 +216,7 @@ const find_mdz_usages = (ast, mdz_names, context) => {
|
|
|
216
216
|
replacement,
|
|
217
217
|
required_imports: result.imports,
|
|
218
218
|
consumed_bindings: consumed,
|
|
219
|
-
component_node: node
|
|
219
|
+
component_node: node
|
|
220
220
|
});
|
|
221
221
|
return;
|
|
222
222
|
}
|
|
@@ -264,9 +264,9 @@ const find_mdz_usages = (ast, mdz_names, context) => {
|
|
|
264
264
|
replacement,
|
|
265
265
|
required_imports: merged_imports,
|
|
266
266
|
consumed_bindings: consumed,
|
|
267
|
-
component_node: node
|
|
267
|
+
component_node: node
|
|
268
268
|
});
|
|
269
|
-
}
|
|
269
|
+
}
|
|
270
270
|
});
|
|
271
271
|
return { transformations, total_usages, transformed_usages };
|
|
272
272
|
};
|
|
@@ -396,7 +396,7 @@ const find_removable_mdz_imports = (ast, mdz_names, total_usages, transformed_us
|
|
|
396
396
|
removable.set(name, {
|
|
397
397
|
node: positioned_node,
|
|
398
398
|
kind: 'partial',
|
|
399
|
-
specifier_to_remove: specifier
|
|
399
|
+
specifier_to_remove: specifier
|
|
400
400
|
});
|
|
401
401
|
}
|
|
402
402
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/mdz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "a strict markdown dialect built for streaming, Svelte authoring, docs websites, and untrusted content",
|
|
5
5
|
"tagline": "markdown for fuz",
|
|
6
6
|
"glyph": "📝",
|
|
@@ -36,12 +36,16 @@
|
|
|
36
36
|
"benchmark:render:clean": "rm -f src/benchmarks/render/baseline.json"
|
|
37
37
|
},
|
|
38
38
|
"type": "module",
|
|
39
|
+
"imports": {
|
|
40
|
+
"#lib/*": "./src/lib/*",
|
|
41
|
+
"#routes/*": "./src/routes/*"
|
|
42
|
+
},
|
|
39
43
|
"engines": {
|
|
40
44
|
"node": ">=24.14"
|
|
41
45
|
},
|
|
42
46
|
"peerDependencies": {
|
|
43
47
|
"@fuzdev/fuz_util": ">=0.65.1",
|
|
44
|
-
"@sveltejs/kit": "^
|
|
48
|
+
"@sveltejs/kit": "^3",
|
|
45
49
|
"@types/estree": "^1",
|
|
46
50
|
"esm-env": "^1",
|
|
47
51
|
"svelte": "^5"
|
|
@@ -59,52 +63,33 @@
|
|
|
59
63
|
"zimmerframe": "^1.1.4"
|
|
60
64
|
},
|
|
61
65
|
"devDependencies": {
|
|
62
|
-
"@fuzdev/
|
|
63
|
-
"@fuzdev/fuz_code": "^0.
|
|
64
|
-
"@fuzdev/fuz_css": "^0.
|
|
65
|
-
"@fuzdev/fuz_ui": "^0.
|
|
66
|
-
"@fuzdev/fuz_util": "^0.
|
|
67
|
-
"@fuzdev/gro": "^0.
|
|
68
|
-
"@ryanatkn/eslint-config": "^0.12.
|
|
66
|
+
"@fuzdev/blake3-wasm": "^0.2.0",
|
|
67
|
+
"@fuzdev/fuz_code": "^0.50.0",
|
|
68
|
+
"@fuzdev/fuz_css": "^0.66.1",
|
|
69
|
+
"@fuzdev/fuz_ui": "^0.212.0",
|
|
70
|
+
"@fuzdev/fuz_util": "^0.72.0",
|
|
71
|
+
"@fuzdev/gro": "^0.214.0",
|
|
72
|
+
"@ryanatkn/eslint-config": "^0.12.2",
|
|
69
73
|
"@sveltejs/acorn-typescript": "^1.0.10",
|
|
70
|
-
"@sveltejs/adapter-static": "^
|
|
71
|
-
"@sveltejs/kit": "
|
|
72
|
-
"@sveltejs/package": "^
|
|
73
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
74
|
+
"@sveltejs/adapter-static": "^4.0.0",
|
|
75
|
+
"@sveltejs/kit": "^3.0.1",
|
|
76
|
+
"@sveltejs/package": "^3.0.0",
|
|
77
|
+
"@sveltejs/vite-plugin-svelte": "^7.3.1",
|
|
74
78
|
"@types/estree": "^1.0.8",
|
|
75
79
|
"@types/node": "^24.12.4",
|
|
76
80
|
"@webref/css": "^8.2.0",
|
|
77
81
|
"eslint": "^9.39.1",
|
|
78
82
|
"eslint-plugin-svelte": "^3.13.1",
|
|
79
83
|
"esm-env": "^1.2.2",
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"svelte": "^
|
|
83
|
-
"svelte-check": "^4.6.0",
|
|
84
|
-
"svelte-docinfo": "^0.5.3",
|
|
84
|
+
"svelte": "^5.57.2",
|
|
85
|
+
"svelte-check": "^4.7.6",
|
|
86
|
+
"svelte-docinfo": "^0.8.0",
|
|
85
87
|
"svelte2tsx": "^0.7.56",
|
|
86
88
|
"tslib": "^2.8.1",
|
|
87
|
-
"typescript": "^
|
|
88
|
-
"typescript-eslint": "^8.
|
|
89
|
-
"vite": "^
|
|
90
|
-
"vitest": "^
|
|
91
|
-
},
|
|
92
|
-
"prettier": {
|
|
93
|
-
"plugins": [
|
|
94
|
-
"prettier-plugin-svelte"
|
|
95
|
-
],
|
|
96
|
-
"useTabs": true,
|
|
97
|
-
"printWidth": 100,
|
|
98
|
-
"singleQuote": true,
|
|
99
|
-
"bracketSpacing": false,
|
|
100
|
-
"overrides": [
|
|
101
|
-
{
|
|
102
|
-
"files": "package.json",
|
|
103
|
-
"options": {
|
|
104
|
-
"useTabs": false
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
]
|
|
89
|
+
"typescript": "^6.0.3",
|
|
90
|
+
"typescript-eslint": "^8.71.1",
|
|
91
|
+
"vite": "^8.3.4",
|
|
92
|
+
"vitest": "^5.0.0"
|
|
108
93
|
},
|
|
109
94
|
"sideEffects": [
|
|
110
95
|
"**/*.css"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {getContext, setContext} from 'svelte';
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
2
|
|
|
3
3
|
// This uses a function instead of a class because of the overloaded type signatures.
|
|
4
4
|
// It could be implemented internally with a class like `SvelteContext`
|
|
@@ -47,6 +47,6 @@ export function create_context<T>(fallback?: () => T): {
|
|
|
47
47
|
},
|
|
48
48
|
get_maybe,
|
|
49
49
|
// this is typesafe, so no runtime check:
|
|
50
|
-
set: (value: T | undefined = fallback?.()) => setContext(key, value)
|
|
50
|
+
set: (value: T | undefined = fallback?.()) => setContext(key, value)!
|
|
51
51
|
};
|
|
52
52
|
}
|
package/src/lib/mdz.ts
CHANGED
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
* @module
|
|
51
51
|
*/
|
|
52
52
|
|
|
53
|
-
import {MdzLexer} from './mdz_lexer.ts';
|
|
54
|
-
import {MdzTokenParser} from './mdz_token_parser.ts';
|
|
53
|
+
import { MdzLexer } from './mdz_lexer.ts';
|
|
54
|
+
import { MdzTokenParser } from './mdz_token_parser.ts';
|
|
55
55
|
|
|
56
56
|
// TODO design incremental parsing or some system that preserves Svelte components across re-renders when possible
|
|
57
57
|
|
package/src/lib/mdz_contexts.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {Component} from 'svelte';
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
2
|
|
|
3
|
-
import {create_context} from './context_helpers.ts';
|
|
3
|
+
import { create_context } from './context_helpers.ts';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Component registry for custom Svelte components that can be used in mdz content.
|
|
@@ -56,7 +56,7 @@ export const mdz_base_context = create_context<() => string | undefined>();
|
|
|
56
56
|
* content as `reference` — the prop name matches `fuz_ui`'s `DocsLink`, so it
|
|
57
57
|
* can be injected directly to auto-link backticked API identifiers.
|
|
58
58
|
*/
|
|
59
|
-
export type MdzCodeComponent = Component<{reference: string}>;
|
|
59
|
+
export type MdzCodeComponent = Component<{ reference: string }>;
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Context for overriding how inline `` `code` `` spans render, via a getter
|
|
@@ -69,7 +69,7 @@ export const mdz_code_context = create_context<() => MdzCodeComponent | undefine
|
|
|
69
69
|
* matching `@fuzdev/fuz_code`'s `Code`, so it can be injected directly for
|
|
70
70
|
* syntax highlighting.
|
|
71
71
|
*/
|
|
72
|
-
export type MdzCodeblockComponent = Component<{lang: string | null; content: string}>;
|
|
72
|
+
export type MdzCodeblockComponent = Component<{ lang: string | null; content: string }>;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Context for overriding how fenced code blocks render, via a getter function.
|
|
@@ -92,7 +92,7 @@ interface MdzGetterContext<T> {
|
|
|
92
92
|
*/
|
|
93
93
|
export const mdz_set_context_with_fallback = <T>(
|
|
94
94
|
context: MdzGetterContext<T>,
|
|
95
|
-
value_fn: () => T | undefined
|
|
95
|
+
value_fn: () => T | undefined
|
|
96
96
|
): void => {
|
|
97
97
|
const ancestor = context.get_maybe();
|
|
98
98
|
context.set(() => value_fn() ?? ancestor?.());
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*
|
|
24
24
|
* @nodocs
|
|
25
25
|
*/
|
|
26
|
-
export const mdz_debug_work: {enabled: boolean; total: number} = {enabled: false, total: 0};
|
|
26
|
+
export const mdz_debug_work: { enabled: boolean; total: number } = { enabled: false, total: 0 };
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Reset the counter and set whether the hot paths accumulate into it. Tests call
|
package/src/lib/mdz_helpers.ts
CHANGED
|
@@ -7,7 +7,13 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
MdzNode,
|
|
12
|
+
MdzNodeText,
|
|
13
|
+
MdzNodeComponent,
|
|
14
|
+
MdzNodeElement,
|
|
15
|
+
MdzTableAlign
|
|
16
|
+
} from './mdz.ts';
|
|
11
17
|
|
|
12
18
|
// Character codes for performance
|
|
13
19
|
/** @nodocs */
|
|
@@ -197,7 +203,7 @@ export interface MdzBlockquotePrefix {
|
|
|
197
203
|
export const mdz_match_blockquote_prefix = (
|
|
198
204
|
text: string,
|
|
199
205
|
i: number,
|
|
200
|
-
forced: boolean
|
|
206
|
+
forced: boolean
|
|
201
207
|
): MdzBlockquotePrefix | 'pending' | null => {
|
|
202
208
|
let depth = 0;
|
|
203
209
|
let pos = i;
|
|
@@ -207,23 +213,23 @@ export const mdz_match_blockquote_prefix = (
|
|
|
207
213
|
depth++;
|
|
208
214
|
pos++;
|
|
209
215
|
if (pos >= text.length) {
|
|
210
|
-
return forced ? {depth, content_start: pos} : 'pending';
|
|
216
|
+
return forced ? { depth, content_start: pos } : 'pending';
|
|
211
217
|
}
|
|
212
218
|
const c = text.charCodeAt(pos);
|
|
213
219
|
if (c === RIGHT_ANGLE) continue; // tight run
|
|
214
220
|
if (c === SPACE) {
|
|
215
221
|
if (pos + 1 >= text.length) {
|
|
216
222
|
// could be a separator (next chunk starts with `>`) or the terminator
|
|
217
|
-
return forced ? {depth, content_start: pos + 1} : 'pending';
|
|
223
|
+
return forced ? { depth, content_start: pos + 1 } : 'pending';
|
|
218
224
|
}
|
|
219
225
|
if (text.charCodeAt(pos + 1) === RIGHT_ANGLE) {
|
|
220
226
|
pos++; // separator — continue the run at the next `>`
|
|
221
227
|
continue;
|
|
222
228
|
}
|
|
223
|
-
return {depth, content_start: pos + 1}; // terminating space
|
|
229
|
+
return { depth, content_start: pos + 1 }; // terminating space
|
|
224
230
|
}
|
|
225
231
|
if (c === NEWLINE) {
|
|
226
|
-
return {depth, content_start: pos}; // bare prefix line
|
|
232
|
+
return { depth, content_start: pos }; // bare prefix line
|
|
227
233
|
}
|
|
228
234
|
if (is_line_whitespace(c)) {
|
|
229
235
|
// tab/CR is not the marker space — valid only as tolerated trailing
|
|
@@ -233,17 +239,17 @@ export const mdz_match_blockquote_prefix = (
|
|
|
233
239
|
j++;
|
|
234
240
|
}
|
|
235
241
|
if (j >= text.length) {
|
|
236
|
-
return forced ? {depth, content_start: pos} : 'pending';
|
|
242
|
+
return forced ? { depth, content_start: pos } : 'pending';
|
|
237
243
|
}
|
|
238
244
|
if (text.charCodeAt(j) === NEWLINE) {
|
|
239
|
-
return {depth, content_start: pos};
|
|
245
|
+
return { depth, content_start: pos };
|
|
240
246
|
}
|
|
241
247
|
// trailing content after non-space whitespace — fall through to backtrack
|
|
242
248
|
}
|
|
243
249
|
// invalid char directly after a `>`: this `>` is content; the separator
|
|
244
250
|
// space before it (if any) re-serves as the terminator
|
|
245
251
|
if (depth >= 2 && text.charCodeAt(pos - 2) === SPACE) {
|
|
246
|
-
return {depth: depth - 1, content_start: pos - 1};
|
|
252
|
+
return { depth: depth - 1, content_start: pos - 1 };
|
|
247
253
|
}
|
|
248
254
|
return null;
|
|
249
255
|
}
|
|
@@ -260,7 +266,7 @@ export const mdz_match_blockquote_prefix = (
|
|
|
260
266
|
export const mdz_blockquote_line_has_content = (
|
|
261
267
|
text: string,
|
|
262
268
|
content_start: number,
|
|
263
|
-
forced: boolean
|
|
269
|
+
forced: boolean
|
|
264
270
|
): boolean | 'pending' => {
|
|
265
271
|
let i = content_start;
|
|
266
272
|
while (i < text.length && is_line_whitespace(text.charCodeAt(i))) {
|
|
@@ -291,8 +297,8 @@ export const mdz_blockquote_strip_width = (text: string, i: number): number =>
|
|
|
291
297
|
* @nodocs
|
|
292
298
|
*/
|
|
293
299
|
export const mdz_remap_segments = (
|
|
294
|
-
segments: Array<{inner_start: number; source_start: number}>,
|
|
295
|
-
p: number
|
|
300
|
+
segments: Array<{ inner_start: number; source_start: number }>,
|
|
301
|
+
p: number
|
|
296
302
|
): number => {
|
|
297
303
|
let lo = 0;
|
|
298
304
|
let hi = segments.length - 1;
|
|
@@ -314,13 +320,13 @@ export const mdz_remap_segments = (
|
|
|
314
320
|
const trim_table_cell = (
|
|
315
321
|
text: string,
|
|
316
322
|
start: number,
|
|
317
|
-
end: number
|
|
318
|
-
): {start: number; end: number} => {
|
|
323
|
+
end: number
|
|
324
|
+
): { start: number; end: number } => {
|
|
319
325
|
let s = start;
|
|
320
326
|
let e = end;
|
|
321
327
|
while (s < e && is_line_whitespace(text.charCodeAt(s))) s++;
|
|
322
328
|
while (e > s && is_line_whitespace(text.charCodeAt(e - 1))) e--;
|
|
323
|
-
return {start: s, end: e};
|
|
329
|
+
return { start: s, end: e };
|
|
324
330
|
};
|
|
325
331
|
|
|
326
332
|
/**
|
|
@@ -343,10 +349,10 @@ const trim_table_cell = (
|
|
|
343
349
|
export const mdz_split_table_row = (
|
|
344
350
|
text: string,
|
|
345
351
|
line_start: number,
|
|
346
|
-
line_end: number
|
|
347
|
-
): Array<{start: number; end: number}> | null => {
|
|
352
|
+
line_end: number
|
|
353
|
+
): Array<{ start: number; end: number }> | null => {
|
|
348
354
|
if (line_start >= line_end || text.charCodeAt(line_start) !== PIPE) return null;
|
|
349
|
-
const cells: Array<{start: number; end: number}> = [];
|
|
355
|
+
const cells: Array<{ start: number; end: number }> = [];
|
|
350
356
|
let i = line_start + 1; // past the leading pipe
|
|
351
357
|
let cell_start = i;
|
|
352
358
|
while (i < line_end) {
|
|
@@ -415,7 +421,7 @@ const table_delimiter_align = (text: string, start: number, end: number): MdzTab
|
|
|
415
421
|
export const mdz_parse_table_delimiter = (
|
|
416
422
|
text: string,
|
|
417
423
|
line_start: number,
|
|
418
|
-
line_end: number
|
|
424
|
+
line_end: number
|
|
419
425
|
): Array<MdzTableAlign> | null => {
|
|
420
426
|
const cells = mdz_split_table_row(text, line_start, line_end);
|
|
421
427
|
if (cells === null) return null;
|
|
@@ -769,7 +775,7 @@ const VOID_ELEMENTS = new Set([
|
|
|
769
775
|
'meta',
|
|
770
776
|
'source',
|
|
771
777
|
'track',
|
|
772
|
-
'wbr'
|
|
778
|
+
'wbr'
|
|
773
779
|
]);
|
|
774
780
|
|
|
775
781
|
/**
|
|
@@ -819,13 +825,13 @@ export const mdz_resolve_relative_path = (reference: string, base: string): stri
|
|
|
819
825
|
*/
|
|
820
826
|
export type MdzLinkRender =
|
|
821
827
|
/** Unsafe protocol — render children only, no `<a>`. */
|
|
822
|
-
| {kind: 'unsafe'}
|
|
828
|
+
| { kind: 'unsafe' }
|
|
823
829
|
/** Route/relative path — wrap in `resolve()` (needs `$app/paths`). */
|
|
824
|
-
| {kind: 'resolve'; href: string}
|
|
830
|
+
| { kind: 'resolve'; href: string }
|
|
825
831
|
/** Internal fragment/query/relative/bare ref — raw `href`, no `resolve()`. */
|
|
826
|
-
| {kind: 'internal'; href: string}
|
|
832
|
+
| { kind: 'internal'; href: string }
|
|
827
833
|
/** External link — raw `href` plus `target="_blank" rel="noopener"`. */
|
|
828
|
-
| {kind: 'external'; href: string};
|
|
834
|
+
| { kind: 'external'; href: string };
|
|
829
835
|
|
|
830
836
|
/**
|
|
831
837
|
* Classify a `Link` reference into how it should render. Pure — no rendering,
|
|
@@ -835,12 +841,12 @@ export type MdzLinkRender =
|
|
|
835
841
|
export const mdz_classify_link = (
|
|
836
842
|
reference: string,
|
|
837
843
|
link_type: 'internal' | 'external' | undefined,
|
|
838
|
-
base: string | undefined
|
|
844
|
+
base: string | undefined
|
|
839
845
|
): MdzLinkRender => {
|
|
840
|
-
if (!mdz_is_safe_reference(reference)) return {kind: 'unsafe'};
|
|
846
|
+
if (!mdz_is_safe_reference(reference)) return { kind: 'unsafe' };
|
|
841
847
|
if (link_type === 'internal') {
|
|
842
848
|
if (reference.startsWith('.') && base) {
|
|
843
|
-
return {kind: 'resolve', href: mdz_resolve_relative_path(reference, base)};
|
|
849
|
+
return { kind: 'resolve', href: mdz_resolve_relative_path(reference, base) };
|
|
844
850
|
}
|
|
845
851
|
// fragment/query/relative/bare — `resolve()` only accepts absolute paths or
|
|
846
852
|
// route ids and throws on anything else
|
|
@@ -850,11 +856,11 @@ export const mdz_classify_link = (
|
|
|
850
856
|
reference.startsWith('.') ||
|
|
851
857
|
!reference.startsWith('/')
|
|
852
858
|
) {
|
|
853
|
-
return {kind: 'internal', href: reference};
|
|
859
|
+
return { kind: 'internal', href: reference };
|
|
854
860
|
}
|
|
855
|
-
return {kind: 'resolve', href: reference};
|
|
861
|
+
return { kind: 'resolve', href: reference };
|
|
856
862
|
}
|
|
857
|
-
return {kind: 'external', href: reference};
|
|
863
|
+
return { kind: 'external', href: reference };
|
|
858
864
|
};
|
|
859
865
|
|
|
860
866
|
/**
|
|
@@ -901,10 +907,10 @@ export const mdz_merge_adjacent_text = (nodes: Array<MdzNode>): Array<MdzNode> =
|
|
|
901
907
|
type: 'Text',
|
|
902
908
|
content: pending.content + node.content,
|
|
903
909
|
start: pending.start,
|
|
904
|
-
end: node.end
|
|
910
|
+
end: node.end
|
|
905
911
|
};
|
|
906
912
|
} else {
|
|
907
|
-
pending = {...node};
|
|
913
|
+
pending = { ...node };
|
|
908
914
|
}
|
|
909
915
|
} else {
|
|
910
916
|
if (pending) {
|
|
@@ -927,7 +933,7 @@ export const mdz_merge_adjacent_text = (nodes: Array<MdzNode>): Array<MdzNode> =
|
|
|
927
933
|
* or `null` if the content should be wrapped in a paragraph
|
|
928
934
|
*/
|
|
929
935
|
export const mdz_extract_single_tag = (
|
|
930
|
-
nodes: Array<MdzNode
|
|
936
|
+
nodes: Array<MdzNode>
|
|
931
937
|
): MdzNodeComponent | MdzNodeElement | null => {
|
|
932
938
|
let tag: MdzNodeComponent | MdzNodeElement | null = null;
|
|
933
939
|
|