@humanspeak/svelte-markdown 1.0.0 โ 1.0.2
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/LICENSE +1 -1
- package/README.md +224 -8
- package/dist/Parser.svelte +1 -1
- package/dist/SvelteMarkdown.svelte +23 -8
- package/dist/index.d.ts +2 -0
- package/dist/types.d.ts +24 -1
- package/package.json +9 -6
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -20,11 +20,12 @@ A powerful, customizable markdown renderer for Svelte with TypeScript support. B
|
|
|
20
20
|
- ๐ Full markdown syntax support through Marked
|
|
21
21
|
- ๐ช Complete TypeScript support with strict typing
|
|
22
22
|
- ๐ Svelte 5 runes compatibility
|
|
23
|
+
- โ๏ธ Inline snippet overrides โ customize renderers without separate files
|
|
23
24
|
- ๐จ Customizable component rendering system
|
|
24
25
|
- โฟ WCAG 2.1 accessibility compliance
|
|
25
26
|
- ๐ฏ GitHub-style slug generation for headers
|
|
26
27
|
- ๐งช Comprehensive test coverage (vitest and playwright)
|
|
27
|
-
-
|
|
28
|
+
- ๐งฉ First-class marked extensions support via `extensions` prop (e.g., KaTeX math, alerts)
|
|
28
29
|
- โก Intelligent token caching (50-200x faster re-renders)
|
|
29
30
|
- ๐ผ๏ธ Smart image lazy loading with fade-in animation
|
|
30
31
|
|
|
@@ -71,7 +72,8 @@ import type {
|
|
|
71
72
|
Renderers,
|
|
72
73
|
Token,
|
|
73
74
|
TokensList,
|
|
74
|
-
SvelteMarkdownOptions
|
|
75
|
+
SvelteMarkdownOptions,
|
|
76
|
+
MarkedExtension
|
|
75
77
|
} from '@humanspeak/svelte-markdown'
|
|
76
78
|
```
|
|
77
79
|
|
|
@@ -259,6 +261,219 @@ Here's a complete example of a custom renderer with TypeScript support:
|
|
|
259
261
|
|
|
260
262
|
If you would like to extend other renderers please take a look inside the [renderers folder](https://github.com/humanspeak/svelte-markdown/tree/main/src/lib/renderers) for the default implentation of them. If you would like feature additions please feel free to open an issue!
|
|
261
263
|
|
|
264
|
+
## Snippet Overrides (Svelte 5)
|
|
265
|
+
|
|
266
|
+
For simple tweaks โ adding a class, changing an attribute, wrapping in a div โ you can override renderers inline with Svelte 5 snippets instead of creating separate component files:
|
|
267
|
+
|
|
268
|
+
```svelte
|
|
269
|
+
<script lang="ts">
|
|
270
|
+
import SvelteMarkdown from '@humanspeak/svelte-markdown'
|
|
271
|
+
|
|
272
|
+
const source = '# Hello\n\nA paragraph with [a link](https://example.com).'
|
|
273
|
+
</script>
|
|
274
|
+
|
|
275
|
+
<SvelteMarkdown {source}>
|
|
276
|
+
{#snippet paragraph({ children })}
|
|
277
|
+
<p class="prose">{@render children?.()}</p>
|
|
278
|
+
{/snippet}
|
|
279
|
+
|
|
280
|
+
{#snippet heading({ depth, children })}
|
|
281
|
+
{#if depth === 1}
|
|
282
|
+
<h1 class="title">{@render children?.()}</h1>
|
|
283
|
+
{:else}
|
|
284
|
+
<h2>{@render children?.()}</h2>
|
|
285
|
+
{/if}
|
|
286
|
+
{/snippet}
|
|
287
|
+
|
|
288
|
+
{#snippet link({ href, title, children })}
|
|
289
|
+
<a {href} {title} target="_blank" rel="noopener noreferrer">
|
|
290
|
+
{@render children?.()}
|
|
291
|
+
</a>
|
|
292
|
+
{/snippet}
|
|
293
|
+
|
|
294
|
+
{#snippet code({ lang, text })}
|
|
295
|
+
<pre class="highlight {lang}"><code>{text}</code></pre>
|
|
296
|
+
{/snippet}
|
|
297
|
+
</SvelteMarkdown>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### How it works
|
|
301
|
+
|
|
302
|
+
- **Container renderers** (paragraph, heading, blockquote, list, etc.) receive a `children` snippet for nested content
|
|
303
|
+
- **Leaf renderers** (code, image, hr, br) receive only data props โ no `children`
|
|
304
|
+
- **Precedence**: snippet > component renderer > default. If both a snippet and a `renderers.paragraph` component are provided, the snippet wins
|
|
305
|
+
|
|
306
|
+
### HTML tag snippets
|
|
307
|
+
|
|
308
|
+
HTML tag snippets use an `html_` prefix to avoid collisions with markdown renderer names:
|
|
309
|
+
|
|
310
|
+
```svelte
|
|
311
|
+
<SvelteMarkdown {source}>
|
|
312
|
+
{#snippet html_div({ attributes, children })}
|
|
313
|
+
<div class="custom-wrapper" {...attributes}>{@render children?.()}</div>
|
|
314
|
+
{/snippet}
|
|
315
|
+
|
|
316
|
+
{#snippet html_a({ attributes, children })}
|
|
317
|
+
<a {...attributes} target="_blank" rel="noopener noreferrer">
|
|
318
|
+
{@render children?.()}
|
|
319
|
+
</a>
|
|
320
|
+
{/snippet}
|
|
321
|
+
</SvelteMarkdown>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
All HTML snippets share a uniform props interface: `{ attributes?: Record<string, any>, children?: Snippet }`.
|
|
325
|
+
|
|
326
|
+
### Custom HTML Tags
|
|
327
|
+
|
|
328
|
+
You can render arbitrary (non-standard) HTML tags like `<click>`, `<tooltip>`, or any custom element by providing a renderer or snippet for the tag name. The parsing pipeline accepts any tag name โ you just need to tell `SvelteMarkdown` how to render it.
|
|
329
|
+
|
|
330
|
+
**Component renderer approach:**
|
|
331
|
+
|
|
332
|
+
```svelte
|
|
333
|
+
<script lang="ts">
|
|
334
|
+
import SvelteMarkdown from '@humanspeak/svelte-markdown'
|
|
335
|
+
import ClickButton from './ClickButton.svelte'
|
|
336
|
+
|
|
337
|
+
const source = '<click>Click Me</click>'
|
|
338
|
+
const renderers = { html: { click: ClickButton } }
|
|
339
|
+
</script>
|
|
340
|
+
|
|
341
|
+
<SvelteMarkdown {source} {renderers} />
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Snippet override approach:**
|
|
345
|
+
|
|
346
|
+
```svelte
|
|
347
|
+
<SvelteMarkdown source={'<click data-action="submit">Click Me</click>'}>
|
|
348
|
+
{#snippet html_click({ attributes, children })}
|
|
349
|
+
<button {...attributes} class="custom-btn">{@render children?.()}</button>
|
|
350
|
+
{/snippet}
|
|
351
|
+
</SvelteMarkdown>
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Both approaches work for any tag name. Snippet overrides take precedence over component renderers when both are provided.
|
|
355
|
+
|
|
356
|
+
## Marked Extensions
|
|
357
|
+
|
|
358
|
+
Use third-party [marked extensions](https://marked.js.org/using_advanced#extensions) via the `extensions` prop. The component handles registering tokenizers internally โ you just provide renderers for the custom token types.
|
|
359
|
+
|
|
360
|
+
### KaTeX Math Rendering
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
npm install marked-katex-extension katex
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Component renderer approach:**
|
|
367
|
+
|
|
368
|
+
```svelte
|
|
369
|
+
<script lang="ts">
|
|
370
|
+
import SvelteMarkdown from '@humanspeak/svelte-markdown'
|
|
371
|
+
import type { RendererComponent, Renderers } from '@humanspeak/svelte-markdown'
|
|
372
|
+
import markedKatex from 'marked-katex-extension'
|
|
373
|
+
import KatexRenderer from './KatexRenderer.svelte'
|
|
374
|
+
|
|
375
|
+
interface KatexRenderers extends Renderers {
|
|
376
|
+
inlineKatex: RendererComponent
|
|
377
|
+
blockKatex: RendererComponent
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const renderers: Partial<KatexRenderers> = {
|
|
381
|
+
inlineKatex: KatexRenderer,
|
|
382
|
+
blockKatex: KatexRenderer
|
|
383
|
+
}
|
|
384
|
+
</script>
|
|
385
|
+
|
|
386
|
+
<svelte:head>
|
|
387
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.28/dist/katex.min.css" crossorigin="anonymous" />
|
|
388
|
+
</svelte:head>
|
|
389
|
+
|
|
390
|
+
<SvelteMarkdown
|
|
391
|
+
source="Euler's identity: $e^{{i\pi}} + 1 = 0$"
|
|
392
|
+
extensions={[markedKatex({ throwOnError: false })]}
|
|
393
|
+
{renderers}
|
|
394
|
+
/>
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Where `KatexRenderer.svelte` is:
|
|
398
|
+
|
|
399
|
+
```svelte
|
|
400
|
+
<script lang="ts">
|
|
401
|
+
import katex from 'katex'
|
|
402
|
+
|
|
403
|
+
interface Props {
|
|
404
|
+
text: string
|
|
405
|
+
displayMode?: boolean
|
|
406
|
+
}
|
|
407
|
+
const { text, displayMode = false }: Props = $props()
|
|
408
|
+
|
|
409
|
+
const html = $derived(katex.renderToString(text, { throwOnError: false, displayMode }))
|
|
410
|
+
</script>
|
|
411
|
+
|
|
412
|
+
{@html html}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Snippet override approach** (no separate component file needed):
|
|
416
|
+
|
|
417
|
+
```svelte
|
|
418
|
+
<script lang="ts">
|
|
419
|
+
import SvelteMarkdown from '@humanspeak/svelte-markdown'
|
|
420
|
+
import katex from 'katex'
|
|
421
|
+
import markedKatex from 'marked-katex-extension'
|
|
422
|
+
</script>
|
|
423
|
+
|
|
424
|
+
<svelte:head>
|
|
425
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.28/dist/katex.min.css" crossorigin="anonymous" />
|
|
426
|
+
</svelte:head>
|
|
427
|
+
|
|
428
|
+
<SvelteMarkdown
|
|
429
|
+
source="Euler's identity: $e^{{i\pi}} + 1 = 0$"
|
|
430
|
+
extensions={[markedKatex({ throwOnError: false })]}
|
|
431
|
+
>
|
|
432
|
+
{#snippet inlineKatex(props)}
|
|
433
|
+
{@html katex.renderToString(props.text, { displayMode: false })}
|
|
434
|
+
{/snippet}
|
|
435
|
+
{#snippet blockKatex(props)}
|
|
436
|
+
{@html katex.renderToString(props.text, { displayMode: true })}
|
|
437
|
+
{/snippet}
|
|
438
|
+
</SvelteMarkdown>
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### How It Works
|
|
442
|
+
|
|
443
|
+
Marked extensions define custom token types with a `name` property (e.g., `inlineKatex`, `blockKatex`, `alert`). When you pass extensions via the `extensions` prop, SvelteMarkdown automatically extracts these token type names and makes them available as both **component renderer keys** and **snippet override names**.
|
|
444
|
+
|
|
445
|
+
To find the token type names for any extension, check its source or documentation for the `name` field in its `extensions` array:
|
|
446
|
+
|
|
447
|
+
```js
|
|
448
|
+
// Example: marked-katex-extension registers tokens named "inlineKatex" and "blockKatex"
|
|
449
|
+
// โ use renderers={{ inlineKatex: ..., blockKatex: ... }}
|
|
450
|
+
// โ or {#snippet inlineKatex(props)} and {#snippet blockKatex(props)}
|
|
451
|
+
|
|
452
|
+
// Example: a custom alert extension registers a token named "alert"
|
|
453
|
+
// โ use renderers={{ alert: AlertComponent }}
|
|
454
|
+
// โ or {#snippet alert(props)}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Each snippet/component receives the token's properties as props (e.g., `text`, `displayMode` for KaTeX; `text`, `level` for alerts).
|
|
458
|
+
|
|
459
|
+
See the [full documentation](https://markdown.svelte.page/docs/advanced/marked-extensions) and [interactive demo](https://markdown.svelte.page/examples/marked-extensions).
|
|
460
|
+
|
|
461
|
+
### TypeScript
|
|
462
|
+
|
|
463
|
+
All snippet prop types are exported for use in external components:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import type {
|
|
467
|
+
ParagraphSnippetProps,
|
|
468
|
+
HeadingSnippetProps,
|
|
469
|
+
LinkSnippetProps,
|
|
470
|
+
CodeSnippetProps,
|
|
471
|
+
HtmlSnippetProps,
|
|
472
|
+
SnippetOverrides,
|
|
473
|
+
HtmlSnippetOverrides
|
|
474
|
+
} from '@humanspeak/svelte-markdown'
|
|
475
|
+
```
|
|
476
|
+
|
|
262
477
|
## Advanced Features
|
|
263
478
|
|
|
264
479
|
### Table Support with Mixed Content
|
|
@@ -417,12 +632,13 @@ The component emits a `parsed` event when tokens are calculated:
|
|
|
417
632
|
|
|
418
633
|
## Props
|
|
419
634
|
|
|
420
|
-
| Prop
|
|
421
|
-
|
|
|
422
|
-
| source
|
|
423
|
-
| renderers
|
|
424
|
-
| options
|
|
425
|
-
| isInline
|
|
635
|
+
| Prop | Type | Description |
|
|
636
|
+
| ---------- | ----------------------- | ------------------------------------------------ |
|
|
637
|
+
| source | `string \| Token[]` | Markdown content or pre-parsed tokens |
|
|
638
|
+
| renderers | `Partial<Renderers>` | Custom component overrides |
|
|
639
|
+
| options | `SvelteMarkdownOptions` | Marked parser configuration |
|
|
640
|
+
| isInline | `boolean` | Toggle inline parsing mode |
|
|
641
|
+
| extensions | `MarkedExtension[]` | Third-party marked extensions (e.g., KaTeX math) |
|
|
426
642
|
|
|
427
643
|
## Security
|
|
428
644
|
|
package/dist/Parser.svelte
CHANGED
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
/>
|
|
96
96
|
{/each}
|
|
97
97
|
{/if}
|
|
98
|
-
{:else if type in renderers}
|
|
98
|
+
{:else if type in renderers || type in snippetOverrides}
|
|
99
99
|
{#if type === 'table'}
|
|
100
100
|
{#if renderers.table && renderers.tablerow && renderers.tablecell}
|
|
101
101
|
{@const tableSnippet = snippetOverrides[type]}
|
|
@@ -59,7 +59,8 @@
|
|
|
59
59
|
type TokensList
|
|
60
60
|
} from './utils/markdown-parser.js'
|
|
61
61
|
import { parseAndCacheTokens } from './utils/parse-and-cache.js'
|
|
62
|
-
import { rendererKeysInternal
|
|
62
|
+
import { rendererKeysInternal } from './utils/rendererKeys.js'
|
|
63
|
+
import { Marked } from 'marked'
|
|
63
64
|
|
|
64
65
|
const {
|
|
65
66
|
source = [],
|
|
@@ -67,12 +68,23 @@
|
|
|
67
68
|
options = {},
|
|
68
69
|
isInline = false,
|
|
69
70
|
parsed = () => {},
|
|
71
|
+
extensions = [],
|
|
70
72
|
...rest
|
|
71
73
|
}: SvelteMarkdownProps & {
|
|
72
74
|
[key: string]: unknown
|
|
73
75
|
} = $props()
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
// Extract custom token type names from the extensions array
|
|
78
|
+
const extensionTokenNames = $derived(
|
|
79
|
+
extensions.flatMap((ext) => ext.extensions?.map((e) => e.name) ?? [])
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
// Create a scoped Marked instance and extract its resolved defaults
|
|
83
|
+
const extensionDefaults = $derived(
|
|
84
|
+
extensions.length > 0 ? new Marked(...extensions).defaults : {}
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const combinedOptions = $derived({ ...defaultOptions, ...extensionDefaults, ...options })
|
|
76
88
|
const slugger = new Slugger()
|
|
77
89
|
|
|
78
90
|
const tokens = $derived.by(() => {
|
|
@@ -106,10 +118,13 @@
|
|
|
106
118
|
: defaultRenderers.html
|
|
107
119
|
})
|
|
108
120
|
|
|
109
|
-
//
|
|
121
|
+
// All renderer keys: built-in + extension token names
|
|
122
|
+
const allRendererKeys = $derived([...rendererKeysInternal, ...extensionTokenNames])
|
|
123
|
+
|
|
124
|
+
// Collect markdown snippet overrides (keys matching renderer names or extension token names)
|
|
110
125
|
const snippetOverrides = $derived(
|
|
111
126
|
Object.fromEntries(
|
|
112
|
-
|
|
127
|
+
allRendererKeys
|
|
113
128
|
.filter((key) => key in rest && rest[key] != null)
|
|
114
129
|
.map((key) => [key, rest[key]])
|
|
115
130
|
)
|
|
@@ -118,15 +133,15 @@
|
|
|
118
133
|
// Collect HTML snippet overrides (keys matching html_<tag>)
|
|
119
134
|
const htmlSnippetOverrides = $derived(
|
|
120
135
|
Object.fromEntries(
|
|
121
|
-
|
|
122
|
-
.filter((key) =>
|
|
123
|
-
.map((key) => [key,
|
|
136
|
+
Object.entries(rest)
|
|
137
|
+
.filter(([key, val]) => key.startsWith('html_') && val != null)
|
|
138
|
+
.map(([key, val]) => [key.slice(5), val])
|
|
124
139
|
)
|
|
125
140
|
)
|
|
126
141
|
|
|
127
142
|
// Passthrough: everything that isn't a known snippet override
|
|
128
143
|
const snippetKeySet = $derived(
|
|
129
|
-
new Set([...
|
|
144
|
+
new Set([...allRendererKeys, ...Object.keys(rest).filter((k) => k.startsWith('html_'))])
|
|
130
145
|
)
|
|
131
146
|
const passThroughProps = $derived(
|
|
132
147
|
Object.fromEntries(Object.entries(rest).filter(([key]) => !snippetKeySet.has(key)))
|
package/dist/index.d.ts
CHANGED
|
@@ -59,5 +59,7 @@ export { htmlRendererKeysInternal as htmlRendererKeys, rendererKeysInternal as r
|
|
|
59
59
|
*/
|
|
60
60
|
export { MemoryCache } from './utils/cache.js';
|
|
61
61
|
export { TokenCache, tokenCache } from './utils/token-cache.js';
|
|
62
|
+
/** Re-exported `MarkedExtension` type for the `extensions` prop. */
|
|
63
|
+
export type { MarkedExtension } from 'marked';
|
|
62
64
|
/** Re-exported types for consumer convenience. */
|
|
63
65
|
export type { BlockquoteSnippetProps, BrSnippetProps, CodeSnippetProps, CodespanSnippetProps, DelSnippetProps, EmSnippetProps, EscapeSnippetProps, HeadingSnippetProps, HrSnippetProps, HtmlRenderers, HtmlSnippetOverrides, HtmlSnippetProps, ImageSnippetProps, LinkSnippetProps, ListItemSnippetProps, ListSnippetProps, ParagraphSnippetProps, RawTextSnippetProps, RendererComponent, Renderers, SnippetOverrides, StrongSnippetProps, SvelteMarkdownOptions, SvelteMarkdownProps, TableBodySnippetProps, TableCellSnippetProps, TableHeadSnippetProps, TableRowSnippetProps, TableSnippetProps, TextSnippetProps, Token, TokensList };
|
package/dist/types.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
20
|
-
import type { Token, TokensList } from 'marked';
|
|
20
|
+
import type { MarkedExtension, Token, TokensList } from 'marked';
|
|
21
21
|
import type { Snippet } from 'svelte';
|
|
22
22
|
import type { MarkedOptions, Renderers } from './utils/markdown-parser.js';
|
|
23
23
|
import type { HtmlKey } from './utils/rendererKeys.js';
|
|
@@ -152,6 +152,29 @@ export type SvelteMarkdownProps<T extends Renderers = Renderers> = {
|
|
|
152
152
|
* generation settings. Merged with {@link defaultOptions}.
|
|
153
153
|
*/
|
|
154
154
|
options?: Partial<SvelteMarkdownOptions>;
|
|
155
|
+
/**
|
|
156
|
+
* Array of marked extensions to apply when parsing.
|
|
157
|
+
*
|
|
158
|
+
* Internally creates a scoped `Marked` instance, extracts its resolved
|
|
159
|
+
* defaults, and merges them into the parser options so the lexer
|
|
160
|
+
* recognises any custom token types the extensions define.
|
|
161
|
+
*
|
|
162
|
+
* Extension token names are also used to collect snippet overrides,
|
|
163
|
+
* enabling both component-renderer and snippet-based rendering of
|
|
164
|
+
* custom tokens.
|
|
165
|
+
*
|
|
166
|
+
* @defaultValue `[]`
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```svelte
|
|
170
|
+
* <SvelteMarkdown
|
|
171
|
+
* source={markdown}
|
|
172
|
+
* extensions={[markedKatex({ throwOnError: false })]}
|
|
173
|
+
* renderers={{ inlineKatex: KatexRenderer, blockKatex: KatexRenderer }}
|
|
174
|
+
* />
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
extensions?: MarkedExtension[];
|
|
155
178
|
/**
|
|
156
179
|
* When `true`, the source is parsed with `Lexer.lexInline()` instead of
|
|
157
180
|
* `Lexer.lex()`, producing only inline tokens (no block elements).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@humanspeak/svelte-markdown",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Fast, customizable markdown renderer for Svelte with built-in caching, TypeScript support, and Svelte 5 runes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|
|
@@ -74,12 +74,13 @@
|
|
|
74
74
|
"@playwright/cli": "^0.1.1",
|
|
75
75
|
"@playwright/test": "^1.58.2",
|
|
76
76
|
"@sveltejs/adapter-auto": "^7.0.1",
|
|
77
|
-
"@sveltejs/kit": "^2.52.
|
|
77
|
+
"@sveltejs/kit": "^2.52.2",
|
|
78
78
|
"@sveltejs/package": "^2.5.7",
|
|
79
79
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
80
80
|
"@testing-library/jest-dom": "^6.9.1",
|
|
81
81
|
"@testing-library/svelte": "^5.3.1",
|
|
82
82
|
"@testing-library/user-event": "^14.6.1",
|
|
83
|
+
"@types/katex": "^0.16.8",
|
|
83
84
|
"@types/node": "^25.2.3",
|
|
84
85
|
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
85
86
|
"@typescript-eslint/parser": "^8.56.0",
|
|
@@ -93,13 +94,15 @@
|
|
|
93
94
|
"globals": "^17.3.0",
|
|
94
95
|
"husky": "^9.1.7",
|
|
95
96
|
"jsdom": "^28.1.0",
|
|
97
|
+
"katex": "^0.16.28",
|
|
98
|
+
"marked-katex-extension": "^5.1.7",
|
|
96
99
|
"prettier": "^3.8.1",
|
|
97
100
|
"prettier-plugin-organize-imports": "^4.3.0",
|
|
98
|
-
"prettier-plugin-svelte": "^3.
|
|
101
|
+
"prettier-plugin-svelte": "^3.5.0",
|
|
99
102
|
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
100
103
|
"publint": "^0.3.17",
|
|
101
|
-
"svelte": "^5.
|
|
102
|
-
"svelte-check": "^4.4.
|
|
104
|
+
"svelte": "^5.53.0",
|
|
105
|
+
"svelte-check": "^4.4.1",
|
|
103
106
|
"typescript": "^5.9.3",
|
|
104
107
|
"typescript-eslint": "^8.56.0",
|
|
105
108
|
"vite": "^7.3.1",
|
|
@@ -123,7 +126,7 @@
|
|
|
123
126
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
124
127
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
125
128
|
"dev": "vite dev",
|
|
126
|
-
"dev:all": "concurrently -k -n pkg,docs -c green,cyan \"pnpm -w -r --filter @humanspeak/svelte-
|
|
129
|
+
"dev:all": "concurrently -k -n pkg,docs -c green,cyan \"pnpm -w -r --filter @humanspeak/svelte-markdown run dev:pkg\" \"pnpm --filter docs run dev\"",
|
|
127
130
|
"dev:pkg": "svelte-kit sync && svelte-package --watch",
|
|
128
131
|
"format": "prettier --write .",
|
|
129
132
|
"lint": "prettier --check . && eslint .",
|