svelte-streamdown 1.0.8 → 2.0.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 (83) hide show
  1. package/README.md +155 -140
  2. package/dist/Block.svelte +17 -41
  3. package/dist/Elements/Alert.svelte +1 -2
  4. package/dist/Elements/Code.svelte +3 -5
  5. package/dist/Elements/Code.svelte.d.ts +0 -2
  6. package/dist/Elements/Element.svelte +170 -42
  7. package/dist/Elements/FootnoteRef.svelte +126 -0
  8. package/dist/Elements/FootnoteRef.svelte.d.ts +7 -0
  9. package/dist/Elements/Image.svelte +4 -4
  10. package/dist/Elements/{A.svelte → Link.svelte} +4 -4
  11. package/dist/Elements/{A.svelte.d.ts → Link.svelte.d.ts} +3 -3
  12. package/dist/Elements/Math.svelte +13 -24
  13. package/dist/Elements/Math.svelte.d.ts +0 -2
  14. package/dist/Elements/Mermaid.svelte +105 -115
  15. package/dist/Elements/Mermaid.svelte.d.ts +0 -2
  16. package/dist/Elements/Table.svelte +1 -1
  17. package/dist/Elements/index.d.ts +5 -24
  18. package/dist/Elements/index.js +5 -24
  19. package/dist/Streamdown.d.ts +52 -10
  20. package/dist/Streamdown.js +19 -1
  21. package/dist/Streamdown.svelte +2 -34
  22. package/dist/Streamdown.svelte.d.ts +1 -14
  23. package/dist/marked/index.d.ts +6 -10
  24. package/dist/marked/index.js +29 -17
  25. package/dist/marked/marked-alert.d.ts +2 -2
  26. package/dist/marked/marked-alert.js +11 -24
  27. package/dist/marked/marked-footnotes.d.ts +1 -0
  28. package/dist/marked/marked-footnotes.js +27 -8
  29. package/dist/marked/marked-list.d.ts +36 -0
  30. package/dist/marked/marked-list.js +232 -0
  31. package/dist/marked/marked-math.js +1 -4
  32. package/dist/marked/marked-subsup.d.ts +28 -0
  33. package/dist/marked/marked-subsup.js +45 -0
  34. package/dist/marked/marked-table.d.ts +59 -0
  35. package/dist/marked/marked-table.js +495 -0
  36. package/dist/theme.d.ts +54 -30
  37. package/dist/theme.js +51 -35
  38. package/dist/utils/panzoom.svelte.d.ts +17 -18
  39. package/dist/utils/panzoom.svelte.js +0 -2
  40. package/dist/utils/parse-incomplete-markdown.js +157 -0
  41. package/dist/utils/useClickOutside.svelte.d.ts +8 -0
  42. package/dist/utils/useClickOutside.svelte.js +41 -0
  43. package/dist/utils/useKeyDown.svelte.d.ts +5 -0
  44. package/dist/utils/useKeyDown.svelte.js +23 -0
  45. package/package.json +2 -1
  46. package/dist/Elements/Blockquote.svelte +0 -28
  47. package/dist/Elements/Blockquote.svelte.d.ts +0 -9
  48. package/dist/Elements/Del.svelte +0 -28
  49. package/dist/Elements/Del.svelte.d.ts +0 -9
  50. package/dist/Elements/Em.svelte +0 -28
  51. package/dist/Elements/Em.svelte.d.ts +0 -9
  52. package/dist/Elements/Heading.svelte +0 -25
  53. package/dist/Elements/Heading.svelte.d.ts +0 -9
  54. package/dist/Elements/Hr.svelte +0 -26
  55. package/dist/Elements/Hr.svelte.d.ts +0 -9
  56. package/dist/Elements/InlineCode.svelte +0 -28
  57. package/dist/Elements/InlineCode.svelte.d.ts +0 -9
  58. package/dist/Elements/Li.svelte +0 -28
  59. package/dist/Elements/Li.svelte.d.ts +0 -9
  60. package/dist/Elements/Ol.svelte +0 -30
  61. package/dist/Elements/Ol.svelte.d.ts +0 -9
  62. package/dist/Elements/P.svelte +0 -28
  63. package/dist/Elements/P.svelte.d.ts +0 -9
  64. package/dist/Elements/Strong.svelte +0 -28
  65. package/dist/Elements/Strong.svelte.d.ts +0 -9
  66. package/dist/Elements/Sub.svelte +0 -27
  67. package/dist/Elements/Sub.svelte.d.ts +0 -8
  68. package/dist/Elements/Sup.svelte +0 -28
  69. package/dist/Elements/Sup.svelte.d.ts +0 -8
  70. package/dist/Elements/Tbody.svelte +0 -24
  71. package/dist/Elements/Tbody.svelte.d.ts +0 -7
  72. package/dist/Elements/Td.svelte +0 -28
  73. package/dist/Elements/Td.svelte.d.ts +0 -9
  74. package/dist/Elements/Th.svelte +0 -28
  75. package/dist/Elements/Th.svelte.d.ts +0 -9
  76. package/dist/Elements/Thead.svelte +0 -27
  77. package/dist/Elements/Thead.svelte.d.ts +0 -9
  78. package/dist/Elements/Tr.svelte +0 -27
  79. package/dist/Elements/Tr.svelte.d.ts +0 -9
  80. package/dist/Elements/Ul.svelte +0 -28
  81. package/dist/Elements/Ul.svelte.d.ts +0 -9
  82. /package/dist/{hightlighter.svelte.d.ts → utils/hightlighter.svelte.d.ts} +0 -0
  83. /package/dist/{hightlighter.svelte.js → utils/hightlighter.svelte.js} +0 -0
@@ -1,7 +1,10 @@
1
1
  import { Lexer } from 'marked';
2
2
  const variants = ['note', 'tip', 'important', 'warning', 'caution'];
3
+ // export function createSyntaxPattern(type: variantType): string {
4
+ // return `^(?:\\[!${type.toUpperCase()}])\\s*?\n*`;
5
+ // }
3
6
  export function createSyntaxPattern(type) {
4
- return `^(?:\\[!${type.toUpperCase()}])\\s*?\n*`;
7
+ return `^\\s*\\[!${type.toUpperCase()}\\]\\s+`;
5
8
  }
6
9
  export default function markedAlert() {
7
10
  const defaultLexer = new Lexer({ gfm: true });
@@ -15,7 +18,7 @@ export default function markedAlert() {
15
18
  const cap = defaultTokenizer.rules.block.blockquote.exec(src);
16
19
  if (cap) {
17
20
  const blockquoteToken = defaultTokenizer.blockquote(src);
18
- blockquoteToken && processAlertToken(blockquoteToken);
21
+ blockquoteToken && processAlertToken(blockquoteToken, this.lexer.options.tokenizer);
19
22
  return blockquoteToken;
20
23
  }
21
24
  }
@@ -23,32 +26,16 @@ export default function markedAlert() {
23
26
  ]
24
27
  };
25
28
  }
26
- export function processAlertToken(token) {
29
+ export function processAlertToken(token, tokenizer) {
27
30
  const matchedVariant = variants.find((type) => new RegExp(createSyntaxPattern(type)).test(('text' in token && token.text) || ''));
28
31
  if (!matchedVariant)
29
32
  return;
30
- const typeRegexp = new RegExp(createSyntaxPattern(matchedVariant));
31
- // Transform the token into an alert token
33
+ const tokens = token.tokens.map((token) => {
34
+ return tokenizer.lexer.blockTokens(token.raw.replaceAll(`[!${matchedVariant.toUpperCase()}]`, '').trim(), [])[0];
35
+ });
32
36
  Object.assign(token, {
33
37
  type: 'alert',
34
- variant: matchedVariant
38
+ variant: matchedVariant,
39
+ tokens
35
40
  });
36
- const firstLine = ('tokens' in token && token.tokens?.[0]);
37
- const firstLineText = firstLine.raw?.replace(typeRegexp, '').trim();
38
- firstLine.text = firstLineText;
39
- if (firstLineText) {
40
- const patternToken = firstLine.tokens[0];
41
- if (patternToken) {
42
- Object.assign(patternToken, {
43
- raw: patternToken.raw.replace(typeRegexp, ''),
44
- text: patternToken.text.replace(typeRegexp, '')
45
- });
46
- }
47
- if (firstLine.tokens[1]?.type === 'br') {
48
- firstLine.tokens.splice(1, 1);
49
- }
50
- }
51
- else if ('tokens' in token && token.tokens) {
52
- token.tokens?.shift();
53
- }
54
41
  }
@@ -15,6 +15,7 @@ export type Footnote = {
15
15
  raw: string;
16
16
  label: string;
17
17
  tokens: StreamdownToken[];
18
+ lines: string[];
18
19
  };
19
20
  /**
20
21
  * Represents a reference to a footnote.
@@ -1,14 +1,30 @@
1
1
  import { lex } from './index.js';
2
+ import { StreamdownContext } from '../Streamdown.js';
3
+ import { getContext } from 'svelte';
4
+ const safeGetContext = () => {
5
+ try {
6
+ return getContext('streamdown');
7
+ }
8
+ catch (e) {
9
+ return null;
10
+ }
11
+ };
2
12
  export default function markedFootnote() {
3
13
  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;
14
+ const streamdown = safeGetContext();
15
+ if (!streamdown) {
16
+ if (!tokenizer.lexer.hasFootnotes) {
17
+ tokenizer.lexer.footnotes = {
18
+ refs: new Map(),
19
+ footnotes: new Map()
20
+ };
21
+ tokenizer.lexer.hasFootnotes = true;
22
+ }
23
+ return tokenizer.lexer.footnotes;
24
+ }
25
+ else {
26
+ return streamdown.footnotes;
10
27
  }
11
- return tokenizer.lexer.footnotes;
12
28
  };
13
29
  return {
14
30
  extensions: [
@@ -30,11 +46,13 @@ export default function markedFootnote() {
30
46
  /^[ \t]*?[>\-*][ ]|[`]{3,}$|^[ \t]*?[|].+[|]$/.test(contentLastLine)
31
47
  ? '\n\n'
32
48
  : '';
49
+ const lines = content.split('\n');
33
50
  const token = {
34
51
  type: 'footnote',
35
52
  raw,
36
53
  label,
37
- tokens: lex(content)
54
+ lines,
55
+ tokens: []
38
56
  };
39
57
  maps.footnotes.set(label, token);
40
58
  const ref = maps.refs.get(label);
@@ -62,6 +80,7 @@ export default function markedFootnote() {
62
80
  type: 'footnote',
63
81
  raw,
64
82
  label,
83
+ lines: [],
65
84
  tokens: []
66
85
  }
67
86
  };
@@ -0,0 +1,36 @@
1
+ import type { TokenizerExtensionFunction } from 'marked';
2
+ export declare function letterToInt(letter: string): number;
3
+ export declare function romanToInt(roman: string): number;
4
+ export declare const romanUpper = "(?:C|XC|L?X{0,3}(?:IX|IV|V?I{0,3}))";
5
+ export declare const romanLower = "(?:c|xc|l?x{0,3}(?:ix|iv|v?i{0,3}))";
6
+ export declare const bulletPattern = "(?:[*+-]|(?:\\d{1,9}|[a-zA-Z]|(?:C|XC|L?X{0,3}(?:IX|IV|V?I{0,3}))|(?:c|xc|l?x{0,3}(?:ix|iv|v?i{0,3})))[.)])";
7
+ export declare const rule = "^( {0,3}(?:[*+-]|(?:\\d{1,9}|[a-zA-Z]|(?:C|XC|L?X{0,3}(?:IX|IV|V?I{0,3}))|(?:c|xc|l?x{0,3}(?:ix|iv|v?i{0,3})))[.)]))([ \\t][^\\n]+?)?(?:\\n|$)";
8
+ export declare function markedList(): {
9
+ extensions: Array<{
10
+ name: string;
11
+ level: 'block' | 'inline';
12
+ tokenizer: TokenizerExtensionFunction;
13
+ }>;
14
+ };
15
+ export interface ListToken {
16
+ type: 'list';
17
+ raw: string;
18
+ ordered: boolean;
19
+ listType: 'decimal' | 'lower-alpha' | 'upper-alpha' | 'lower-roman' | 'upper-roman' | null;
20
+ loose: boolean;
21
+ tokens: ListItemToken[];
22
+ }
23
+ /**
24
+ * Token representing an item in an extended list.
25
+ */
26
+ export interface ListItemToken {
27
+ type: 'list_item';
28
+ raw: string;
29
+ task: boolean;
30
+ checked: boolean;
31
+ loose: boolean;
32
+ text: string;
33
+ value: number | null;
34
+ skipped: boolean;
35
+ tokens: unknown[];
36
+ }
@@ -0,0 +1,232 @@
1
+ export function letterToInt(letter) {
2
+ return letter.toLowerCase().charCodeAt(0) - 96;
3
+ }
4
+ const romanMap = {
5
+ I: 1,
6
+ V: 5,
7
+ X: 10,
8
+ L: 50,
9
+ C: 100,
10
+ D: 500,
11
+ M: 1000
12
+ };
13
+ export function romanToInt(roman) {
14
+ roman = roman.toUpperCase();
15
+ let total = 0;
16
+ for (let i = 0; i < roman.length; i++) {
17
+ const current = romanMap[roman[i]];
18
+ const next = romanMap[roman[i + 1]];
19
+ total += next && current < next ? -current : current;
20
+ }
21
+ return total;
22
+ }
23
+ // Regular expression patterns for list detection
24
+ export const romanUpper = '(?:C|XC|L?X{0,3}(?:IX|IV|V?I{0,3}))';
25
+ export const romanLower = '(?:c|xc|l?x{0,3}(?:ix|iv|v?i{0,3}))';
26
+ // Fixed regex pattern - carefully balanced parentheses
27
+ export const bulletPattern = `(?:[*+-]|(?:\\d{1,9}|[a-zA-Z]|${romanUpper}|${romanLower})[.)])`;
28
+ export const rule = `^( {0,3}${bulletPattern})([ \\t][^\\n]+?)?(?:\\n|$)`;
29
+ function finalizeList(list, lexer) {
30
+ if (list.tokens.length === 0)
31
+ return;
32
+ // Trim trailing newline from last item
33
+ const lastItem = list.tokens[list.tokens.length - 1];
34
+ lastItem.raw = lastItem.raw.trimEnd();
35
+ lastItem.text = lastItem.text.trimEnd();
36
+ list.raw = list.raw.trimEnd();
37
+ // Handle child tokens
38
+ for (const item of list.tokens) {
39
+ lexer.state.top = false;
40
+ item.tokens = lexer.blockTokens(item.text, []);
41
+ }
42
+ // Mark list as loose if needed
43
+ if (list.loose) {
44
+ for (const item of list.tokens) {
45
+ item.loose = true;
46
+ }
47
+ }
48
+ }
49
+ function escapeForRegex(s) {
50
+ return s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
51
+ }
52
+ export function markedList() {
53
+ return {
54
+ extensions: [
55
+ {
56
+ name: 'list',
57
+ level: 'block',
58
+ tokenizer(src) {
59
+ let cap = new RegExp(rule).exec(src);
60
+ if (!cap)
61
+ return null;
62
+ const bullet = cap[1].trim();
63
+ const isOrdered = bullet !== '*' && bullet !== '-' && bullet !== '+';
64
+ let bull;
65
+ let type = '';
66
+ let expectedValue = null;
67
+ // Detect list type (Roman, alphabetic, numeric)
68
+ if (isOrdered) {
69
+ if (bullet.match(new RegExp(`^${romanUpper}[.)]$`))) {
70
+ type = 'upper-roman';
71
+ bull = `${romanUpper}\\${bullet.slice(-1)}`;
72
+ }
73
+ else if (bullet.match(new RegExp(`^${romanLower}[.)]$`))) {
74
+ type = 'lower-roman';
75
+ bull = `${romanLower}\\${bullet.slice(-1)}`;
76
+ }
77
+ else if (bullet.match(/^[a-z][.)]$/)) {
78
+ type = 'lower-alpha';
79
+ bull = `[a-z]\\${bullet.slice(-1)}`;
80
+ }
81
+ else if (bullet.match(/^[A-Z][.)]$/)) {
82
+ type = 'upper-alpha';
83
+ bull = `[A-Z]\\${bullet.slice(-1)}`;
84
+ }
85
+ else {
86
+ type = 'decimal';
87
+ bull = `\\d{1,9}\\${bullet.slice(-1)}`;
88
+ }
89
+ }
90
+ else {
91
+ bull = this.lexer.options.pedantic ? bullet : '[*+-]';
92
+ bull = this.lexer.options.pedantic ? escapeForRegex(bullet) : '[*+-]';
93
+ }
94
+ const list = {
95
+ type: 'list',
96
+ raw: '',
97
+ ordered: isOrdered,
98
+ listType: isOrdered ? type : null,
99
+ loose: false,
100
+ tokens: []
101
+ };
102
+ // Get next list item
103
+ const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
104
+ let endsWithBlankLine = false;
105
+ // Check if current bullet point can start a new List Item
106
+ while (src) {
107
+ let raw = '';
108
+ let itemContents = '';
109
+ let endEarly = false;
110
+ if (!(cap = itemRegex.exec(src)))
111
+ break;
112
+ raw = cap[0];
113
+ const bullet = cap[1].trim();
114
+ src = src.substring(raw.length);
115
+ const line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
116
+ const nextLine = src.split('\n', 1)[0];
117
+ const blankLine = !line.trim();
118
+ let indent = 0;
119
+ if (this.lexer.options.pedantic) {
120
+ indent = 2;
121
+ itemContents = line.trimStart();
122
+ }
123
+ else if (blankLine) {
124
+ indent = cap[1].length + 1;
125
+ }
126
+ else {
127
+ indent = cap[2].search(/[^ ]/); // Find first non-space char
128
+ indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
129
+ itemContents = line.slice(indent);
130
+ indent += cap[1].length;
131
+ }
132
+ if (blankLine && /^[ \t]*$/.test(nextLine)) {
133
+ // Items begin with at most one blank line
134
+ raw += nextLine + '\n';
135
+ src = src.substring(nextLine.length + 1);
136
+ endEarly = true;
137
+ }
138
+ if (!endEarly) {
139
+ const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|(?:\\d{1,9}|[a-zA-Z]|${romanUpper}|${romanLower})[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
140
+ const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
141
+ const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
142
+ const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
143
+ const htmlBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}<[a-z].*>`, 'i');
144
+ // Check if following lines should be included in List Item
145
+ while (src) {
146
+ const rawLine = src.split('\n', 1)[0];
147
+ const nextLineWithoutTabs = rawLine.replace(/\t/g, ' ');
148
+ if (fencesBeginRegex.test(nextLineWithoutTabs) ||
149
+ headingBeginRegex.test(nextLineWithoutTabs) ||
150
+ htmlBeginRegex.test(nextLineWithoutTabs) ||
151
+ nextBulletRegex.test(nextLineWithoutTabs) ||
152
+ hrRegex.test(nextLineWithoutTabs))
153
+ break;
154
+ if (nextLineWithoutTabs.search(/[^ ]/) >= indent || !nextLineWithoutTabs.trim()) {
155
+ itemContents += '\n' + nextLineWithoutTabs.slice(indent);
156
+ }
157
+ else {
158
+ itemContents += '\n' + nextLineWithoutTabs;
159
+ }
160
+ raw += rawLine + '\n';
161
+ src = src.substring(rawLine.length + 1);
162
+ }
163
+ }
164
+ if (!list.loose) {
165
+ // If the previous item ended with a blank line, the list is loose
166
+ if (endsWithBlankLine) {
167
+ list.loose = true;
168
+ }
169
+ else if (/\n[ \t]*\n[ \t]*$/.test(raw)) {
170
+ endsWithBlankLine = true;
171
+ }
172
+ }
173
+ let isTask = null;
174
+ let isChecked = false;
175
+ // Check for task list items
176
+ if (this.lexer.options.gfm) {
177
+ isTask = /^\[[ xX]] /.exec(itemContents);
178
+ if (isTask) {
179
+ isChecked = isTask[0] !== '[ ] ';
180
+ itemContents = itemContents.replace(/^\[[ xX]] +/, '');
181
+ }
182
+ }
183
+ let value = null;
184
+ if (!isOrdered) {
185
+ // Do nothing for unordered lists
186
+ }
187
+ else if (type === 'decimal') {
188
+ value = parseInt(bullet.slice(0, -1), 10);
189
+ }
190
+ else if (type === 'lower-alpha' || type === 'upper-alpha') {
191
+ value = letterToInt(bullet.slice(0, -1));
192
+ }
193
+ else if (type === 'lower-roman' || type === 'upper-roman') {
194
+ value = romanToInt(bullet.slice(0, -1));
195
+ }
196
+ // Handle expectedValue initialization and validation
197
+ let skipped = false;
198
+ if (isOrdered) {
199
+ if (expectedValue === null) {
200
+ // First item: set expectedValue to this item's value (or 1 if parsing failed)
201
+ expectedValue = value ?? 1;
202
+ }
203
+ else {
204
+ // Subsequent items: check if value matches expected
205
+ skipped = value !== null && value !== expectedValue;
206
+ // Increment expectedValue for next item
207
+ expectedValue += 1;
208
+ }
209
+ }
210
+ list.tokens.push({
211
+ type: 'list_item',
212
+ raw,
213
+ task: !!isTask,
214
+ checked: isChecked,
215
+ loose: false,
216
+ text: itemContents,
217
+ value,
218
+ skipped,
219
+ tokens: []
220
+ });
221
+ list.raw += raw;
222
+ }
223
+ if (list.tokens.length === 0)
224
+ return null;
225
+ // Finalize the list
226
+ finalizeList(list, this.lexer);
227
+ return list;
228
+ }
229
+ }
230
+ ]
231
+ };
232
+ }
@@ -1,6 +1,6 @@
1
1
  const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n\$]))\1(?=[\s?!\.,:?!。,:]|$)/;
2
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|$)/;
3
+ const blockRule = /^(\${1,2})\n((?:\\[\s\S]|[^\\])+?)\n\1(?:\n|$)/;
4
4
  export function markedMath() {
5
5
  return {
6
6
  extensions: [
@@ -27,9 +27,6 @@ export function markedMath() {
27
27
  },
28
28
  tokenizer(src) {
29
29
  const match = src.match(inlineRuleNonStandard);
30
- if (match) {
31
- console.log('match', match);
32
- }
33
30
  if (match) {
34
31
  return {
35
32
  type: 'math',
@@ -0,0 +1,28 @@
1
+ import type { TokenizerExtensionFunction } from 'marked';
2
+ export default function markedSubSup(): {
3
+ extensions: {
4
+ name: string;
5
+ level: 'inline';
6
+ tokenizer: TokenizerExtensionFunction;
7
+ start?: (src: string) => number | undefined;
8
+ }[];
9
+ };
10
+ /**
11
+ * Represents a subscript token.
12
+ */
13
+ export type SubToken = {
14
+ type: 'sub';
15
+ raw: string;
16
+ text: string;
17
+ tokens: any[];
18
+ };
19
+ /**
20
+ * Represents a superscript token.
21
+ */
22
+ export type SupToken = {
23
+ type: 'sup';
24
+ raw: string;
25
+ text: string;
26
+ tokens: any[];
27
+ };
28
+ export type SubSupToken = SubToken | SupToken;
@@ -0,0 +1,45 @@
1
+ const subRule = /^~([^~\s](?:[^~]*[^~\s])?)~/; // ~text~
2
+ const supRule = /^\^([^\^\s](?:[^\^]*[^\^\s])?)\^/; // ^text^
3
+ export default function markedSubSup() {
4
+ return {
5
+ extensions: [
6
+ {
7
+ name: 'sub',
8
+ level: 'inline',
9
+ start(src) {
10
+ const i = src.indexOf('~');
11
+ return i === -1 ? undefined : i;
12
+ },
13
+ tokenizer(src) {
14
+ const match = src.match(subRule);
15
+ if (match) {
16
+ return {
17
+ type: 'sub',
18
+ raw: match[0],
19
+ text: match[1],
20
+ tokens: this.lexer.inlineTokens(match[1])
21
+ };
22
+ }
23
+ }
24
+ },
25
+ {
26
+ name: 'sup',
27
+ level: 'inline',
28
+ start(src) {
29
+ return src.indexOf('^');
30
+ },
31
+ tokenizer(src) {
32
+ const match = src.match(supRule);
33
+ if (match) {
34
+ return {
35
+ type: 'sup',
36
+ raw: match[0],
37
+ text: match[1],
38
+ tokens: this.lexer.inlineTokens(match[1])
39
+ };
40
+ }
41
+ }
42
+ }
43
+ ]
44
+ };
45
+ }
@@ -0,0 +1,59 @@
1
+ import type { MarkedExtension } from 'marked';
2
+ export interface SpanTableOptions {
3
+ useTheadTbody?: boolean;
4
+ useTfoot?: boolean;
5
+ detectFooter?: boolean;
6
+ maxColspan?: number | null;
7
+ handleComplexSpans?: boolean;
8
+ }
9
+ interface BaseCell {
10
+ rowspan: number;
11
+ colspan: number;
12
+ text: string;
13
+ position?: number;
14
+ tokens?: unknown[];
15
+ rowSpanTarget?: BaseCell;
16
+ complexRowSpan?: boolean;
17
+ relatedCell?: BaseCell;
18
+ align?: string | null;
19
+ }
20
+ export interface TH extends BaseCell {
21
+ type: 'th';
22
+ }
23
+ export interface TD extends BaseCell {
24
+ type: 'td';
25
+ }
26
+ export interface THeadRow {
27
+ type: 'tr';
28
+ tokens: TH[];
29
+ }
30
+ export interface TRow {
31
+ type: 'tr';
32
+ tokens: TD[];
33
+ }
34
+ export interface THead {
35
+ type: 'thead';
36
+ tokens: THeadRow[];
37
+ }
38
+ export interface TBody {
39
+ type: 'tbody';
40
+ tokens: TRow[];
41
+ }
42
+ export interface TFoot {
43
+ type: 'tfoot';
44
+ tokens: TRow[];
45
+ }
46
+ export type TableSection = THead | TBody | TFoot;
47
+ export interface TableToken {
48
+ type: 'table';
49
+ tokens: TableSection[];
50
+ raw: string;
51
+ }
52
+ interface WorkingCell extends BaseCell {
53
+ }
54
+ type WorkingRow = WorkingCell[];
55
+ export declare const DEFAULT_OPTIONS: Required<SpanTableOptions>;
56
+ export declare const getTableCell: (text: string, cell: BaseCell, type: "th" | "td", align: string | null) => string;
57
+ export declare const splitCells: (tableRow: string, count: number | null, prevRow?: WorkingRow | null, maxColspan?: number | null) => WorkingRow;
58
+ export declare function markedTable(options?: SpanTableOptions): MarkedExtension;
59
+ export {};