@fuzdev/mdz 0.7.0 → 0.8.1

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 CHANGED
@@ -1,9 +1,11 @@
1
1
  # mdz
2
2
 
3
+ [<img src="static/logo.svg" alt="a purple pen nib hovering over an inkwell with a glint of light" align="right" width="192" height="192">](https://mdz.fuz.dev/)
4
+
3
5
  [**mdz.fuz.dev**](https://mdz.fuz.dev/)
4
6
 
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
+ mdz is a strict markdown dialect built for streaming, web authoring,
8
+ docs, and untrusted content. The same grammar serves multiple use cases:
7
9
 
8
10
  - streaming output from LLMs and other live sources
9
11
  - authoring with Svelte components, with an optional build-time preprocessor
package/dist/Mdz.svelte CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { mdz_parse, type MdzNode } from './mdz.js';
6
6
  import MdzNodeView from './MdzNodeView.svelte';
7
+ import { mdz_unwrap_inline } from './mdz_helpers.js';
7
8
  import {
8
9
  mdz_base_context,
9
10
  mdz_set_context_with_fallback,
@@ -18,6 +19,10 @@
18
19
  base,
19
20
  ...rest
20
21
  }: (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
22
+ /**
23
+ * Renders a `span` wrapper and unwraps a lone paragraph so the content
24
+ * can sit inside other text. Multiple blocks still render as blocks.
25
+ */
21
26
  inline?: boolean;
22
27
  /**
23
28
  * Sets `white-space` on the wrapper. When omitted, whitespace collapses
@@ -39,7 +44,8 @@
39
44
  if (DEV && (content === undefined) === (nodes_prop === undefined)) {
40
45
  throw new Error('Mdz: pass exactly one of `content` or `nodes`');
41
46
  }
42
- return nodes_prop ?? mdz_parse(content ?? '');
47
+ const parsed = nodes_prop ?? mdz_parse(content ?? '');
48
+ return inline ? mdz_unwrap_inline(parsed) : parsed;
43
49
  });
44
50
  </script>
45
51
 
@@ -2,6 +2,10 @@ import type { SvelteHTMLElements } from 'svelte/elements';
2
2
  import { type MdzNode } from './mdz.js';
3
3
  import { type MdzWhitespace } from './mdz_contexts.js';
4
4
  type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
5
+ /**
6
+ * Renders a `span` wrapper and unwraps a lone paragraph so the content
7
+ * can sit inside other text. Multiple blocks still render as blocks.
8
+ */
5
9
  inline?: boolean;
6
10
  /**
7
11
  * Sets `white-space` on the wrapper. When omitted, whitespace collapses
@@ -1 +1 @@
1
- {"version":3,"file":"Mdz.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/Mdz.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnD,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,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,uEAAuE;AAG1E,CACC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;CAAE,CACvF,CAAC;AAkCJ,QAAA,MAAM,GAAG,sDAAwC,CAAC;AAClD,KAAK,GAAG,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;AAClC,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"Mdz.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/Mdz.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAGnD,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;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,uEAAuE;AAG1E,CACC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;CAAE,CACvF,CAAC;AAoCJ,QAAA,MAAM,GAAG,sDAAwC,CAAC;AAClD,KAAK,GAAG,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;AAClC,eAAe,GAAG,CAAC"}
@@ -17,6 +17,10 @@
17
17
  children,
18
18
  ...rest
19
19
  }: (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
20
+ /**
21
+ * Renders a `span` wrapper. The preprocessor has already unwrapped a lone
22
+ * paragraph in `children`, matching `Mdz`.
23
+ */
20
24
  inline?: boolean;
21
25
  /**
22
26
  * Sets `white-space` on the wrapper. When omitted, whitespace collapses
@@ -24,10 +28,11 @@
24
28
  * Use `pre-line` to render every newline as a line break.
25
29
  */
26
30
  whitespace?: MdzWhitespace;
27
- children: Snippet;
31
+ /** Absent for empty content, which compiles to no children. */
32
+ children?: Snippet;
28
33
  } = $props();
29
34
  </script>
30
35
 
31
36
  <svelte:element this={inline ? 'span' : 'div'} {...rest} style:white-space={whitespace}>
32
- {@render children()}
37
+ {@render children?.()}
33
38
  </svelte:element>
@@ -2,6 +2,10 @@ import type { Snippet } from 'svelte';
2
2
  import type { SvelteHTMLElements } from 'svelte/elements';
3
3
  import type { MdzWhitespace } from './mdz_contexts.js';
4
4
  type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
5
+ /**
6
+ * Renders a `span` wrapper. The preprocessor has already unwrapped a lone
7
+ * paragraph in `children`, matching `Mdz`.
8
+ */
5
9
  inline?: boolean;
6
10
  /**
7
11
  * Sets `white-space` on the wrapper. When omitted, whitespace collapses
@@ -9,7 +13,8 @@ type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span'])
9
13
  * Use `pre-line` to render every newline as a line break.
10
14
  */
11
15
  whitespace?: MdzWhitespace;
12
- children: Snippet;
16
+ /** Absent for empty content, which compiles to no children. */
17
+ children?: Snippet;
13
18
  };
14
19
  declare const MdzPrecompiled: import("svelte").Component<$$ComponentProps, {}, "">;
15
20
  type MdzPrecompiled = ReturnType<typeof MdzPrecompiled>;
@@ -1 +1 @@
1
- {"version":3,"file":"MdzPrecompiled.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzPrecompiled.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEtD,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"}
1
+ {"version":3,"file":"MdzPrecompiled.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzPrecompiled.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEtD,KAAK,gBAAgB,GAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG;IACnF;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AA4BH,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -17,6 +17,10 @@
17
17
  ...rest
18
18
  }: (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
19
19
  stream: MdzStreamState;
20
+ /**
21
+ * Renders a `span` wrapper. Unlike `Mdz`, a lone paragraph keeps its `p`,
22
+ * because a stream can't know a paragraph is the only block until it ends.
23
+ */
20
24
  inline?: boolean;
21
25
  /**
22
26
  * Sets `white-space` on the wrapper. When omitted, whitespace collapses
@@ -3,6 +3,10 @@ import { type MdzWhitespace } from './mdz_contexts.js';
3
3
  import type { MdzStreamState } from './mdz_stream_state.svelte.js';
4
4
  type $$ComponentProps = (SvelteHTMLElements['div'] | SvelteHTMLElements['span']) & {
5
5
  stream: MdzStreamState;
6
+ /**
7
+ * Renders a `span` wrapper. Unlike `Mdz`, a lone paragraph keeps its `p`,
8
+ * because a stream can't know a paragraph is the only block until it ends.
9
+ */
6
10
  inline?: boolean;
7
11
  /**
8
12
  * Sets `white-space` on the wrapper. When omitted, whitespace collapses
@@ -1 +1 @@
1
- {"version":3,"file":"MdzStream.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzStream.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,OAAO,EAGL,KAAK,aAAa,EAClB,MAAM,mBAAmB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAElE,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;AA0BH,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"MdzStream.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/MdzStream.svelte"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,OAAO,EAGL,KAAK,aAAa,EAClB,MAAM,mBAAmB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAElE,KAAK,gBAAgB,GAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG;IACnF,MAAM,EAAE,cAAc,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AA0BH,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
package/dist/mdz.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * mdz — strict markdown dialect built for streaming, Svelte authoring, docs
3
- * sites, and untrusted content.
2
+ * mdz — strict markdown dialect built for streaming, web authoring, docs, and
3
+ * untrusted content.
4
4
  *
5
5
  * Created for two motivating use cases: rendering TSDoc/JSDoc comments on
6
6
  * docs websites (with domain-specific behavior like linkifying backticked
package/dist/mdz.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * mdz — strict markdown dialect built for streaming, Svelte authoring, docs
3
- * sites, and untrusted content.
2
+ * mdz — strict markdown dialect built for streaming, web authoring, docs, and
3
+ * untrusted content.
4
4
  *
5
5
  * Created for two motivating use cases: rendering TSDoc/JSDoc comments on
6
6
  * docs websites (with domain-specific behavior like linkifying backticked
@@ -346,6 +346,15 @@ export declare const mdz_heading_id: (nodes: Array<MdzNode>) => string;
346
346
  * rather than building `MdzNode[]` trees.
347
347
  */
348
348
  export declare const mdz_heading_id_from_text: (text: string) => string;
349
+ /**
350
+ * Prepares top-level nodes for inline rendering by unwrapping a lone paragraph
351
+ * into its children, so `inline` output has no block `<p>`.
352
+ * Multiple blocks or a non-paragraph block can't be inline and return unchanged.
353
+ *
354
+ * @param nodes - top-level nodes from `mdz_parse`
355
+ * @returns the lone paragraph's children, otherwise `nodes`
356
+ */
357
+ export declare const mdz_unwrap_inline: (nodes: Array<MdzNode>) => Array<MdzNode>;
349
358
  export declare const mdz_is_url: (s: string) => boolean;
350
359
  export declare const mdz_is_safe_reference: (reference: string) => boolean;
351
360
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mdz_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mdz_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_helpers.ts"],"names":[],"mappings":"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"}
@@ -679,6 +679,18 @@ export const mdz_heading_id = (nodes) => slugify(mdz_text_content(nodes));
679
679
  * rather than building `MdzNode[]` trees.
680
680
  */
681
681
  export const mdz_heading_id_from_text = (text) => slugify(text);
682
+ /**
683
+ * Prepares top-level nodes for inline rendering by unwrapping a lone paragraph
684
+ * into its children, so `inline` output has no block `<p>`.
685
+ * Multiple blocks or a non-paragraph block can't be inline and return unchanged.
686
+ *
687
+ * @param nodes - top-level nodes from `mdz_parse`
688
+ * @returns the lone paragraph's children, otherwise `nodes`
689
+ */
690
+ export const mdz_unwrap_inline = (nodes) => {
691
+ const first = nodes[0];
692
+ return nodes.length === 1 && first?.type === 'Paragraph' ? first.children : nodes;
693
+ };
682
694
  /**
683
695
  * Check if a string is a URL (`https://` or `http://`).
684
696
  * Requires at least one valid character after the protocol.
@@ -1 +1 @@
1
- {"version":3,"file":"mdz_to_svelte.d.ts","sourceRoot":"../src/lib/","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;AAMD;;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
+ {"version":3,"file":"mdz_to_svelte.d.ts","sourceRoot":"../src/lib/","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"}
@@ -18,6 +18,39 @@ const format_attributes = (entries) => {
18
18
  }
19
19
  return out;
20
20
  };
21
+ /** The whitespace the Svelte compiler trims and collapses in template text. */
22
+ const is_template_whitespace = (char) => char === ' ' || char === '\t' || char === '\r' || char === '\n';
23
+ /**
24
+ * Emits a whitespace run, as an expression when the Svelte compiler would
25
+ * otherwise change it. Only a single space beside a sibling survives as
26
+ * template text: fragment edges are trimmed, longer runs collapse.
27
+ */
28
+ const render_whitespace = (whitespace, has_sibling) => whitespace === '' || (whitespace === ' ' && has_sibling)
29
+ ? whitespace
30
+ : `{'${escape_js_string(whitespace)}'}`;
31
+ /**
32
+ * Emits text so it survives the Svelte compiler's whitespace handling, matching
33
+ * the runtime views' `{text}` expressions. Interior whitespace needs no
34
+ * protection, only the runs at the text's edges.
35
+ *
36
+ * @param content - the raw text
37
+ * @param has_prev - whether a sibling node precedes the text
38
+ * @param has_next - whether a sibling node follows the text
39
+ * @returns Svelte markup
40
+ */
41
+ const render_text = (content, has_prev, has_next) => {
42
+ let start = 0;
43
+ while (start < content.length && is_template_whitespace(content[start]))
44
+ start++;
45
+ if (start === content.length)
46
+ return render_whitespace(content, has_prev && has_next);
47
+ let end = content.length;
48
+ while (is_template_whitespace(content[end - 1]))
49
+ end--;
50
+ return (render_whitespace(content.slice(0, start), has_prev) +
51
+ escape_svelte_text(content.slice(start, end)) +
52
+ render_whitespace(content.slice(end), has_next));
53
+ };
21
54
  /** Derives an import's local identifier from a `.svelte` import path's basename. */
22
55
  const component_local_name = (import_path) => import_path.slice(import_path.lastIndexOf('/') + 1).replace(/\.svelte$/, '');
23
56
  /**
@@ -34,15 +67,15 @@ export const mdz_to_svelte = (nodes, options) => {
34
67
  const imports = new Map();
35
68
  let has_unconfigured_tags = false;
36
69
  const render_nodes = (children) => {
37
- return children.map((child) => render_node(child)).join('');
70
+ return children.map((child, i) => render_node(child, i > 0, i < children.length - 1)).join('');
38
71
  };
39
- const render_node = (node) => {
72
+ const render_node = (node, has_prev, has_next) => {
40
73
  switch (node.type) {
41
74
  case 'Text':
42
- return escape_svelte_text(node.content);
75
+ return render_text(node.content, has_prev, has_next);
43
76
  case 'Code': {
44
77
  if (!code_component_import) {
45
- return `<code>${escape_svelte_text(node.content)}</code>`;
78
+ return `<code>${render_text(node.content, false, false)}</code>`;
46
79
  }
47
80
  const name = component_local_name(code_component_import);
48
81
  imports.set(name, { path: code_component_import, kind: 'default' });
@@ -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,EAAS,KAAK,iBAAiB,EAAY,MAAM,iBAAiB,CAAC;AAsB1E,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"}
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;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"}
@@ -19,6 +19,7 @@ import { walk } from 'zimmerframe';
19
19
  import { should_exclude_path } from '@fuzdev/fuz_util/path.ts';
20
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
+ import { mdz_unwrap_inline } from './mdz_helpers.js';
22
23
  import { mdz_to_svelte } from './mdz_to_svelte.js';
23
24
  const PRECOMPILED_NAME = 'MdzPrecompiled';
24
25
  /**
@@ -138,16 +139,33 @@ const collect_consumed_bindings = (value, bindings) => {
138
139
  collect_from_expr(value.expression);
139
140
  return consumed;
140
141
  };
142
+ /**
143
+ * Reads a static boolean attribute value, from a bare attribute or a boolean
144
+ * literal expression.
145
+ *
146
+ * @returns the boolean, or `null` when the value isn't known at build time
147
+ */
148
+ const extract_static_boolean = (value) => {
149
+ if (value === true)
150
+ return true;
151
+ if (Array.isArray(value))
152
+ return null;
153
+ const { expression } = value;
154
+ return expression.type === 'Literal' && typeof expression.value === 'boolean'
155
+ ? expression.value
156
+ : null;
157
+ };
141
158
  /**
142
159
  * Parse a static mdz string and render it to Svelte markup. Returns `null` to
143
160
  * leave the usage for the runtime — either the content raised a parse error
144
161
  * (reported via `on_error`) or it contains unconfigured tags (which the
145
162
  * precompiler emits nothing for; the runtime renders the fallback chrome).
146
163
  */
147
- const render_static_mdz = (content, base, context) => {
164
+ const render_static_mdz = (content, base, inline, context) => {
148
165
  let result;
149
166
  try {
150
- result = mdz_to_svelte(mdz_parse(content), {
167
+ const nodes = mdz_parse(content);
168
+ result = mdz_to_svelte(inline ? mdz_unwrap_inline(nodes) : nodes, {
151
169
  components: context.components,
152
170
  elements: context.elements,
153
171
  base,
@@ -197,6 +215,13 @@ const find_mdz_usages = (ast, mdz_names, context) => {
197
215
  return; // dynamic base — fall back to runtime
198
216
  base = base_value;
199
217
  }
218
+ // `inline` decides the markup, not just the wrapper — a lone paragraph is
219
+ // unwrapped — so a dynamic value can't be precompiled. The attribute stays
220
+ // in the output for `MdzPrecompiled`'s wrapper.
221
+ const inline_attr = find_attribute(node, 'inline');
222
+ const inline = inline_attr ? extract_static_boolean(inline_attr.value) : false;
223
+ if (inline === null)
224
+ return; // dynamic inline — fall back to runtime
200
225
  // Collect attributes to exclude from precompiled output
201
226
  const exclude_attrs = new Set([content_attr]);
202
227
  if (base_attr)
@@ -204,7 +229,7 @@ const find_mdz_usages = (ast, mdz_names, context) => {
204
229
  // Extract static string value
205
230
  const content_value = extract_static_string(content_attr.value, context.bindings);
206
231
  if (content_value !== null) {
207
- const result = render_static_mdz(content_value, base, context);
232
+ const result = render_static_mdz(content_value, base, inline, context);
208
233
  if (result === null)
209
234
  return; // parse error or unconfigured tags — leave for runtime
210
235
  const consumed = collect_consumed_bindings(content_attr.value, context.bindings);
@@ -227,7 +252,7 @@ const find_mdz_usages = (ast, mdz_names, context) => {
227
252
  // Parse and render each branch
228
253
  const branch_results = [];
229
254
  for (const branch of chain) {
230
- const result = render_static_mdz(branch.value, base, context);
255
+ const result = render_static_mdz(branch.value, base, inline, context);
231
256
  if (result === null)
232
257
  return; // parse error or unconfigured tags — leave for runtime
233
258
  branch_results.push({ markup: result.markup, imports: result.imports });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fuzdev/mdz",
3
- "version": "0.7.0",
4
- "description": "a strict markdown dialect built for streaming, Svelte authoring, docs websites, and untrusted content",
3
+ "version": "0.8.1",
4
+ "description": "a strict markdown dialect built for streaming, web authoring, docs, and untrusted content",
5
5
  "tagline": "markdown for fuz",
6
6
  "glyph": "📝",
7
7
  "logo": "logo.svg",
@@ -25,7 +25,7 @@
25
25
  "build": "gro build",
26
26
  "check": "gro check",
27
27
  "test": "gro test",
28
- "fixtures:update": "gro src/test/fixtures/update",
28
+ "fixtures:update": "gro task src/test/fixtures/mdz/update.task.ts && gro task src/test/fixtures/svelte_preprocess_mdz/update.task.ts",
29
29
  "preview": "vite preview",
30
30
  "deploy": "gro deploy",
31
31
  "benchmark": "gro run src/benchmarks/mdz.benchmark.ts",
@@ -44,7 +44,7 @@
44
44
  "node": ">=24.14"
45
45
  },
46
46
  "peerDependencies": {
47
- "@fuzdev/fuz_util": ">=0.79.0",
47
+ "@fuzdev/fuz_util": ">=0.80.0",
48
48
  "@sveltejs/kit": "^3",
49
49
  "@types/estree": "^1",
50
50
  "esm-env": "^1",
@@ -64,13 +64,13 @@
64
64
  },
65
65
  "devDependencies": {
66
66
  "@fuzdev/blake3-wasm": "^0.2.0",
67
- "@fuzdev/fuz_code": "^0.54.0",
68
- "@fuzdev/fuz_css": "^0.71.1",
69
- "@fuzdev/fuz_schema": "^0.5.0",
70
- "@fuzdev/fuz_ui": "^0.220.0",
71
- "@fuzdev/fuz_util": "^0.79.0",
72
- "@fuzdev/gro": "^0.222.0",
73
- "@ryanatkn/eslint-config": "^0.13.1",
67
+ "@fuzdev/fuz_code": "^0.58.0",
68
+ "@fuzdev/fuz_css": "^0.79.0",
69
+ "@fuzdev/fuz_schema": "^0.5.6",
70
+ "@fuzdev/fuz_ui": "^0.226.0",
71
+ "@fuzdev/fuz_util": "^0.80.0",
72
+ "@fuzdev/gro": "^0.226.0",
73
+ "@ryanatkn/eslint-config": "^0.13.2",
74
74
  "@sveltejs/acorn-typescript": "^1.0.10",
75
75
  "@sveltejs/adapter-static": "^4.0.0",
76
76
  "@sveltejs/kit": "^3.0.1",
package/src/lib/mdz.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * mdz — strict markdown dialect built for streaming, Svelte authoring, docs
3
- * sites, and untrusted content.
2
+ * mdz — strict markdown dialect built for streaming, web authoring, docs, and
3
+ * untrusted content.
4
4
  *
5
5
  * Created for two motivating use cases: rendering TSDoc/JSDoc comments on
6
6
  * docs websites (with domain-specific behavior like linkifying backticked
@@ -752,6 +752,19 @@ export const mdz_heading_id = (nodes: Array<MdzNode>): string => slugify(mdz_tex
752
752
  */
753
753
  export const mdz_heading_id_from_text = (text: string): string => slugify(text);
754
754
 
755
+ /**
756
+ * Prepares top-level nodes for inline rendering by unwrapping a lone paragraph
757
+ * into its children, so `inline` output has no block `<p>`.
758
+ * Multiple blocks or a non-paragraph block can't be inline and return unchanged.
759
+ *
760
+ * @param nodes - top-level nodes from `mdz_parse`
761
+ * @returns the lone paragraph's children, otherwise `nodes`
762
+ */
763
+ export const mdz_unwrap_inline = (nodes: Array<MdzNode>): Array<MdzNode> => {
764
+ const first = nodes[0];
765
+ return nodes.length === 1 && first?.type === 'Paragraph' ? first.children : nodes;
766
+ };
767
+
755
768
  /**
756
769
  * Check if a string is a URL (`https://` or `http://`).
757
770
  * Requires at least one valid character after the protocol.
@@ -56,6 +56,43 @@ export interface MdzToSvelteResult {
56
56
  has_unconfigured_tags: boolean;
57
57
  }
58
58
 
59
+ /** The whitespace the Svelte compiler trims and collapses in template text. */
60
+ const is_template_whitespace = (char: string | undefined): boolean =>
61
+ char === ' ' || char === '\t' || char === '\r' || char === '\n';
62
+
63
+ /**
64
+ * Emits a whitespace run, as an expression when the Svelte compiler would
65
+ * otherwise change it. Only a single space beside a sibling survives as
66
+ * template text: fragment edges are trimmed, longer runs collapse.
67
+ */
68
+ const render_whitespace = (whitespace: string, has_sibling: boolean): string =>
69
+ whitespace === '' || (whitespace === ' ' && has_sibling)
70
+ ? whitespace
71
+ : `{'${escape_js_string(whitespace)}'}`;
72
+
73
+ /**
74
+ * Emits text so it survives the Svelte compiler's whitespace handling, matching
75
+ * the runtime views' `{text}` expressions. Interior whitespace needs no
76
+ * protection, only the runs at the text's edges.
77
+ *
78
+ * @param content - the raw text
79
+ * @param has_prev - whether a sibling node precedes the text
80
+ * @param has_next - whether a sibling node follows the text
81
+ * @returns Svelte markup
82
+ */
83
+ const render_text = (content: string, has_prev: boolean, has_next: boolean): string => {
84
+ let start = 0;
85
+ while (start < content.length && is_template_whitespace(content[start])) start++;
86
+ if (start === content.length) return render_whitespace(content, has_prev && has_next);
87
+ let end = content.length;
88
+ while (is_template_whitespace(content[end - 1])) end--;
89
+ return (
90
+ render_whitespace(content.slice(0, start), has_prev) +
91
+ escape_svelte_text(content.slice(start, end)) +
92
+ render_whitespace(content.slice(end), has_next)
93
+ );
94
+ };
95
+
59
96
  /** Derives an import's local identifier from a `.svelte` import path's basename. */
60
97
  const component_local_name = (import_path: string): string =>
61
98
  import_path.slice(import_path.lastIndexOf('/') + 1).replace(/\.svelte$/, '');
@@ -123,17 +160,17 @@ export const mdz_to_svelte = (
123
160
  let has_unconfigured_tags = false;
124
161
 
125
162
  const render_nodes = (children: Array<MdzNode>): string => {
126
- return children.map((child) => render_node(child)).join('');
163
+ return children.map((child, i) => render_node(child, i > 0, i < children.length - 1)).join('');
127
164
  };
128
165
 
129
- const render_node = (node: MdzNode): string => {
166
+ const render_node = (node: MdzNode, has_prev: boolean, has_next: boolean): string => {
130
167
  switch (node.type) {
131
168
  case 'Text':
132
- return escape_svelte_text(node.content);
169
+ return render_text(node.content, has_prev, has_next);
133
170
 
134
171
  case 'Code': {
135
172
  if (!code_component_import) {
136
- return `<code>${escape_svelte_text(node.content)}</code>`;
173
+ return `<code>${render_text(node.content, false, false)}</code>`;
137
174
  }
138
175
  const name = component_local_name(code_component_import);
139
176
  imports.set(name, { path: code_component_import, kind: 'default' });
@@ -37,6 +37,7 @@ import {
37
37
  } from '@fuzdev/fuz_util/svelte_preprocess_helpers.ts';
38
38
 
39
39
  import { mdz_parse } from './mdz.ts';
40
+ import { mdz_unwrap_inline } from './mdz_helpers.ts';
40
41
  import { mdz_to_svelte, type MdzComponentImport, type MdzToSvelteResult } from './mdz_to_svelte.ts';
41
42
 
42
43
  /**
@@ -302,6 +303,21 @@ const collect_consumed_bindings = (
302
303
  return consumed;
303
304
  };
304
305
 
306
+ /**
307
+ * Reads a static boolean attribute value, from a bare attribute or a boolean
308
+ * literal expression.
309
+ *
310
+ * @returns the boolean, or `null` when the value isn't known at build time
311
+ */
312
+ const extract_static_boolean = (value: AST.Attribute['value']): boolean | null => {
313
+ if (value === true) return true;
314
+ if (Array.isArray(value)) return null;
315
+ const { expression } = value;
316
+ return expression.type === 'Literal' && typeof expression.value === 'boolean'
317
+ ? expression.value
318
+ : null;
319
+ };
320
+
305
321
  /**
306
322
  * Parse a static mdz string and render it to Svelte markup. Returns `null` to
307
323
  * leave the usage for the runtime — either the content raised a parse error
@@ -311,11 +327,13 @@ const collect_consumed_bindings = (
311
327
  const render_static_mdz = (
312
328
  content: string,
313
329
  base: string | undefined,
330
+ inline: boolean,
314
331
  context: FindMdzUsagesContext
315
332
  ): MdzToSvelteResult | null => {
316
333
  let result: MdzToSvelteResult;
317
334
  try {
318
- result = mdz_to_svelte(mdz_parse(content), {
335
+ const nodes = mdz_parse(content);
336
+ result = mdz_to_svelte(inline ? mdz_unwrap_inline(nodes) : nodes, {
319
337
  components: context.components,
320
338
  elements: context.elements,
321
339
  base,
@@ -372,6 +390,13 @@ const find_mdz_usages = (
372
390
  base = base_value;
373
391
  }
374
392
 
393
+ // `inline` decides the markup, not just the wrapper — a lone paragraph is
394
+ // unwrapped — so a dynamic value can't be precompiled. The attribute stays
395
+ // in the output for `MdzPrecompiled`'s wrapper.
396
+ const inline_attr = find_attribute(node, 'inline');
397
+ const inline = inline_attr ? extract_static_boolean(inline_attr.value) : false;
398
+ if (inline === null) return; // dynamic inline — fall back to runtime
399
+
375
400
  // Collect attributes to exclude from precompiled output
376
401
  const exclude_attrs: Set<AST.Attribute> = new Set([content_attr]);
377
402
  if (base_attr) exclude_attrs.add(base_attr);
@@ -379,7 +404,7 @@ const find_mdz_usages = (
379
404
  // Extract static string value
380
405
  const content_value = extract_static_string(content_attr.value, context.bindings);
381
406
  if (content_value !== null) {
382
- const result = render_static_mdz(content_value, base, context);
407
+ const result = render_static_mdz(content_value, base, inline, context);
383
408
  if (result === null) return; // parse error or unconfigured tags — leave for runtime
384
409
 
385
410
  const consumed = collect_consumed_bindings(content_attr.value, context.bindings);
@@ -408,7 +433,7 @@ const find_mdz_usages = (
408
433
  const branch_results: Array<{ markup: string; imports: Map<string, PreprocessImportInfo> }> =
409
434
  [];
410
435
  for (const branch of chain) {
411
- const result = render_static_mdz(branch.value, base, context);
436
+ const result = render_static_mdz(branch.value, base, inline, context);
412
437
  if (result === null) return; // parse error or unconfigured tags — leave for runtime
413
438
  branch_results.push({ markup: result.markup, imports: result.imports });
414
439
  }