@fuzdev/mdz 0.1.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.
Files changed (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -0
  3. package/dist/Mdz.svelte +39 -0
  4. package/dist/Mdz.svelte.d.ts +17 -0
  5. package/dist/Mdz.svelte.d.ts.map +1 -0
  6. package/dist/MdzNodeView.svelte +140 -0
  7. package/dist/MdzNodeView.svelte.d.ts +9 -0
  8. package/dist/MdzNodeView.svelte.d.ts.map +1 -0
  9. package/dist/MdzPrecompiled.svelte +33 -0
  10. package/dist/MdzPrecompiled.svelte.d.ts +17 -0
  11. package/dist/MdzPrecompiled.svelte.d.ts.map +1 -0
  12. package/dist/MdzRoot.svelte +40 -0
  13. package/dist/MdzRoot.svelte.d.ts +14 -0
  14. package/dist/MdzRoot.svelte.d.ts.map +1 -0
  15. package/dist/MdzStream.svelte +37 -0
  16. package/dist/MdzStream.svelte.d.ts +18 -0
  17. package/dist/MdzStream.svelte.d.ts.map +1 -0
  18. package/dist/MdzStreamNodeView.svelte +150 -0
  19. package/dist/MdzStreamNodeView.svelte.d.ts +9 -0
  20. package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -0
  21. package/dist/context_helpers.d.ts +23 -0
  22. package/dist/context_helpers.d.ts.map +1 -0
  23. package/dist/context_helpers.js +19 -0
  24. package/dist/mdz.d.ts +152 -0
  25. package/dist/mdz.d.ts.map +1 -0
  26. package/dist/mdz.js +61 -0
  27. package/dist/mdz_contexts.d.ts +106 -0
  28. package/dist/mdz_contexts.d.ts.map +1 -0
  29. package/dist/mdz_contexts.js +42 -0
  30. package/dist/mdz_helpers.d.ts +321 -0
  31. package/dist/mdz_helpers.d.ts.map +1 -0
  32. package/dist/mdz_helpers.js +668 -0
  33. package/dist/mdz_lexer.d.ts +123 -0
  34. package/dist/mdz_lexer.d.ts.map +1 -0
  35. package/dist/mdz_lexer.js +1405 -0
  36. package/dist/mdz_opcodes.d.ts +193 -0
  37. package/dist/mdz_opcodes.d.ts.map +1 -0
  38. package/dist/mdz_opcodes.js +14 -0
  39. package/dist/mdz_opcodes_to_nodes.d.ts +26 -0
  40. package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -0
  41. package/dist/mdz_opcodes_to_nodes.js +410 -0
  42. package/dist/mdz_stream_parser.d.ts +109 -0
  43. package/dist/mdz_stream_parser.d.ts.map +1 -0
  44. package/dist/mdz_stream_parser.js +699 -0
  45. package/dist/mdz_stream_parser_block.d.ts +99 -0
  46. package/dist/mdz_stream_parser_block.d.ts.map +1 -0
  47. package/dist/mdz_stream_parser_block.js +437 -0
  48. package/dist/mdz_stream_parser_inline.d.ts +98 -0
  49. package/dist/mdz_stream_parser_inline.d.ts.map +1 -0
  50. package/dist/mdz_stream_parser_inline.js +481 -0
  51. package/dist/mdz_stream_parser_link.d.ts +29 -0
  52. package/dist/mdz_stream_parser_link.d.ts.map +1 -0
  53. package/dist/mdz_stream_parser_link.js +227 -0
  54. package/dist/mdz_stream_parser_list.d.ts +106 -0
  55. package/dist/mdz_stream_parser_list.d.ts.map +1 -0
  56. package/dist/mdz_stream_parser_list.js +438 -0
  57. package/dist/mdz_stream_parser_state.d.ts +476 -0
  58. package/dist/mdz_stream_parser_state.d.ts.map +1 -0
  59. package/dist/mdz_stream_parser_state.js +651 -0
  60. package/dist/mdz_stream_parser_text.d.ts +25 -0
  61. package/dist/mdz_stream_parser_text.d.ts.map +1 -0
  62. package/dist/mdz_stream_parser_text.js +67 -0
  63. package/dist/mdz_stream_parser_url.d.ts +76 -0
  64. package/dist/mdz_stream_parser_url.d.ts.map +1 -0
  65. package/dist/mdz_stream_parser_url.js +328 -0
  66. package/dist/mdz_stream_state.svelte.d.ts +53 -0
  67. package/dist/mdz_stream_state.svelte.d.ts.map +1 -0
  68. package/dist/mdz_stream_state.svelte.js +360 -0
  69. package/dist/mdz_to_svelte.d.ts +71 -0
  70. package/dist/mdz_to_svelte.d.ts.map +1 -0
  71. package/dist/mdz_to_svelte.js +127 -0
  72. package/dist/mdz_token_parser.d.ts +20 -0
  73. package/dist/mdz_token_parser.d.ts.map +1 -0
  74. package/dist/mdz_token_parser.js +449 -0
  75. package/dist/svelte_preprocess_mdz.d.ts +80 -0
  76. package/dist/svelte_preprocess_mdz.d.ts.map +1 -0
  77. package/dist/svelte_preprocess_mdz.js +543 -0
  78. package/dist/tsdoc_mdz.d.ts +45 -0
  79. package/dist/tsdoc_mdz.d.ts.map +1 -0
  80. package/dist/tsdoc_mdz.js +88 -0
  81. package/package.json +131 -0
  82. package/src/lib/context_helpers.ts +52 -0
  83. package/src/lib/mdz.ts +190 -0
  84. package/src/lib/mdz_contexts.ts +99 -0
  85. package/src/lib/mdz_helpers.ts +727 -0
  86. package/src/lib/mdz_lexer.ts +1761 -0
  87. package/src/lib/mdz_opcodes.ts +227 -0
  88. package/src/lib/mdz_opcodes_to_nodes.ts +470 -0
  89. package/src/lib/mdz_stream_parser.ts +766 -0
  90. package/src/lib/mdz_stream_parser_block.ts +490 -0
  91. package/src/lib/mdz_stream_parser_inline.ts +527 -0
  92. package/src/lib/mdz_stream_parser_link.ts +283 -0
  93. package/src/lib/mdz_stream_parser_list.ts +525 -0
  94. package/src/lib/mdz_stream_parser_state.ts +957 -0
  95. package/src/lib/mdz_stream_parser_text.ts +95 -0
  96. package/src/lib/mdz_stream_parser_url.ts +386 -0
  97. package/src/lib/mdz_stream_state.svelte.ts +383 -0
  98. package/src/lib/mdz_to_svelte.ts +213 -0
  99. package/src/lib/mdz_token_parser.ts +544 -0
  100. package/src/lib/svelte_preprocess_mdz.ts +777 -0
  101. package/src/lib/tsdoc_mdz.ts +97 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) fuz.dev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # mdz
2
+
3
+ [**mdz.fuz.dev**](https://mdz.fuz.dev/)
4
+
5
+ mdz is a strict markdown dialect built for streaming, Svelte authoring,
6
+ docs websites, and untrusted content. The same grammar serves multiple use cases:
7
+
8
+ - streaming output from LLMs and other live sources
9
+ - authoring with Svelte components, with an optional build-time preprocessor
10
+ that compiles static usage to plain Svelte markup
11
+ - rendering TSDoc/JSDoc comments on docs websites with domain-specific behavior
12
+ like backticked identifiers linkifying to API docs
13
+ - dynamic content from untrusted users, with granular control over enabled behaviors
14
+
15
+ mdz's predictable grammar means streaming never re-parses:
16
+ LLM output renders incrementally, and the infrequent corrections --
17
+ like an unclosed `**` or a link resolving late -- are bounded, explicit opcodes.
18
+ The streaming design is derived from [@pngwn](https://github.com/pngwn)'s
19
+ ideas in this [Bluesky thread](https://bsky.app/profile/pngwn.at/post/3mi527zntb22n)
20
+ ([pngwn.at](https://pngwn.at/)), and other parts of the mdz design are
21
+ inspired by pngwn's [MDsveX](https://mdsvex.pngwn.io/).
22
+
23
+ mdz takes after [CommonMark](https://commonmark.org/) and [GFM](https://github.github.com/gfm/),
24
+ diverging where their rules fight streaming or carry avoidable complexity and ambiguity.
25
+ For more see the [docs](https://mdz.fuz.dev/docs).
26
+
27
+ AI disclosure: almost everything here was generated by machine agents except
28
+ for the designs and intros. mdz is the result of 5+ years of prototyping ideas.
29
+
30
+ ## License
31
+
32
+ [MIT](LICENSE)
@@ -0,0 +1,39 @@
1
+ <script lang="ts">
2
+ import type {SvelteHTMLElements} from 'svelte/elements';
3
+
4
+ import {mdz_parse} from './mdz.js';
5
+ import MdzNodeView from './MdzNodeView.svelte';
6
+ import {
7
+ mdz_base_context,
8
+ mdz_set_context_with_fallback,
9
+ type MdzWhitespace,
10
+ } from './mdz_contexts.js';
11
+
12
+ const {
13
+ content,
14
+ inline = false,
15
+ whitespace,
16
+ base,
17
+ ...rest
18
+ }: (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
19
+ content: string;
20
+ inline?: boolean;
21
+ /**
22
+ * Sets `white-space` on the wrapper. When omitted, whitespace collapses
23
+ * like standard markdown — single newlines render as soft breaks.
24
+ * Use `pre-line` to render every newline as a line break.
25
+ */
26
+ whitespace?: MdzWhitespace;
27
+ base?: string;
28
+ } = $props();
29
+
30
+ mdz_set_context_with_fallback(mdz_base_context, () => base);
31
+
32
+ const nodes = $derived(mdz_parse(content));
33
+ </script>
34
+
35
+ <svelte:element this={inline ? 'span' : 'div'} {...rest} style:white-space={whitespace}>
36
+ {#each nodes as node (node)}
37
+ <MdzNodeView {node} />
38
+ {/each}
39
+ </svelte:element>
@@ -0,0 +1,17 @@
1
+ import type { SvelteHTMLElements } from 'svelte/elements';
2
+ import { type MdzWhitespace } from './mdz_contexts.js';
3
+ type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
4
+ content: string;
5
+ inline?: boolean;
6
+ /**
7
+ * Sets `white-space` on the wrapper. When omitted, whitespace collapses
8
+ * like standard markdown — single newlines render as soft breaks.
9
+ * Use `pre-line` to render every newline as a line break.
10
+ */
11
+ whitespace?: MdzWhitespace;
12
+ base?: string;
13
+ };
14
+ declare const Mdz: import("svelte").Component<$$ComponentProps, {}, "">;
15
+ type Mdz = ReturnType<typeof Mdz>;
16
+ export default Mdz;
17
+ //# sourceMappingURL=Mdz.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mdz.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/Mdz.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAIxD,OAAO,EAGL,KAAK,aAAa,EAClB,MAAM,mBAAmB,CAAC;AAE3B,KAAK,gBAAgB,GAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AA6BH,QAAA,MAAM,GAAG,sDAAwC,CAAC;AAClD,KAAK,GAAG,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;AAClC,eAAe,GAAG,CAAC"}
@@ -0,0 +1,140 @@
1
+ <script lang="ts">
2
+ import {resolve} from '$app/paths';
3
+
4
+ import type {MdzNode} from './mdz.js';
5
+ import {
6
+ mdz_resolve_relative_path,
7
+ mdz_is_safe_reference,
8
+ mdz_is_void_element,
9
+ } from './mdz_helpers.js';
10
+ import MdzNodeView from './MdzNodeView.svelte';
11
+ import {
12
+ mdz_components_context,
13
+ mdz_elements_context,
14
+ mdz_base_context,
15
+ mdz_code_context,
16
+ mdz_codeblock_context,
17
+ } from './mdz_contexts.js';
18
+
19
+ const {
20
+ node,
21
+ }: {
22
+ node: MdzNode;
23
+ } = $props();
24
+
25
+ const get_components = mdz_components_context.get_maybe();
26
+ const get_elements = mdz_elements_context.get_maybe();
27
+ const get_mdz_base = mdz_base_context.get_maybe();
28
+ const get_code = mdz_code_context.get_maybe();
29
+ const get_codeblock = mdz_codeblock_context.get_maybe();
30
+ </script>
31
+
32
+ {#if node.type === 'Element'}
33
+ {@const element_config = get_elements?.()?.get(node.name)}
34
+ {#if element_config !== undefined}
35
+ {#if mdz_is_void_element(node.name)}
36
+ <!-- void elements cannot have content — any parsed children are dropped -->
37
+ <svelte:element this={node.name} />
38
+ {:else}
39
+ <svelte:element this={node.name}>
40
+ {#if node.children.length > 0}
41
+ {@render render_children(node.children)}
42
+ {/if}
43
+ </svelte:element>
44
+ {/if}
45
+ {:else}
46
+ {@render render_unregistered_tag(node.name, node.children)}
47
+ {/if}
48
+ {:else if node.type === 'Component'}
49
+ {@const Component = get_components?.()?.get(node.name)}
50
+ {#if Component}
51
+ <Component>
52
+ {#if node.children.length > 0}
53
+ {@render render_children(node.children)}
54
+ {/if}
55
+ </Component>
56
+ {:else}
57
+ {@render render_unregistered_tag(node.name, node.children)}
58
+ {/if}
59
+ {:else if node.type === 'Text'}
60
+ {node.content}
61
+ {:else if node.type === 'Code'}
62
+ {@const Code = get_code?.()}
63
+ {#if Code}
64
+ <Code reference={node.content} />
65
+ {:else}
66
+ <code>{node.content}</code>
67
+ {/if}
68
+ {:else if node.type === 'Bold'}
69
+ <strong>{@render render_children(node.children)}</strong>
70
+ {:else if node.type === 'Italic'}
71
+ <em>{@render render_children(node.children)}</em>
72
+ {:else if node.type === 'Strikethrough'}
73
+ <s>{@render render_children(node.children)}</s>
74
+ {:else if node.type === 'Link'}
75
+ {@const {reference} = node}
76
+ {#if !mdz_is_safe_reference(reference)}
77
+ {@render render_children(node.children)}
78
+ {:else if node.link_type === 'internal'}
79
+ {@const skip_resolve = reference.startsWith('#') || reference.startsWith('?')}
80
+ {@const mdz_base = get_mdz_base?.()}
81
+ {#if reference.startsWith('.') && mdz_base}
82
+ {@const resolved = mdz_resolve_relative_path(reference, mdz_base)}
83
+ <a href={resolve(resolved as any)}>{@render render_children(node.children)}</a>
84
+ {:else if skip_resolve || reference.startsWith('.') || !reference.startsWith('/')}
85
+ <!-- Fragment, query, and relative links (including bare references like `foo`) skip resolve() -->
86
+ <!-- resolve() only accepts absolute pathnames or route IDs and throws on anything else -->
87
+ <!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
88
+ <a href={reference}>{@render render_children(node.children)}</a>
89
+ {:else}
90
+ <a href={resolve(reference as any)}>{@render render_children(node.children)}</a>
91
+ {/if}
92
+ {:else}
93
+ <!-- external link -->
94
+ <!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
95
+ <a href={reference} target="_blank" rel="noopener">{@render render_children(node.children)}</a>
96
+ {/if}
97
+ {:else if node.type === 'Paragraph'}
98
+ <p>{@render render_children(node.children)}</p>
99
+ {:else if node.type === 'List'}
100
+ {#if node.ordered}
101
+ <ol start={node.start_number === 1 ? undefined : node.start_number}>
102
+ {@render render_children(node.children)}
103
+ </ol>
104
+ {:else}
105
+ <ul>{@render render_children(node.children)}</ul>
106
+ {/if}
107
+ {:else if node.type === 'ListItem'}
108
+ <li>{@render render_children(node.children)}</li>
109
+ {:else if node.type === 'Blockquote'}
110
+ <blockquote>{@render render_children(node.children)}</blockquote>
111
+ {:else if node.type === 'Hr'}
112
+ <hr />
113
+ {:else if node.type === 'Heading'}
114
+ <svelte:element this={`h${node.level}`} id={node.id || undefined}>
115
+ {@render render_children(node.children)}
116
+ </svelte:element>
117
+ {:else if node.type === 'Codeblock'}
118
+ {@const Codeblock = get_codeblock?.()}
119
+ {#if Codeblock}
120
+ <Codeblock lang={node.lang} content={node.content} />
121
+ {:else}
122
+ <pre><code>{node.content}</code></pre>
123
+ {/if}
124
+ {/if}
125
+
126
+ {#snippet render_children(nodes: Array<MdzNode>)}
127
+ {#each nodes as node (node)}
128
+ <MdzNodeView {node} />
129
+ {/each}
130
+ {/snippet}
131
+
132
+ {#snippet render_unregistered_tag(name: string, children: Array<MdzNode>)}
133
+ {#if children.length > 0}
134
+ <code class="color_c_50">&lt;{name}&gt;</code>{@render render_children(children)}<code
135
+ class="color_c_50">&lt;/{name}&gt;</code
136
+ >
137
+ {:else}
138
+ <code class="color_c_50">&lt;{name} /&gt;</code>
139
+ {/if}
140
+ {/snippet}
@@ -0,0 +1,9 @@
1
+ import type { MdzNode } from './mdz.js';
2
+ import MdzNodeView from './MdzNodeView.svelte';
3
+ type $$ComponentProps = {
4
+ node: MdzNode;
5
+ };
6
+ declare const MdzNodeView: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type MdzNodeView = ReturnType<typeof MdzNodeView>;
8
+ export default MdzNodeView;
9
+ //# sourceMappingURL=MdzNodeView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdzNodeView.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzNodeView.svelte"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,UAAU,CAAC;AAMtC,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAS9C,KAAK,gBAAgB,GAAI;IACxB,IAAI,EAAE,OAAO,CAAC;CACd,CAAC;AAkIH,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import type {Snippet} from 'svelte';
3
+ import type {SvelteHTMLElements} from 'svelte/elements';
4
+
5
+ import type {MdzWhitespace} from './mdz_contexts.js';
6
+
7
+ /**
8
+ * Wrapper for precompiled mdz content. Used by `svelte_preprocess_mdz`.
9
+ * Not intended for direct use.
10
+ *
11
+ * @module
12
+ */
13
+
14
+ const {
15
+ inline = false,
16
+ whitespace,
17
+ children,
18
+ ...rest
19
+ }: (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
20
+ inline?: boolean;
21
+ /**
22
+ * Sets `white-space` on the wrapper. When omitted, whitespace collapses
23
+ * like standard markdown — single newlines render as soft breaks.
24
+ * Use `pre-line` to render every newline as a line break.
25
+ */
26
+ whitespace?: MdzWhitespace;
27
+ children: Snippet;
28
+ } = $props();
29
+ </script>
30
+
31
+ <svelte:element this={inline ? 'span' : 'div'} {...rest} style:white-space={whitespace}>
32
+ {@render children()}
33
+ </svelte:element>
@@ -0,0 +1,17 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ import type { MdzWhitespace } from './mdz_contexts.js';
4
+ type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
5
+ inline?: boolean;
6
+ /**
7
+ * Sets `white-space` on the wrapper. When omitted, whitespace collapses
8
+ * like standard markdown — single newlines render as soft breaks.
9
+ * Use `pre-line` to render every newline as a line break.
10
+ */
11
+ whitespace?: MdzWhitespace;
12
+ children: Snippet;
13
+ };
14
+ declare const MdzPrecompiled: import("svelte").Component<$$ComponentProps, {}, "">;
15
+ type MdzPrecompiled = ReturnType<typeof MdzPrecompiled>;
16
+ export default MdzPrecompiled;
17
+ //# sourceMappingURL=MdzPrecompiled.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdzPrecompiled.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzPrecompiled.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAExD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAEpD,KAAK,gBAAgB,GAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;CAClB,CAAC;AA4BH,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import type {Snippet} from 'svelte';
3
+
4
+ import {
5
+ mdz_base_context,
6
+ mdz_code_context,
7
+ mdz_codeblock_context,
8
+ mdz_components_context,
9
+ mdz_elements_context,
10
+ mdz_set_context_with_fallback,
11
+ type MdzCodeComponent,
12
+ type MdzCodeblockComponent,
13
+ type MdzComponents,
14
+ type MdzElements,
15
+ } from './mdz_contexts.js';
16
+
17
+ const {
18
+ base,
19
+ components,
20
+ elements,
21
+ code,
22
+ codeblock,
23
+ children,
24
+ }: {
25
+ base?: string;
26
+ components?: MdzComponents;
27
+ elements?: MdzElements;
28
+ code?: MdzCodeComponent;
29
+ codeblock?: MdzCodeblockComponent;
30
+ children: Snippet;
31
+ } = $props();
32
+
33
+ mdz_set_context_with_fallback(mdz_base_context, () => base);
34
+ mdz_set_context_with_fallback(mdz_components_context, () => components);
35
+ mdz_set_context_with_fallback(mdz_elements_context, () => elements);
36
+ mdz_set_context_with_fallback(mdz_code_context, () => code);
37
+ mdz_set_context_with_fallback(mdz_codeblock_context, () => codeblock);
38
+ </script>
39
+
40
+ {@render children()}
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ import { type MdzCodeComponent, type MdzCodeblockComponent, type MdzComponents, type MdzElements } from './mdz_contexts.js';
3
+ type $$ComponentProps = {
4
+ base?: string;
5
+ components?: MdzComponents;
6
+ elements?: MdzElements;
7
+ code?: MdzCodeComponent;
8
+ codeblock?: MdzCodeblockComponent;
9
+ children: Snippet;
10
+ };
11
+ declare const MdzRoot: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type MdzRoot = ReturnType<typeof MdzRoot>;
13
+ export default MdzRoot;
14
+ //# sourceMappingURL=MdzRoot.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdzRoot.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzRoot.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAOL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,mBAAmB,CAAC;AAE3B,KAAK,gBAAgB,GAAI;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;CAClB,CAAC;AA0BH,QAAA,MAAM,OAAO,sDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,37 @@
1
+ <script lang="ts">
2
+ import type {SvelteHTMLElements} from 'svelte/elements';
3
+
4
+ import MdzStreamNodeView from './MdzStreamNodeView.svelte';
5
+ import {
6
+ mdz_base_context,
7
+ mdz_set_context_with_fallback,
8
+ type MdzWhitespace,
9
+ } from './mdz_contexts.js';
10
+ import type {MdzStreamState} from './mdz_stream_state.svelte.js';
11
+
12
+ const {
13
+ stream,
14
+ inline = false,
15
+ whitespace,
16
+ base,
17
+ ...rest
18
+ }: (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
19
+ stream: MdzStreamState;
20
+ inline?: boolean;
21
+ /**
22
+ * Sets `white-space` on the wrapper. When omitted, whitespace collapses
23
+ * like standard markdown — single newlines render as soft breaks.
24
+ * Use `pre-line` to render every newline as a line break.
25
+ */
26
+ whitespace?: MdzWhitespace;
27
+ base?: string;
28
+ } = $props();
29
+
30
+ mdz_set_context_with_fallback(mdz_base_context, () => base);
31
+ </script>
32
+
33
+ <svelte:element this={inline ? 'span' : 'div'} {...rest} style:white-space={whitespace}>
34
+ {#each stream.root as node (node.id)}
35
+ <MdzStreamNodeView {node} />
36
+ {/each}
37
+ </svelte:element>
@@ -0,0 +1,18 @@
1
+ import type { SvelteHTMLElements } from 'svelte/elements';
2
+ import { type MdzWhitespace } from './mdz_contexts.js';
3
+ import type { MdzStreamState } from './mdz_stream_state.svelte.js';
4
+ type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
5
+ stream: MdzStreamState;
6
+ inline?: boolean;
7
+ /**
8
+ * Sets `white-space` on the wrapper. When omitted, whitespace collapses
9
+ * like standard markdown — single newlines render as soft breaks.
10
+ * Use `pre-line` to render every newline as a line break.
11
+ */
12
+ whitespace?: MdzWhitespace;
13
+ base?: string;
14
+ };
15
+ declare const MdzStream: import("svelte").Component<$$ComponentProps, {}, "">;
16
+ type MdzStream = ReturnType<typeof MdzStream>;
17
+ export default MdzStream;
18
+ //# sourceMappingURL=MdzStream.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdzStream.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzStream.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAGL,KAAK,aAAa,EAClB,MAAM,mBAAmB,CAAC;AAC5B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAEhE,KAAK,gBAAgB,GAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG;IACnF,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AA2BH,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -0,0 +1,150 @@
1
+ <script lang="ts">
2
+ import {resolve} from '$app/paths';
3
+
4
+ import {
5
+ mdz_resolve_relative_path,
6
+ mdz_is_safe_reference,
7
+ mdz_is_void_element,
8
+ } from './mdz_helpers.js';
9
+ import MdzStreamNodeView from './MdzStreamNodeView.svelte';
10
+ import {
11
+ mdz_components_context,
12
+ mdz_elements_context,
13
+ mdz_base_context,
14
+ mdz_code_context,
15
+ mdz_codeblock_context,
16
+ } from './mdz_contexts.js';
17
+ import type {MdzStreamNode} from './mdz_stream_state.svelte.js';
18
+
19
+ const {
20
+ node,
21
+ }: {
22
+ node: MdzStreamNode;
23
+ } = $props();
24
+
25
+ const get_components = mdz_components_context.get_maybe();
26
+ const get_elements = mdz_elements_context.get_maybe();
27
+ const get_mdz_base = mdz_base_context.get_maybe();
28
+ const get_code = mdz_code_context.get_maybe();
29
+ const get_codeblock = mdz_codeblock_context.get_maybe();
30
+
31
+ // While a Code/Codeblock container is open, streamed text accumulates in
32
+ // `children`; `MdzStreamState` collapses it into `content` at close. Joining
33
+ // the children makes the content visible as it streams instead of popping in
34
+ // all at once when the fence closes (`content` is preferred after close —
35
+ // it's identical, the children are just retained in the render tree).
36
+ const streaming_content = (n: MdzStreamNode): string =>
37
+ n.content || n.children.map((c) => c.content).join('');
38
+ </script>
39
+
40
+ {#if node.type === 'Element'}
41
+ {@const element_config = get_elements?.()?.get(node.name ?? '')}
42
+ {#if element_config !== undefined}
43
+ {#if mdz_is_void_element(node.name ?? '')}
44
+ <!-- void elements cannot have content — any parsed children are dropped -->
45
+ <svelte:element this={node.name} />
46
+ {:else}
47
+ <svelte:element this={node.name}>
48
+ {#if node.children.length > 0}
49
+ {@render render_children(node.children)}
50
+ {/if}
51
+ </svelte:element>
52
+ {/if}
53
+ {:else}
54
+ {@render render_unregistered_tag(node.name ?? '', node.children)}
55
+ {/if}
56
+ {:else if node.type === 'Component'}
57
+ {@const Component = get_components?.()?.get(node.name ?? '')}
58
+ {#if Component}
59
+ <Component>
60
+ {#if node.children.length > 0}
61
+ {@render render_children(node.children)}
62
+ {/if}
63
+ </Component>
64
+ {:else}
65
+ {@render render_unregistered_tag(node.name ?? '', node.children)}
66
+ {/if}
67
+ {:else if node.type === 'Text'}
68
+ {node.content}
69
+ {:else if node.type === 'Code'}
70
+ {@const Code = get_code?.()}
71
+ {@const code_content = streaming_content(node)}
72
+ {#if Code}
73
+ <Code reference={code_content} />
74
+ {:else}
75
+ <code>{code_content}</code>
76
+ {/if}
77
+ {:else if node.type === 'Bold'}
78
+ <strong>{@render render_children(node.children)}</strong>
79
+ {:else if node.type === 'Italic'}
80
+ <em>{@render render_children(node.children)}</em>
81
+ {:else if node.type === 'Strikethrough'}
82
+ <s>{@render render_children(node.children)}</s>
83
+ {:else if node.type === 'Link'}
84
+ {@const reference = node.reference ?? ''}
85
+ {#if !mdz_is_safe_reference(reference)}
86
+ {@render render_children(node.children)}
87
+ {:else if node.link_type === 'internal'}
88
+ {@const skip_resolve = reference.startsWith('#') || reference.startsWith('?')}
89
+ {@const mdz_base = get_mdz_base?.()}
90
+ {#if reference.startsWith('.') && mdz_base}
91
+ {@const resolved = mdz_resolve_relative_path(reference, mdz_base)}
92
+ <a href={resolve(resolved as any)}>{@render render_children(node.children)}</a>
93
+ {:else if skip_resolve || reference.startsWith('.') || !reference.startsWith('/')}
94
+ <!-- Fragment, query, and relative links (including bare references like `foo`) skip resolve() -->
95
+ <!-- resolve() only accepts absolute pathnames or route IDs and throws on anything else -->
96
+ <!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
97
+ <a href={reference}>{@render render_children(node.children)}</a>
98
+ {:else}
99
+ <a href={resolve(reference as any)}>{@render render_children(node.children)}</a>
100
+ {/if}
101
+ {:else}
102
+ <!-- external link -->
103
+ <!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
104
+ <a href={reference} target="_blank" rel="noopener">{@render render_children(node.children)}</a>
105
+ {/if}
106
+ {:else if node.type === 'Paragraph'}
107
+ <p>{@render render_children(node.children)}</p>
108
+ {:else if node.type === 'List'}
109
+ {#if node.ordered}
110
+ <ol start={node.start_number === 1 ? undefined : node.start_number}>
111
+ {@render render_children(node.children)}
112
+ </ol>
113
+ {:else}
114
+ <ul>{@render render_children(node.children)}</ul>
115
+ {/if}
116
+ {:else if node.type === 'ListItem'}
117
+ <li>{@render render_children(node.children)}</li>
118
+ {:else if node.type === 'Blockquote'}
119
+ <blockquote>{@render render_children(node.children)}</blockquote>
120
+ {:else if node.type === 'Hr'}
121
+ <hr />
122
+ {:else if node.type === 'Heading'}
123
+ <svelte:element this={`h${node.level}`} id={node.heading_id || undefined}>
124
+ {@render render_children(node.children)}
125
+ </svelte:element>
126
+ {:else if node.type === 'Codeblock'}
127
+ {@const Codeblock = get_codeblock?.()}
128
+ {@const codeblock_content = streaming_content(node)}
129
+ {#if Codeblock}
130
+ <Codeblock lang={node.lang ?? null} content={codeblock_content} />
131
+ {:else}
132
+ <pre><code>{codeblock_content}</code></pre>
133
+ {/if}
134
+ {/if}
135
+
136
+ {#snippet render_children(nodes: Array<MdzStreamNode>)}
137
+ {#each nodes as node (node.id)}
138
+ <MdzStreamNodeView {node} />
139
+ {/each}
140
+ {/snippet}
141
+
142
+ {#snippet render_unregistered_tag(name: string, children: Array<MdzStreamNode>)}
143
+ {#if children.length > 0}
144
+ <code class="color_c_50">&lt;{name}&gt;</code>{@render render_children(children)}<code
145
+ class="color_c_50">&lt;/{name}&gt;</code
146
+ >
147
+ {:else}
148
+ <code class="color_c_50">&lt;{name} /&gt;</code>
149
+ {/if}
150
+ {/snippet}
@@ -0,0 +1,9 @@
1
+ import MdzStreamNodeView from './MdzStreamNodeView.svelte';
2
+ import type { MdzStreamNode } from './mdz_stream_state.svelte.js';
3
+ type $$ComponentProps = {
4
+ node: MdzStreamNode;
5
+ };
6
+ declare const MdzStreamNodeView: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type MdzStreamNodeView = ReturnType<typeof MdzStreamNodeView>;
8
+ export default MdzStreamNodeView;
9
+ //# sourceMappingURL=MdzStreamNodeView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdzStreamNodeView.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzStreamNodeView.svelte"],"names":[],"mappings":"AAUA,OAAO,iBAAiB,MAAM,4BAA4B,CAAC;AAQ3D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAE/D,KAAK,gBAAgB,GAAI;IACxB,IAAI,EAAE,aAAa,CAAC;CACpB,CAAC;AA4IH,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Wraps Svelte's `setContext` and `getContext` for better ergonomics.
3
+ * When no value is set in the context,
4
+ * `get` throws an error and `get_maybe` returns `undefined`.
5
+ * If a `fallback` is provided, the `value` argument to `set` is optional
6
+ * and `get_maybe` is omitted from the type.
7
+ *
8
+ * Vendored from `@fuzdev/fuz_ui/context_helpers.js` — fuz_ui sits above mdz
9
+ * in the dependency graph, so mdz keeps its own copy for `mdz_contexts.ts`.
10
+ * Consumers should import fuz_ui's.
11
+ *
12
+ * @nodocs
13
+ */
14
+ export declare function create_context<T>(fallback: () => T): {
15
+ get: () => T;
16
+ set: (value?: T) => T;
17
+ };
18
+ export declare function create_context<T>(): {
19
+ get: (error_message?: string) => T;
20
+ get_maybe: () => T | undefined;
21
+ set: (value: T) => T;
22
+ };
23
+ //# sourceMappingURL=context_helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/context_helpers.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG;IACrD,GAAG,EAAE,MAAM,CAAC,CAAC;IACb,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;CACtB,CAAC;AACF,wBAAgB,cAAc,CAAC,CAAC,KAAK;IACpC,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC/B,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;CACrB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ export function create_context(fallback) {
3
+ const key = Symbol();
4
+ const get_maybe = () => {
5
+ const value = getContext(key); // treat `null` as a valid value - the `typescript-eslint` rule below is bugged because `??` would clobber nulls, see issue https://github.com/typescript-eslint/typescript-eslint/issues/7842
6
+ return value === undefined ? fallback?.() : value;
7
+ };
8
+ return {
9
+ get: (error_message) => {
10
+ const value = get_maybe();
11
+ if (value === undefined)
12
+ throw Error(error_message ?? 'context value is not set');
13
+ return value;
14
+ },
15
+ get_maybe,
16
+ // this is typesafe, so no runtime check:
17
+ set: (value = fallback?.()) => setContext(key, value),
18
+ };
19
+ }