svelte-streamdown 1.0.8 → 1.0.9

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 (72) hide show
  1. package/README.md +11 -5
  2. package/dist/Block.svelte +26 -10
  3. package/dist/Elements/Code.svelte +1 -1
  4. package/dist/Elements/Element.svelte +120 -37
  5. package/dist/Elements/FootnoteRef.svelte +113 -0
  6. package/dist/Elements/FootnoteRef.svelte.d.ts +7 -0
  7. package/dist/Elements/Image.svelte +3 -3
  8. package/dist/Elements/{A.svelte → Link.svelte} +3 -3
  9. package/dist/Elements/{A.svelte.d.ts → Link.svelte.d.ts} +3 -3
  10. package/dist/Elements/Math.svelte +3 -2
  11. package/dist/Elements/index.d.ts +5 -24
  12. package/dist/Elements/index.js +5 -24
  13. package/dist/Streamdown.d.ts +1 -1
  14. package/dist/Streamdown.svelte +7 -1
  15. package/dist/Streamdown.svelte.d.ts +6 -0
  16. package/dist/marked/index.d.ts +18 -5
  17. package/dist/marked/index.js +4 -0
  18. package/dist/marked/marked-alert.d.ts +2 -2
  19. package/dist/marked/marked-alert.js +18 -18
  20. package/dist/marked/marked-footnotes.d.ts +1 -0
  21. package/dist/marked/marked-footnotes.js +28 -8
  22. package/dist/marked/marked-list.d.ts +36 -0
  23. package/dist/marked/marked-list.js +215 -0
  24. package/dist/marked/marked-math.js +0 -3
  25. package/dist/marked/marked-subsup.d.ts +28 -0
  26. package/dist/marked/marked-subsup.js +44 -0
  27. package/dist/theme.d.ts +48 -42
  28. package/dist/theme.js +47 -43
  29. package/dist/utils/parse-incomplete-markdown.js +157 -0
  30. package/dist/utils/useClickOutside.svelte.d.ts +8 -0
  31. package/dist/utils/useClickOutside.svelte.js +42 -0
  32. package/dist/utils/useKeyDown.svelte.d.ts +5 -0
  33. package/dist/utils/useKeyDown.svelte.js +20 -0
  34. package/package.json +3 -1
  35. package/dist/Elements/Blockquote.svelte +0 -28
  36. package/dist/Elements/Blockquote.svelte.d.ts +0 -9
  37. package/dist/Elements/Del.svelte +0 -28
  38. package/dist/Elements/Del.svelte.d.ts +0 -9
  39. package/dist/Elements/Em.svelte +0 -28
  40. package/dist/Elements/Em.svelte.d.ts +0 -9
  41. package/dist/Elements/Heading.svelte +0 -25
  42. package/dist/Elements/Heading.svelte.d.ts +0 -9
  43. package/dist/Elements/Hr.svelte +0 -26
  44. package/dist/Elements/Hr.svelte.d.ts +0 -9
  45. package/dist/Elements/InlineCode.svelte +0 -28
  46. package/dist/Elements/InlineCode.svelte.d.ts +0 -9
  47. package/dist/Elements/Li.svelte +0 -28
  48. package/dist/Elements/Li.svelte.d.ts +0 -9
  49. package/dist/Elements/Ol.svelte +0 -30
  50. package/dist/Elements/Ol.svelte.d.ts +0 -9
  51. package/dist/Elements/P.svelte +0 -28
  52. package/dist/Elements/P.svelte.d.ts +0 -9
  53. package/dist/Elements/Strong.svelte +0 -28
  54. package/dist/Elements/Strong.svelte.d.ts +0 -9
  55. package/dist/Elements/Sub.svelte +0 -27
  56. package/dist/Elements/Sub.svelte.d.ts +0 -8
  57. package/dist/Elements/Sup.svelte +0 -28
  58. package/dist/Elements/Sup.svelte.d.ts +0 -8
  59. package/dist/Elements/Tbody.svelte +0 -24
  60. package/dist/Elements/Tbody.svelte.d.ts +0 -7
  61. package/dist/Elements/Td.svelte +0 -28
  62. package/dist/Elements/Td.svelte.d.ts +0 -9
  63. package/dist/Elements/Th.svelte +0 -28
  64. package/dist/Elements/Th.svelte.d.ts +0 -9
  65. package/dist/Elements/Thead.svelte +0 -27
  66. package/dist/Elements/Thead.svelte.d.ts +0 -9
  67. package/dist/Elements/Tr.svelte +0 -27
  68. package/dist/Elements/Tr.svelte.d.ts +0 -9
  69. package/dist/Elements/Ul.svelte +0 -28
  70. package/dist/Elements/Ul.svelte.d.ts +0 -9
  71. /package/dist/{hightlighter.svelte.d.ts → utils/hightlighter.svelte.d.ts} +0 -0
  72. /package/dist/{hightlighter.svelte.js → utils/hightlighter.svelte.js} +0 -0
package/README.md CHANGED
@@ -30,7 +30,15 @@ Full support for GitHub Flavored Markdown including:
30
30
 
31
31
  - Task lists
32
32
  - Tables
33
- - Strikethrough text
33
+ - ~~Strikethrough~~
34
+ - Subscript (H~2~O)
35
+ - Superscript (E = mc^2^)
36
+ - Footnotes [^1]
37
+
38
+ [^1]:
39
+ Reference render in a popover by default.
40
+ with _rich_ **content** support
41
+ and multiline
34
42
 
35
43
  ### 💻 Interactive Code Blocks
36
44
 
@@ -133,6 +141,8 @@ This Svelte port maintains feature parity with the original [Streamdown](https:/
133
141
 
134
142
  > [!NOTE]
135
143
  > Streamdown comes with **built-in Tailwind CSS classes** for beautiful default styling. To ensure all styles are included in your build, add the following to your `app.css` or main CSS file:
144
+ > This setup is primarily necessary if you're using Tailwind CSS v4's new `@source` directive or if you have aggressive purging enabled in older versions. If you're using standard Tailwind CSS v3+ with default purging, Streamdown's styles should be automatically included when the component is imported and used in your application.
145
+ > This ensures that all Streamdown's default styling is included in your Tailwind build process.
136
146
 
137
147
  ```css
138
148
  @import 'tailwindcss';
@@ -140,10 +150,6 @@ This Svelte port maintains feature parity with the original [Streamdown](https:/
140
150
  @source "../node_modules/svelte-streamdown/**/*";
141
151
  ```
142
152
 
143
- This ensures that all Streamdown's default styling is included in your Tailwind build process.
144
-
145
- > **Note:** This setup is primarily necessary if you're using Tailwind CSS v4's new `@source` directive or if you have aggressive purging enabled in older versions. If you're using standard Tailwind CSS v3+ with default purging, Streamdown's styles should be automatically included when the component is imported and used in your application.
146
-
147
153
  ## 🚀 Quick Start
148
154
 
149
155
  ### Basic Usage
package/dist/Block.svelte CHANGED
@@ -1,3 +1,6 @@
1
+ <script lang="ts" module>
2
+ </script>
3
+
1
4
  <script lang="ts">
2
5
  import { parseIncompleteMarkdown } from './utils/parse-incomplete-markdown.js';
3
6
  import Element from './Elements/Element.svelte';
@@ -17,21 +20,27 @@
17
20
  }
18
21
 
19
22
  if (token.type === 'table') {
20
- const headerRow = {
21
- type: 'tableRow',
22
- tokens: token.header.map((cell) => ({
23
- type: 'tableCell',
24
- ...cell
25
- })),
26
- isHeader: true
27
- } satisfies TableRow;
23
+ const headerRow = token.header?.length
24
+ ? ({
25
+ type: 'tableRow',
26
+ raw: '',
27
+ tokens: token.header.map((cell) => ({
28
+ type: 'th',
29
+ raw: '',
30
+ ...cell
31
+ })),
32
+ isHeader: true
33
+ } satisfies TableRow)
34
+ : null;
28
35
 
29
36
  const rows = token.rows.reduce(
30
37
  (acc, cells) => {
31
38
  const row = {
32
39
  type: 'tableRow',
40
+ raw: '',
33
41
  tokens: cells.map((cell) => ({
34
- type: 'tableCell',
42
+ type: 'td',
43
+ raw: '',
35
44
  ...cell
36
45
  })),
37
46
  isHeader: false
@@ -39,7 +48,14 @@
39
48
  acc.push(row);
40
49
  return acc;
41
50
  },
42
- [headerRow] as TableRow[]
51
+ headerRow
52
+ ? ([
53
+ {
54
+ type: 'tableHead',
55
+ tokens: [headerRow]
56
+ }
57
+ ] as StreamdownToken[])
58
+ : []
43
59
  );
44
60
 
45
61
  return rows;
@@ -2,7 +2,7 @@
2
2
  import { useStreamdown } from '../Streamdown.svelte';
3
3
  import { save } from '../utils/save.js';
4
4
  import { useCopy } from '../utils/copy.svelte.js';
5
- import { HighlighterManager, languageExtensionMap } from '../hightlighter.svelte.js';
5
+ import { HighlighterManager, languageExtensionMap } from '../utils/hightlighter.svelte.js';
6
6
  import type { Tokens } from 'marked';
7
7
  import type { Snippet } from 'svelte';
8
8
 
@@ -1,80 +1,163 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import A from './A.svelte';
4
- import Blockquote from './Blockquote.svelte';
3
+ import Link from './Link.svelte';
5
4
  import Code from './Code.svelte';
6
- import Hr from './Hr.svelte';
7
5
  import Image from './Image.svelte';
8
- import Li from './Li.svelte';
9
- import Ol from './Ol.svelte';
10
- import P from './P.svelte';
11
- import Strong from './Strong.svelte';
12
- import Sub from './Sub.svelte';
13
- import Sup from './Sup.svelte';
14
6
  import Table from './Table.svelte';
15
- import Tbody from './Tbody.svelte';
16
- import Td from './Td.svelte';
17
- import Th from './Th.svelte';
18
- import Thead from './Thead.svelte';
19
- import Tr from './Tr.svelte';
20
- import Ul from './Ul.svelte';
21
- import InlineCode from './InlineCode.svelte';
22
7
  import Mermaid from './Mermaid.svelte';
23
8
  import Math from './Math.svelte';
24
- import Em from './Em.svelte';
25
- import Del from './Del.svelte';
26
9
  import Alert from './Alert.svelte';
27
10
  import type { StreamdownToken } from '../marked/index.js';
28
- import Heading from './Heading.svelte';
11
+ import Slot from './Slot.svelte';
12
+ import { useStreamdown } from '../Streamdown.svelte';
13
+ import FootnoteRef from './FootnoteRef.svelte';
29
14
  let { token, children }: { token: StreamdownToken; children: Snippet } = $props();
15
+ const id = $props.id();
16
+ const streamdown = useStreamdown();
30
17
  </script>
31
18
 
32
19
  {#if token.type === 'heading'}
33
- <Heading {token} {children} />
20
+ {@const level = `h${token.depth}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'}
21
+ {@const className = streamdown.theme[level].base}
22
+ <Slot
23
+ props={{
24
+ children,
25
+ token
26
+ }}
27
+ render={streamdown.snippets.heading}
28
+ >
29
+ <svelte:element this={level} class={className}>
30
+ {@render children()}
31
+ </svelte:element>
32
+ </Slot>
34
33
  {:else if token.type === 'paragraph'}
35
- <P {token} {children} />
34
+ <Slot props={{ children, token }} render={streamdown.snippets.paragraph}>
35
+ <p class={streamdown.theme.paragraph.base}>
36
+ {@render children()}
37
+ </p>
38
+ </Slot>
36
39
  {:else if token.type === 'blockquote'}
37
- <Blockquote {token} {children} />
40
+ <Slot props={{ children, token }} render={streamdown.snippets.blockquote}>
41
+ <blockquote class={streamdown.theme.blockquote.base}>
42
+ {@render children()}
43
+ </blockquote>
44
+ </Slot>
38
45
  {:else if token.type === 'code' && token.lang === 'mermaid'}
39
46
  <Mermaid {token} {children} />
40
47
  {:else if token.type === 'code'}
41
48
  <Code {token} {children} />
42
49
  {:else if token.type === 'codespan'}
43
- <InlineCode {token} {children} />
50
+ <Slot props={{ children, token }} render={streamdown.snippets.codespan}>
51
+ <code class={streamdown.theme.codespan.base}>
52
+ {token.text}
53
+ </code>
54
+ </Slot>
44
55
  {:else if token.type === 'list'}
45
56
  {#if token.ordered}
46
- <Ol {token} {children} />
57
+ {@const firstItemValue = token.items[0]?.value || 1}
58
+ {@const counterName = `counter-${id}`}
59
+ <Slot props={{ children, token }} render={streamdown.snippets.ol}>
60
+ <ol style:list-style-type={token.listType} class={streamdown.theme.ol.base}>
61
+ {@render children()}
62
+ </ol>
63
+ </Slot>
47
64
  {:else}
48
- <Ul {token} {children} />
65
+ <Slot props={{ children, token }} render={streamdown.snippets.ul}>
66
+ <ul class={streamdown.theme.ul.base}>
67
+ {@render children()}
68
+ </ul>
69
+ </Slot>
49
70
  {/if}
50
71
  {:else if token.type === 'list_item'}
51
- <Li {token} {children} />
72
+ <Slot props={{ children, token }} render={streamdown.snippets.li}>
73
+ <li
74
+ style:list-style-type={token.task ? 'none' : undefined}
75
+ value={token.value}
76
+ class={streamdown.theme.li.base}
77
+ >
78
+ {#if token.task}
79
+ <input
80
+ disabled
81
+ type="checkbox"
82
+ checked={token.checked}
83
+ class={streamdown.theme.li.checkbox}
84
+ />
85
+ {/if}
86
+ {@render children()}
87
+ </li>
88
+ </Slot>
52
89
  {:else if token.type === 'table'}
53
90
  <Table {token} {children} />
54
- {:else if token.type === 'tableRow' && token.isHeader}
55
- <Thead {token} {children} />
56
- {:else if token.type === 'tableRow' && !token.isHeader}
57
- <Tr {token} {children} />
58
- {:else if token.type === 'tableCell'}
59
- <Td {token} {children} />
91
+ {:else if token.type === 'tableRow'}
92
+ <Slot props={{ token, children }} render={streamdown.snippets.tableRow}>
93
+ <tr class={streamdown.theme.tableRow.base}>
94
+ {@render children?.()}
95
+ </tr>
96
+ </Slot>
97
+ {:else if token.type === 'tableHead'}
98
+ <Slot props={{ token, children }} render={streamdown.snippets.tableHead}>
99
+ <thead class={streamdown.theme.tableHead.base}>
100
+ {@render children?.()}
101
+ </thead>
102
+ </Slot>
103
+ {:else if token.type === 'td'}
104
+ <Slot props={{ children, token }} render={streamdown.snippets.td}>
105
+ <td class={streamdown.theme.td.base}>
106
+ {@render children?.()}
107
+ </td>
108
+ </Slot>
109
+ {:else if token.type === 'th'}
110
+ <Slot props={{ children, token }} render={streamdown.snippets.th}>
111
+ <th class={streamdown.theme.th.base}>
112
+ {@render children?.()}
113
+ </th>
114
+ </Slot>
60
115
  {:else if token.type === 'image'}
61
116
  <Image {token} {children} />
62
117
  {:else if token.type === 'link'}
63
- <A {token} {children} />
118
+ <Link {token} {children} />
119
+ {:else if token.type === 'sub'}
120
+ <Slot props={{ children, token }} render={streamdown.snippets.sub}>
121
+ <sub class={streamdown.theme.sub.base}>
122
+ {@render children()}
123
+ </sub>
124
+ </Slot>
125
+ {:else if token.type === 'sup'}
126
+ <Slot props={{ children, token }} render={streamdown.snippets.sup}>
127
+ <sup class={streamdown.theme.sup.base}>
128
+ {@render children()}
129
+ </sup>
130
+ </Slot>
64
131
  {:else if token.type === 'strong'}
65
- <Strong {token} {children} />
132
+ <Slot props={{ children, token }} render={streamdown.snippets.strong}>
133
+ <strong class={streamdown.theme.strong.base}>
134
+ {@render children()}
135
+ </strong>
136
+ </Slot>
66
137
  {:else if token.type === 'em'}
67
- <Em {token} {children} />
138
+ <Slot props={{ children, token }} render={streamdown.snippets.em}>
139
+ <em class={streamdown.theme.em.base}>
140
+ {@render children()}
141
+ </em>
142
+ </Slot>
68
143
  {:else if token.type === 'del'}
69
- <Del {token} {children} />
144
+ <Slot props={{ children, token }} render={streamdown.snippets.del}>
145
+ <del class={streamdown.theme.del.base}>
146
+ {@render children()}
147
+ </del>
148
+ </Slot>
70
149
  {:else if token.type === 'hr'}
71
- <Hr {token} {children} />
150
+ <Slot props={{ children, token }} render={streamdown.snippets.hr}>
151
+ <hr class={streamdown.theme.hr.base} />
152
+ </Slot>
72
153
  {:else if token.type === 'br'}
73
154
  <br />
74
155
  {:else if token.type === 'math'}
75
156
  <Math {token} {children} />
76
157
  {:else if token.type === 'alert'}
77
158
  <Alert {token} {children} />
159
+ {:else if token.type === 'footnoteRef'}
160
+ <FootnoteRef {token} />
78
161
  {:else}
79
162
  <!-- For tokens we don't handle specifically, render children or fallback -->
80
163
  {@render children?.()}
@@ -0,0 +1,113 @@
1
+ <script lang="ts">
2
+ import { useStreamdown } from '../Streamdown.svelte';
3
+ import Slot from './Slot.svelte';
4
+ import type { FootnoteRef } from '../marked/marked-footnotes.js';
5
+ import { autoPlacement, computePosition, hide, offset, shift, size } from '@floating-ui/dom';
6
+ import { useClickOutside } from '../utils/useClickOutside.svelte.js';
7
+ import { scale } from 'svelte/transition';
8
+ import Block from '../Block.svelte';
9
+ import { useKeyDown } from '../utils/useKeyDown.svelte.js';
10
+
11
+ const streamdown = useStreamdown();
12
+
13
+ const {
14
+ token
15
+ }: {
16
+ token: FootnoteRef;
17
+ } = $props();
18
+
19
+ let isOpen = $state(false);
20
+
21
+ let reference = $state<HTMLButtonElement>();
22
+ let content = $state<HTMLDialogElement>();
23
+
24
+ const clickOutside = useClickOutside({
25
+ get isActive() {
26
+ return isOpen;
27
+ },
28
+ callback: () => {
29
+ isOpen = false;
30
+ }
31
+ });
32
+
33
+ useKeyDown({
34
+ keys: ['Escape'],
35
+ get isActive() {
36
+ return isOpen;
37
+ },
38
+ callback: () => {
39
+ isOpen = false;
40
+ }
41
+ });
42
+
43
+ const place = async (node: HTMLElement) => {
44
+ const middleware = [
45
+ hide(),
46
+ offset(0),
47
+ shift({
48
+ mainAxis: true
49
+ }),
50
+ autoPlacement({
51
+ allowedPlacements: ['top', 'top-end', 'top-start', 'bottom', 'bottom-end', 'bottom-start']
52
+ }),
53
+ size()
54
+ ];
55
+ const { x, y, strategy, placement, middlewareData } = await computePosition(reference!, node, {
56
+ strategy: 'fixed',
57
+ middleware
58
+ });
59
+
60
+ Object.assign(node.style, {
61
+ position: strategy,
62
+ left: `${x}px`,
63
+ top: `${y}px`
64
+ });
65
+ };
66
+
67
+ const popoverAttachment = (node: HTMLDialogElement) => {
68
+ content = node;
69
+ void place(node);
70
+
71
+ return () => {
72
+ //
73
+ };
74
+ };
75
+ </script>
76
+
77
+ {#if isOpen}
78
+ <Slot
79
+ props={{
80
+ token,
81
+ isOpen
82
+ }}
83
+ render={streamdown.snippets.footnotePopover}
84
+ >
85
+ <dialog
86
+ transition:scale|global={{ start: 0.95, duration: 100 }}
87
+ {@attach clickOutside.attachment}
88
+ {@attach popoverAttachment}
89
+ open
90
+ class={`${streamdown.theme.footnotePopover.base}`}
91
+ >
92
+ {#each token.content.lines as line}
93
+ <Block block={line} />
94
+ {/each}
95
+ </dialog>
96
+ </Slot>
97
+ {/if}
98
+
99
+ <Slot
100
+ props={{
101
+ token
102
+ }}
103
+ render={streamdown.snippets.footnoteRef}
104
+ >
105
+ <button
106
+ bind:this={reference}
107
+ class={streamdown.theme.footnoteRef.base}
108
+ onclick={() => (isOpen = !isOpen)}
109
+ {@attach clickOutside.attachment}
110
+ >
111
+ {token.label.replace('^', '')}
112
+ </button>
113
+ </Slot>
@@ -0,0 +1,7 @@
1
+ import type { FootnoteRef } from '../marked/marked-footnotes.js';
2
+ type $$ComponentProps = {
3
+ token: FootnoteRef;
4
+ };
5
+ declare const FootnoteRef: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type FootnoteRef = ReturnType<typeof FootnoteRef>;
7
+ export default FootnoteRef;
@@ -28,10 +28,10 @@
28
28
  children,
29
29
  token
30
30
  }}
31
- render={streamdown.snippets.img}
31
+ render={streamdown.snippets.image}
32
32
  >
33
- <div class={streamdown.theme.img.base}>
34
- <img class={streamdown.theme.img.image} src={transformedUrl} alt={token.text} />
33
+ <div class={streamdown.theme.image.base}>
34
+ <img class={streamdown.theme.image.image} src={transformedUrl} alt={token.text} />
35
35
  </div>
36
36
  </Slot>
37
37
  {:else}
@@ -30,10 +30,10 @@
30
30
  children,
31
31
  token
32
32
  }}
33
- render={streamdown.snippets.a}
33
+ render={streamdown.snippets.link}
34
34
  >
35
35
  <a
36
- class={streamdown.theme.a.base}
36
+ class={streamdown.theme.link.base}
37
37
  href={transformedUrl}
38
38
  target="_blank"
39
39
  rel="noopener noreferrer"
@@ -43,7 +43,7 @@
43
43
  </Slot>
44
44
  {:else}
45
45
  <span
46
- class={streamdown.theme.a.blocked}
46
+ class={streamdown.theme.link.blocked}
47
47
  title={token.title ? `Blocked URL: ${token.href}` : undefined}
48
48
  >
49
49
  {@render children()} [blocked]
@@ -4,6 +4,6 @@ type $$ComponentProps = {
4
4
  children: Snippet;
5
5
  token: Tokens.Link;
6
6
  };
7
- declare const A: import("svelte").Component<$$ComponentProps, {}, "">;
8
- type A = ReturnType<typeof A>;
9
- export default A;
7
+ declare const Link: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type Link = ReturnType<typeof Link>;
9
+ export default Link;
@@ -42,6 +42,7 @@
42
42
  : streamdown.katexConfig || {})
43
43
  };
44
44
  const code = token.text;
45
+ console.log({ code });
45
46
  try {
46
47
  return katexInstance.renderToString(code, config);
47
48
  } catch (error) {
@@ -60,13 +61,13 @@
60
61
  render={streamdown.snippets.math}
61
62
  >
62
63
  {#if isInline}
63
- <span bind:this={inner} class={streamdown.theme.inlineMath.base}>
64
+ <span bind:this={inner} class={streamdown.theme.math.inline}>
64
65
  {@html html}
65
66
  </span>
66
67
  {:else}
67
68
  <div class="h-fit w-full">
68
69
  <div class="overflow-x-auto">
69
- <div bind:this={inner} class={streamdown.theme.math.base}>
70
+ <div bind:this={inner} class={streamdown.theme.math.block}>
70
71
  {@html html}
71
72
  </div>
72
73
  </div>
@@ -1,28 +1,9 @@
1
- export { default as A } from './A.svelte';
2
- export { default as Blockquote } from './Blockquote.svelte';
1
+ export { default as Alert } from './Alert.svelte';
3
2
  export { default as Code } from './Code.svelte';
4
- export { default as CodeBlock } from './Code.svelte';
5
- export { default as Heading } from './Heading.svelte';
6
- export { default as Hr } from './Hr.svelte';
3
+ export { default as Element } from './Element.svelte';
7
4
  export { default as Image } from './Image.svelte';
8
- export { default as Li } from './Li.svelte';
9
- export { default as Ol } from './Ol.svelte';
10
- export { default as P } from './P.svelte';
5
+ export { default as Link } from './Link.svelte';
6
+ export { default as Math } from './Math.svelte';
7
+ export { default as Mermaid } from './Mermaid.svelte';
11
8
  export { default as Slot } from './Slot.svelte';
12
- export { default as Strong } from './Strong.svelte';
13
- export { default as Sub } from './Sub.svelte';
14
- export { default as Sup } from './Sup.svelte';
15
9
  export { default as Table } from './Table.svelte';
16
- export { default as Tbody } from './Tbody.svelte';
17
- export { default as Td } from './Td.svelte';
18
- export { default as Th } from './Th.svelte';
19
- export { default as Thead } from './Thead.svelte';
20
- export { default as Tr } from './Tr.svelte';
21
- export { default as Ul } from './Ul.svelte';
22
- export { default as InlineCode } from './InlineCode.svelte';
23
- export { default as Mermaid } from './Mermaid.svelte';
24
- export { default as Math } from './Math.svelte';
25
- export { default as Em } from './Em.svelte';
26
- export { default as Del } from './Del.svelte';
27
- export { default as Alert } from './Alert.svelte';
28
- export { default as Element } from './Element.svelte';
@@ -1,28 +1,9 @@
1
- export { default as A } from './A.svelte';
2
- export { default as Blockquote } from './Blockquote.svelte';
1
+ export { default as Alert } from './Alert.svelte';
3
2
  export { default as Code } from './Code.svelte';
4
- export { default as CodeBlock } from './Code.svelte';
5
- export { default as Heading } from './Heading.svelte';
6
- export { default as Hr } from './Hr.svelte';
3
+ export { default as Element } from './Element.svelte';
7
4
  export { default as Image } from './Image.svelte';
8
- export { default as Li } from './Li.svelte';
9
- export { default as Ol } from './Ol.svelte';
10
- export { default as P } from './P.svelte';
5
+ export { default as Link } from './Link.svelte';
6
+ export { default as Math } from './Math.svelte';
7
+ export { default as Mermaid } from './Mermaid.svelte';
11
8
  export { default as Slot } from './Slot.svelte';
12
- export { default as Strong } from './Strong.svelte';
13
- export { default as Sub } from './Sub.svelte';
14
- export { default as Sup } from './Sup.svelte';
15
9
  export { default as Table } from './Table.svelte';
16
- export { default as Tbody } from './Tbody.svelte';
17
- export { default as Td } from './Td.svelte';
18
- export { default as Th } from './Th.svelte';
19
- export { default as Thead } from './Thead.svelte';
20
- export { default as Tr } from './Tr.svelte';
21
- export { default as Ul } from './Ul.svelte';
22
- export { default as InlineCode } from './InlineCode.svelte';
23
- export { default as Mermaid } from './Mermaid.svelte';
24
- export { default as Math } from './Math.svelte';
25
- export { default as Em } from './Em.svelte';
26
- export { default as Del } from './Del.svelte';
27
- export { default as Alert } from './Alert.svelte';
28
- export { default as Element } from './Element.svelte';
@@ -5,7 +5,7 @@ import type { MermaidConfig } from 'mermaid';
5
5
  import type { KatexOptions } from 'katex';
6
6
  import type { StreamdownContext } from './Streamdown.svelte';
7
7
  import type { StreamdownToken } from './marked/index.js';
8
- type PredefinedElements = 'a' | 'heading' | 'paragraph' | 'code' | 'inlineCode' | 'img' | 'ul' | 'ol' | 'li' | 'hr' | 'alert' | 'strong' | 'blockquote' | 'table' | 'thead' | 'tbody' | 'tr' | 'th' | 'td' | 'sup' | 'sub' | 'pre' | 'mermaid' | 'math' | 'inlineMath' | 'em' | 'del';
8
+ type PredefinedElements = 'heading' | 'paragraph' | 'blockquote' | 'code' | 'codespan' | 'ul' | 'ol' | 'li' | 'table' | 'tableRow' | 'tableHead' | 'td' | 'th' | 'image' | 'link' | 'strong' | 'em' | 'del' | 'hr' | 'br' | 'math' | 'alert' | 'mermaid' | 'footnoteRef' | 'footnotePopover' | 'sup' | 'sub';
9
9
  export type Snippets = {
10
10
  [K in PredefinedElements]?: Snippet<[
11
11
  {
@@ -8,6 +8,10 @@
8
8
  theme: Theme;
9
9
  }
10
10
  export class StreamdownContext {
11
+ footnotes = {
12
+ refs: new Map<string, FootnoteRef>(),
13
+ footnotes: new Map<string, Footnote>()
14
+ };
11
15
  constructor(props: Omit<StreamdownProps, keyof Snippets | 'class'> & { snippets: Snippets }) {
12
16
  bind(this, props);
13
17
  setContext('streamdown', this);
@@ -30,7 +34,9 @@
30
34
  import { mergeTheme, type Theme, shadcnTheme } from './theme.js';
31
35
  import type { BundledTheme } from 'shiki';
32
36
  import { parseBlocks } from './marked/index.js';
33
-
37
+ import { SvelteMap } from 'svelte/reactivity';
38
+ import type { FootnoteRef } from './marked/marked-footnotes.js';
39
+ import type { Footnote } from './marked/marked-footnotes.js';
34
40
  let {
35
41
  content = '',
36
42
  class: className,
@@ -4,6 +4,10 @@ export interface StreamdownContext extends Omit<StreamdownProps, keyof Snippets
4
4
  theme: Theme;
5
5
  }
6
6
  export declare class StreamdownContext {
7
+ footnotes: {
8
+ refs: Map<string, FootnoteRef>;
9
+ footnotes: Map<string, Footnote>;
10
+ };
7
11
  constructor(props: Omit<StreamdownProps, keyof Snippets | 'class'> & {
8
12
  snippets: Snippets;
9
13
  });
@@ -13,6 +17,8 @@ import type { Snippets, StreamdownProps } from './Streamdown.js';
13
17
  import 'katex/dist/katex.min.css';
14
18
  import { type Theme } from './theme.js';
15
19
  import type { BundledTheme } from 'shiki';
20
+ import type { FootnoteRef } from './marked/marked-footnotes.js';
21
+ import type { Footnote } from './marked/marked-footnotes.js';
16
22
  declare const Streamdown: import("svelte").Component<StreamdownProps, {}, "streamdown">;
17
23
  type Streamdown = ReturnType<typeof Streamdown>;
18
24
  export default Streamdown;
@@ -2,15 +2,28 @@ import { type MarkedToken, type Tokens } from 'marked';
2
2
  import { type AlertToken } from './marked-alert.js';
3
3
  import { type FootnoteToken } from './marked-footnotes.js';
4
4
  import { type MathToken } from './marked-math.js';
5
- export type StreamdownToken = MarkedToken | MathToken | AlertToken | FootnoteToken | TableRow | TableCell;
6
- export type TableCell = Tokens.TableCell & {
7
- type: 'tableCell';
5
+ import { type SubSupToken } from './marked-subsup.js';
6
+ import { type ListItemToken, type ListToken } from './marked-list.js';
7
+ export type StreamdownToken = Exclude<MarkedToken, Tokens.List | Tokens.ListItem> | ListToken | ListItemToken | MathToken | AlertToken | FootnoteToken | SubSupToken | TableRow | TD | TH | TableHead;
8
+ export type TD = Tokens.TableCell & {
9
+ type: 'td';
10
+ raw: string;
11
+ };
12
+ export type TH = Tokens.TableCell & {
13
+ type: 'th';
14
+ raw: string;
8
15
  };
9
16
  export type TableRow = {
10
17
  type: 'tableRow';
11
- tokens: TableCell[];
18
+ raw: string;
19
+ tokens: (TD | TH)[];
12
20
  isHeader: boolean;
13
21
  };
22
+ export type TableHead = {
23
+ type: 'tableHead';
24
+ raw: string;
25
+ tokens: TableRow[];
26
+ };
14
27
  export declare const lex: (markdown: string) => StreamdownToken[];
15
28
  export declare const parseBlocks: (markdown: string) => string[];
16
- export type { MathToken, AlertToken, FootnoteToken };
29
+ export type { MathToken, AlertToken, FootnoteToken, SubSupToken };