svelte-streamdown 1.0.6 → 1.0.7

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 (90) hide show
  1. package/dist/Block.svelte +64 -20
  2. package/dist/Elements/A.svelte +17 -14
  3. package/dist/Elements/A.svelte.d.ts +7 -2
  4. package/dist/Elements/Alert.svelte +12 -28
  5. package/dist/Elements/Alert.svelte.d.ts +7 -2
  6. package/dist/Elements/Blockquote.svelte +11 -9
  7. package/dist/Elements/Blockquote.svelte.d.ts +7 -2
  8. package/dist/Elements/Code.svelte +13 -11
  9. package/dist/Elements/Code.svelte.d.ts +7 -2
  10. package/dist/Elements/Del.svelte +11 -7
  11. package/dist/Elements/Del.svelte.d.ts +7 -2
  12. package/dist/Elements/Element.svelte +50 -99
  13. package/dist/Elements/Element.svelte.d.ts +2 -5
  14. package/dist/Elements/Em.svelte +11 -6
  15. package/dist/Elements/Em.svelte.d.ts +7 -2
  16. package/dist/Elements/Heading.svelte +25 -0
  17. package/dist/Elements/Heading.svelte.d.ts +9 -0
  18. package/dist/Elements/Hr.svelte +12 -6
  19. package/dist/Elements/Hr.svelte.d.ts +7 -2
  20. package/dist/Elements/Image.svelte +17 -17
  21. package/dist/Elements/Image.svelte.d.ts +7 -2
  22. package/dist/Elements/InlineCode.svelte +12 -7
  23. package/dist/Elements/InlineCode.svelte.d.ts +7 -2
  24. package/dist/Elements/Li.svelte +11 -6
  25. package/dist/Elements/Li.svelte.d.ts +7 -2
  26. package/dist/Elements/Math.svelte +19 -9
  27. package/dist/Elements/Math.svelte.d.ts +7 -2
  28. package/dist/Elements/Mermaid.svelte +13 -9
  29. package/dist/Elements/Mermaid.svelte.d.ts +7 -2
  30. package/dist/Elements/Ol.svelte +13 -6
  31. package/dist/Elements/Ol.svelte.d.ts +7 -2
  32. package/dist/Elements/P.svelte +11 -6
  33. package/dist/Elements/P.svelte.d.ts +7 -2
  34. package/dist/Elements/Strong.svelte +11 -6
  35. package/dist/Elements/Strong.svelte.d.ts +7 -2
  36. package/dist/Elements/Sub.svelte +10 -6
  37. package/dist/Elements/Sub.svelte.d.ts +6 -2
  38. package/dist/Elements/Sup.svelte +10 -5
  39. package/dist/Elements/Sup.svelte.d.ts +6 -2
  40. package/dist/Elements/Table.svelte +12 -7
  41. package/dist/Elements/Table.svelte.d.ts +7 -2
  42. package/dist/Elements/Tbody.svelte +8 -7
  43. package/dist/Elements/Tbody.svelte.d.ts +5 -2
  44. package/dist/Elements/Td.svelte +12 -7
  45. package/dist/Elements/Td.svelte.d.ts +7 -2
  46. package/dist/Elements/Th.svelte +11 -6
  47. package/dist/Elements/Th.svelte.d.ts +7 -2
  48. package/dist/Elements/Thead.svelte +13 -9
  49. package/dist/Elements/Thead.svelte.d.ts +7 -2
  50. package/dist/Elements/Tr.svelte +13 -9
  51. package/dist/Elements/Tr.svelte.d.ts +7 -2
  52. package/dist/Elements/Ul.svelte +11 -6
  53. package/dist/Elements/Ul.svelte.d.ts +7 -2
  54. package/dist/Elements/index.d.ts +1 -6
  55. package/dist/Elements/index.js +1 -6
  56. package/dist/Streamdown.d.ts +16 -24
  57. package/dist/Streamdown.svelte +7 -39
  58. package/dist/Streamdown.svelte.d.ts +1 -1
  59. package/dist/hightlighter.svelte.js +0 -1
  60. package/dist/marked/index.d.ts +16 -0
  61. package/dist/marked/index.js +34 -0
  62. package/dist/marked/marked-alert.d.ts +19 -0
  63. package/dist/marked/marked-alert.js +54 -0
  64. package/dist/marked/marked-footnotes.d.ts +28 -0
  65. package/dist/marked/marked-footnotes.js +75 -0
  66. package/dist/marked/marked-math.d.ts +10 -0
  67. package/dist/marked/marked-math.js +60 -0
  68. package/dist/theme.d.ts +3 -3
  69. package/dist/theme.js +5 -5
  70. package/package.json +2 -14
  71. package/dist/Elements/H1.svelte +0 -23
  72. package/dist/Elements/H1.svelte.d.ts +0 -4
  73. package/dist/Elements/H2.svelte +0 -23
  74. package/dist/Elements/H2.svelte.d.ts +0 -4
  75. package/dist/Elements/H3.svelte +0 -23
  76. package/dist/Elements/H3.svelte.d.ts +0 -4
  77. package/dist/Elements/H4.svelte +0 -23
  78. package/dist/Elements/H4.svelte.d.ts +0 -4
  79. package/dist/Elements/H5.svelte +0 -23
  80. package/dist/Elements/H5.svelte.d.ts +0 -4
  81. package/dist/Elements/H6.svelte +0 -23
  82. package/dist/Elements/H6.svelte.d.ts +0 -4
  83. package/dist/Elements/element.d.ts +0 -8
  84. package/dist/Elements/element.js +0 -1
  85. package/dist/utils/alerts.d.ts +0 -12
  86. package/dist/utils/alerts.js +0 -207
  87. package/dist/utils/parse-blocks.d.ts +0 -1
  88. package/dist/utils/parse-blocks.js +0 -40
  89. package/dist/utils/parse.d.ts +0 -3
  90. package/dist/utils/parse.js +0 -131
@@ -0,0 +1,75 @@
1
+ import { lex } from './index.js';
2
+ export default function markedFootnote() {
3
+ const ensureMaps = (tokenizer) => {
4
+ if (!tokenizer.lexer.hasFootnotes) {
5
+ tokenizer.lexer.footnotes = {
6
+ refs: new Map(),
7
+ footnotes: new Map()
8
+ };
9
+ tokenizer.lexer.hasFootnotes = true;
10
+ }
11
+ return tokenizer.lexer.footnotes;
12
+ };
13
+ return {
14
+ extensions: [
15
+ {
16
+ name: 'footnote',
17
+ level: 'block',
18
+ tokenizer(src) {
19
+ const maps = ensureMaps(this);
20
+ const match = /^\[\^([^\]\n]+)\]:(?:[ \t]+|[\n]*?|$)([^\n]*?(?:\n|$)(?:\n*?[ ]{4,}[^\n]*)*)/.exec(src);
21
+ if (match) {
22
+ const [raw, label, text = ''] = match;
23
+ let content = text.split('\n').reduce((acc, curr) => {
24
+ return acc + '\n' + curr.replace(/^(?:[ ]{4}|[\t])/, '');
25
+ }, '');
26
+ const contentLastLine = content.trimEnd().split('\n').pop();
27
+ content +=
28
+ // add lines after list, blockquote, codefence, and table
29
+ contentLastLine &&
30
+ /^[ \t]*?[>\-*][ ]|[`]{3,}$|^[ \t]*?[|].+[|]$/.test(contentLastLine)
31
+ ? '\n\n'
32
+ : '';
33
+ const token = {
34
+ type: 'footnote',
35
+ raw,
36
+ label,
37
+ tokens: lex(content)
38
+ };
39
+ maps.footnotes.set(label, token);
40
+ const ref = maps.refs.get(label);
41
+ if (ref) {
42
+ ref.content = token;
43
+ }
44
+ return token;
45
+ }
46
+ }
47
+ },
48
+ {
49
+ name: 'footnoteRef',
50
+ level: 'inline',
51
+ tokenizer(src) {
52
+ const maps = ensureMaps(this);
53
+ const match = /^\[\^([^\]\n]+)\]/.exec(src);
54
+ if (match) {
55
+ const [raw, label] = match;
56
+ const footnote = maps.footnotes.get(label);
57
+ const token = {
58
+ type: 'footnoteRef',
59
+ raw,
60
+ label,
61
+ content: footnote || {
62
+ type: 'footnote',
63
+ raw,
64
+ label,
65
+ tokens: []
66
+ }
67
+ };
68
+ maps.refs.set(label, token);
69
+ return token;
70
+ }
71
+ }
72
+ }
73
+ ]
74
+ };
75
+ }
@@ -0,0 +1,10 @@
1
+ import type { TokenizerAndRendererExtension } from 'marked';
2
+ export declare function markedMath(): {
3
+ extensions: TokenizerAndRendererExtension<string, string>[];
4
+ };
5
+ export type MathToken = {
6
+ type: 'math';
7
+ isInline: boolean;
8
+ raw: string;
9
+ text: string;
10
+ };
@@ -0,0 +1,60 @@
1
+ const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n\$]))\1(?=[\s?!\.,:?!。,:]|$)/;
2
+ const inlineRuleNonStandard = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n\$]))\1/; // Non-standard, even if there are no spaces before and after $ or $$, try to parse
3
+ const blockRule = /^(\${1,2})\n((?:\\[^]|[^\\])+?)\n\1(?:\n|$)/;
4
+ export function markedMath() {
5
+ return {
6
+ extensions: [
7
+ {
8
+ name: 'inline-math',
9
+ level: 'inline',
10
+ start(src) {
11
+ let index;
12
+ let indexSrc = src;
13
+ while (indexSrc) {
14
+ index = indexSrc.indexOf('$');
15
+ if (index === -1) {
16
+ return;
17
+ }
18
+ const f = index > -1;
19
+ if (f) {
20
+ const possibleKatex = indexSrc.substring(index);
21
+ if (possibleKatex.match(inlineRuleNonStandard)) {
22
+ return index;
23
+ }
24
+ }
25
+ indexSrc = indexSrc.substring(index + 1).replace(/^\$+/, '');
26
+ }
27
+ },
28
+ tokenizer(src) {
29
+ const match = src.match(inlineRuleNonStandard);
30
+ if (match) {
31
+ console.log('match', match);
32
+ }
33
+ if (match) {
34
+ return {
35
+ type: 'math',
36
+ isInline: true,
37
+ raw: match[0],
38
+ text: match[2].trim()
39
+ };
40
+ }
41
+ }
42
+ },
43
+ {
44
+ name: 'block-math',
45
+ level: 'block',
46
+ tokenizer(src) {
47
+ const match = src.match(blockRule);
48
+ if (match) {
49
+ return {
50
+ type: 'math',
51
+ isInline: false,
52
+ raw: match[0],
53
+ text: match[2].trim()
54
+ };
55
+ }
56
+ }
57
+ }
58
+ ]
59
+ };
60
+ }
package/dist/theme.d.ts CHANGED
@@ -23,7 +23,7 @@ export declare const theme: {
23
23
  h6: {
24
24
  base: string;
25
25
  };
26
- p: {
26
+ paragraph: {
27
27
  base: string;
28
28
  };
29
29
  ul: {
@@ -142,7 +142,7 @@ export declare const shadcnTheme: {
142
142
  h6: {
143
143
  base: string;
144
144
  };
145
- p: {
145
+ paragraph: {
146
146
  base: string;
147
147
  };
148
148
  ul: {
@@ -262,7 +262,7 @@ export declare const mergeTheme: (customTheme?: Partial<Theme>, baseTheme?: "tai
262
262
  h6: {
263
263
  base: string;
264
264
  };
265
- p: {
265
+ paragraph: {
266
266
  base: string;
267
267
  };
268
268
  ul: {
package/dist/theme.js CHANGED
@@ -24,7 +24,7 @@ export const theme = {
24
24
  h6: {
25
25
  base: 'mt-6 mb-2 text-sm font-semibold'
26
26
  },
27
- p: {
27
+ paragraph: {
28
28
  base: ''
29
29
  },
30
30
  ul: {
@@ -46,7 +46,7 @@ export const theme = {
46
46
  pre: 'overflow-x-auto font-mono p-0 bg-gray-100/40'
47
47
  },
48
48
  inlineCode: {
49
- base: 'bg-gray-100 rounded px-1.5 py-0.5 font-mono text-sm'
49
+ base: 'bg-gray-100 rounded px-1.5 py-0.5 font-mono'
50
50
  },
51
51
  img: {
52
52
  base: 'group relative my-4 mx-auto w-fit block',
@@ -80,7 +80,7 @@ export const theme = {
80
80
  base: 'divide-gray-200 bg-gray-100/40 divide-y'
81
81
  },
82
82
  tr: {
83
- base: 'border-gray-200 border-b'
83
+ base: 'border-gray-200 border-b hover:bg-gray-100/50 transition-colors'
84
84
  },
85
85
  th: {
86
86
  base: 'px-4 py-3 text-left text-sm font-semibold whitespace-nowrap min-w-[200px]'
@@ -143,7 +143,7 @@ export const shadcnTheme = {
143
143
  h6: {
144
144
  base: 'mt-6 mb-2 text-sm font-semibold text-foreground'
145
145
  },
146
- p: {
146
+ paragraph: {
147
147
  base: 'text-foreground'
148
148
  },
149
149
  ul: {
@@ -165,7 +165,7 @@ export const shadcnTheme = {
165
165
  pre: 'overflow-x-auto font-mono p-0 bg-muted/40'
166
166
  },
167
167
  inlineCode: {
168
- base: 'bg-muted rounded px-1.5 py-0.5 font-mono text-sm text-foreground'
168
+ base: 'bg-muted rounded px-1.5 py-0.5 font-mono text-foreground'
169
169
  },
170
170
  img: {
171
171
  base: 'group relative my-4 mx-auto w-fit block',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-streamdown",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -68,24 +68,12 @@
68
68
  ]
69
69
  },
70
70
  "dependencies": {
71
- "@types/hast": "^3.0.4",
72
71
  "clsx": "^2.1.1",
73
- "hast": "^1.0.0",
74
- "hast-util-is-element": "^3.0.0",
75
72
  "html-url-attributes": "^3.0.1",
76
73
  "katex": "^0.16.22",
77
74
  "marked": "^16.2.1",
78
- "mdast": "^3.0.0",
79
75
  "mermaid": "^11.11.0",
80
- "rehype-github-alerts": "^4.1.1",
81
- "rehype-katex": "^7.0.1",
82
- "remark-gfm": "^4.0.1",
83
- "remark-math": "^6.0.0",
84
- "remark-parse": "^11.0.0",
85
- "remark-rehype": "^11.1.2",
86
76
  "shiki": "^3.12.2",
87
- "tailwind-merge": "^3.3.1",
88
- "unified": "^11.0.5",
89
- "unist-util-visit": "^5.0.0"
77
+ "tailwind-merge": "^3.3.1"
90
78
  }
91
79
  }
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
- import Slot from './Slot.svelte';
6
-
7
- const streamdown = useStreamdown();
8
-
9
- const { children, node, className, props }: ElementProps = $props();
10
- </script>
11
-
12
- <Slot
13
- props={{
14
- children,
15
- node,
16
- ...props
17
- }}
18
- render={streamdown.snippets.h1}
19
- >
20
- <h1 {...props} class={clsx(streamdown.theme.h1.base, className)}>
21
- {@render children()}
22
- </h1>
23
- </Slot>
@@ -1,4 +0,0 @@
1
- import type { ElementProps } from './element.js';
2
- declare const H1: import("svelte").Component<ElementProps, {}, "">;
3
- type H1 = ReturnType<typeof H1>;
4
- export default H1;
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
- import Slot from './Slot.svelte';
6
-
7
- const streamdown = useStreamdown();
8
-
9
- const { children, node, className, props }: ElementProps = $props();
10
- </script>
11
-
12
- <Slot
13
- props={{
14
- children,
15
- node,
16
- ...props
17
- }}
18
- render={streamdown.snippets.h2}
19
- >
20
- <h2 {...props} class={clsx(streamdown.theme.h2.base, className)}>
21
- {@render children()}
22
- </h2>
23
- </Slot>
@@ -1,4 +0,0 @@
1
- import type { ElementProps } from './element.js';
2
- declare const H2: import("svelte").Component<ElementProps, {}, "">;
3
- type H2 = ReturnType<typeof H2>;
4
- export default H2;
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
- import Slot from './Slot.svelte';
6
-
7
- const streamdown = useStreamdown();
8
-
9
- const { children, node, className, props }: ElementProps = $props();
10
- </script>
11
-
12
- <Slot
13
- props={{
14
- children,
15
- node,
16
- ...props
17
- }}
18
- render={streamdown.snippets.h3}
19
- >
20
- <h3 {...props} class={clsx(streamdown.theme.h3.base, className)}>
21
- {@render children()}
22
- </h3>
23
- </Slot>
@@ -1,4 +0,0 @@
1
- import type { ElementProps } from './element.js';
2
- declare const H3: import("svelte").Component<ElementProps, {}, "">;
3
- type H3 = ReturnType<typeof H3>;
4
- export default H3;
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
- import Slot from './Slot.svelte';
6
-
7
- const streamdown = useStreamdown();
8
-
9
- const { children, node, className, props }: ElementProps = $props();
10
- </script>
11
-
12
- <Slot
13
- props={{
14
- children,
15
- node,
16
- ...props
17
- }}
18
- render={streamdown.snippets.h4}
19
- >
20
- <h4 {...props} class={clsx(streamdown.theme.h4.base, className)}>
21
- {@render children()}
22
- </h4>
23
- </Slot>
@@ -1,4 +0,0 @@
1
- import type { ElementProps } from './element.js';
2
- declare const H4: import("svelte").Component<ElementProps, {}, "">;
3
- type H4 = ReturnType<typeof H4>;
4
- export default H4;
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
- import Slot from './Slot.svelte';
6
-
7
- const streamdown = useStreamdown();
8
-
9
- const { children, node, className, props }: ElementProps = $props();
10
- </script>
11
-
12
- <Slot
13
- props={{
14
- children,
15
- node,
16
- ...props
17
- }}
18
- render={streamdown.snippets.h5}
19
- >
20
- <h5 {...props} class={clsx(streamdown.theme.h5.base, className)}>
21
- {@render children()}
22
- </h5>
23
- </Slot>
@@ -1,4 +0,0 @@
1
- import type { ElementProps } from './element.js';
2
- declare const H5: import("svelte").Component<ElementProps, {}, "">;
3
- type H5 = ReturnType<typeof H5>;
4
- export default H5;
@@ -1,23 +0,0 @@
1
- <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
- import Slot from './Slot.svelte';
6
-
7
- const streamdown = useStreamdown();
8
-
9
- const { children, node, className, props }: ElementProps = $props();
10
- </script>
11
-
12
- <Slot
13
- props={{
14
- children,
15
- node,
16
- ...props
17
- }}
18
- render={streamdown.snippets.h6}
19
- >
20
- <h6 {...props} class={clsx(streamdown.theme.h6.base, className)}>
21
- {@render children()}
22
- </h6>
23
- </Slot>
@@ -1,4 +0,0 @@
1
- import type { ElementProps } from './element.js';
2
- declare const H6: import("svelte").Component<ElementProps, {}, "">;
3
- type H6 = ReturnType<typeof H6>;
4
- export default H6;
@@ -1,8 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- import type { Element as HastElement } from 'hast';
3
- export type ElementProps<T = {}> = {
4
- children: Snippet;
5
- className?: string[];
6
- node: HastElement;
7
- props: Record<string, any>;
8
- } & T & Record<string, any>;
@@ -1 +0,0 @@
1
- export {};
@@ -1,12 +0,0 @@
1
- import type { Root, ElementContent } from 'hast';
2
- export interface IAlert {
3
- keyword: string;
4
- }
5
- export type DefaultBuildType = (alertOptions: IAlert, originalChildren: ElementContent[]) => ElementContent | null;
6
- export interface IOptions {
7
- alerts: IAlert[];
8
- supportLegacy?: boolean;
9
- build?: DefaultBuildType;
10
- }
11
- export declare const rehypeGithubAlerts: (options: IOptions) => (tree: Root) => void;
12
- export declare const defaultBuild: DefaultBuildType;
@@ -1,207 +0,0 @@
1
- import { SKIP, visit } from 'unist-util-visit';
2
- import { isElement } from 'hast-util-is-element';
3
- let internalOptions;
4
- export const rehypeGithubAlerts = (options) => {
5
- const defaultOptions = {
6
- supportLegacy: false,
7
- alerts: [
8
- {
9
- keyword: 'NOTE'
10
- },
11
- {
12
- keyword: 'IMPORTANT'
13
- },
14
- {
15
- keyword: 'WARNING'
16
- },
17
- {
18
- keyword: 'TIP'
19
- },
20
- {
21
- keyword: 'CAUTION'
22
- }
23
- ]
24
- };
25
- internalOptions = Object.assign({}, defaultOptions, options);
26
- return (tree) => {
27
- visit(tree, 'element', (node, index, parent) => {
28
- create(node, index, parent);
29
- });
30
- };
31
- };
32
- const create = (node, index, parent) => {
33
- // check if main element is a blockquote
34
- if (node.tagName !== 'blockquote') {
35
- return [SKIP];
36
- }
37
- // make sure the blockquote is not empty
38
- if (node.children.length < 1) {
39
- return [SKIP];
40
- }
41
- // find the first paragraph inside of the blockquote
42
- const firstParagraph = node.children.find((child) => {
43
- return child.type === 'element' && child.tagName === 'p';
44
- });
45
- // typescript type guard
46
- // make sure the first paragraph is a valid element
47
- if (!isElement(firstParagraph)) {
48
- return [SKIP];
49
- }
50
- // try to find the alert type
51
- const headerData = extractHeaderData(firstParagraph);
52
- // typescript type guard
53
- if (headerData === null) {
54
- return [SKIP];
55
- }
56
- // if the first line contains more than the type
57
- // drop out of rendering as alert, this is what
58
- // GitHub does (as of Mar. 2024)
59
- if (headerData.rest.trim() !== '') {
60
- if (!headerData.rest.startsWith('\n') && !headerData.rest.startsWith('\r')) {
61
- return [SKIP];
62
- }
63
- }
64
- // try to find options matching the alert keyword
65
- const alertOptions = getAlertOptions(headerData.alertType);
66
- if (alertOptions === null) {
67
- return [SKIP];
68
- }
69
- // make sure we have parent element and an index
70
- // or we won't be able to replace the blockquote
71
- // with the new alert element
72
- if (!parent || typeof index !== 'number') {
73
- return [SKIP];
74
- }
75
- // use a build to convert the blockquote into an alert
76
- const build = internalOptions.build ?? defaultBuild;
77
- const alertBodyChildren = [];
78
- // for alerts the blockquote first element is always
79
- // a paragraph but it can have more children than just
80
- // the alert type text node
81
- const remainingFirstParagraphChildren = firstParagraph.children.slice(1, firstParagraph.children.length);
82
- const newFirstParagraphChildren = [];
83
- // remove the first line break from rest if there is one
84
- const rest = headerData.rest.replace(/^(\r\n|\r|\n)/, '');
85
- // if the rest is empty and the first paragraph has no children
86
- // this is a special github case (as of Mar. 2024)
87
- // where the alert is only the type (no alert body)
88
- // in this case github keeps the original blockquote
89
- if (rest === '' && remainingFirstParagraphChildren.length === 0 && node.children.length < 4) {
90
- return [SKIP];
91
- }
92
- if (remainingFirstParagraphChildren.length > 0) {
93
- // if the alert type has a hard line break we remove it
94
- // to not start the alert with a blank line
95
- // meaning we start the slice at 2 to not take
96
- // the br element and new line text nodes
97
- if (remainingFirstParagraphChildren[0].type === 'element' &&
98
- remainingFirstParagraphChildren[0].tagName === 'br') {
99
- const remainingChildrenWithoutLineBreak = remainingFirstParagraphChildren.slice(2, firstParagraph.children.length);
100
- newFirstParagraphChildren.push(...remainingChildrenWithoutLineBreak);
101
- }
102
- else {
103
- // if the first line of the blockquote has no hard line break
104
- // after the alert type but some text, then both the type
105
- // and the text will be in a single text node
106
- // headerData rest contains the remaining text without the alert type
107
- if (rest !== '') {
108
- const restAsTextNode = {
109
- type: 'text',
110
- value: rest
111
- };
112
- remainingFirstParagraphChildren.unshift(restAsTextNode);
113
- }
114
- // if no hard line break (br) take all the remaining
115
- // and add them to new paragraph to mimic the initial structure
116
- newFirstParagraphChildren.push(...remainingFirstParagraphChildren);
117
- }
118
- }
119
- else {
120
- if (rest !== '') {
121
- const restAsTextNode = {
122
- type: 'text',
123
- value: rest
124
- };
125
- newFirstParagraphChildren.push(restAsTextNode);
126
- }
127
- }
128
- if (newFirstParagraphChildren.length > 0) {
129
- const paragraphElement = {
130
- type: 'element',
131
- tagName: 'p',
132
- properties: {},
133
- children: newFirstParagraphChildren
134
- };
135
- alertBodyChildren.push(paragraphElement);
136
- }
137
- // outside of the first paragraph there may also be children
138
- // we add them too back into the alert body
139
- if (node.children.length > 2) {
140
- alertBodyChildren.push(...node.children.slice(2, node.children.length));
141
- }
142
- const alertElement = build(alertOptions, alertBodyChildren);
143
- // replace the original blockquote with the
144
- // new alert element and its children
145
- if (alertElement !== null) {
146
- parent.children[index] = alertElement;
147
- }
148
- return [SKIP];
149
- };
150
- export const defaultBuild = (alertOptions, originalChildren) => {
151
- // Filter out any title paragraphs that might contain icons or titles
152
- const filteredChildren = originalChildren.filter((child) => {
153
- if (child.type === 'element' && child.tagName === 'p') {
154
- const className = child.properties?.className;
155
- // Remove paragraphs with markdown-alert-title class
156
- if (className?.includes('markdown-alert-title')) {
157
- return false;
158
- }
159
- }
160
- return true;
161
- });
162
- const alert = {
163
- type: 'element',
164
- tagName: 'alert',
165
- properties: {
166
- className: ['markdown-alert', `markdown-alert-${alertOptions.keyword.toLowerCase()}`]
167
- },
168
- children: filteredChildren
169
- };
170
- return alert;
171
- };
172
- const extractHeaderData = (paragraph) => {
173
- const header = paragraph.children[0];
174
- let alertType;
175
- let rest = '';
176
- if (internalOptions.supportLegacy) {
177
- if (header.type === 'element' && header.tagName === 'strong') {
178
- if (header.children[0].type === 'text') {
179
- alertType = header.children[0].value;
180
- }
181
- }
182
- }
183
- if (header.type === 'text') {
184
- const match = /\[!(.*?)\]/.exec(header.value);
185
- if (!match?.input) {
186
- return null;
187
- }
188
- if (match.input.length > match[0].length) {
189
- // if in markdown there are no two spaces at the end
190
- // then in html there will be no line break
191
- // this means in the first line there will be more
192
- // content than just the alert type
193
- rest = match.input.replace(match[0], '');
194
- }
195
- alertType = match[1];
196
- }
197
- if (typeof alertType === 'undefined') {
198
- return null;
199
- }
200
- return { alertType, rest };
201
- };
202
- const getAlertOptions = (alertType) => {
203
- const alertOptions = internalOptions.alerts.find((alert) => {
204
- return alertType.toUpperCase() === alert.keyword.toUpperCase();
205
- });
206
- return alertOptions ?? null;
207
- };
@@ -1 +0,0 @@
1
- export declare const parseMarkdownIntoBlocks: (markdown: string) => string[];