@humanspeak/svelte-markdown 0.8.9 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -122,6 +122,166 @@ import type {
122
122
  } from '@humanspeak/svelte-markdown'
123
123
  ```
124
124
 
125
+ ## Exports for programmatic overrides
126
+
127
+ You can import renderer maps and helper keys to selectively override behavior.
128
+
129
+ ```ts
130
+ import SvelteMarkdown, {
131
+ // Maps
132
+ defaultRenderers, // markdown renderer map
133
+ Html, // HTML renderer map
134
+
135
+ // Keys
136
+ rendererKeys, // markdown renderer keys (excludes 'html')
137
+ htmlRendererKeys, // HTML renderer tag names
138
+
139
+ // Utility components
140
+ Unsupported, // markdown-level unsupported fallback
141
+ UnsupportedHTML // HTML-level unsupported fallback
142
+ } from '@humanspeak/svelte-markdown'
143
+
144
+ // Example: override a subset
145
+ const customRenderers = {
146
+ ...defaultRenderers,
147
+ link: CustomLink,
148
+ html: {
149
+ ...Html,
150
+ span: CustomSpan
151
+ }
152
+ }
153
+
154
+ // Optional: iterate keys when building overrides dynamically
155
+ for (const key of rendererKeys) {
156
+ // if (key === 'paragraph') customRenderers.paragraph = MyParagraph
157
+ }
158
+ for (const tag of htmlRendererKeys) {
159
+ // if (tag === 'div') customRenderers.html.div = MyDiv
160
+ }
161
+ ```
162
+
163
+ Notes
164
+
165
+ - `rendererKeys` intentionally excludes `html`. Use `htmlRendererKeys` for HTML tag overrides.
166
+ - `Unsupported` and `UnsupportedHTML` are available if you want a pass-through fallback strategy.
167
+
168
+ ## Helper utilities for allow/deny strategies
169
+
170
+ These helpers make it easy to either allow only a subset or exclude only a subset of renderers without writing huge maps by hand.
171
+
172
+ - **HTML helpers**
173
+ - `buildUnsupportedHTML()`: returns a map where every HTML tag uses `UnsupportedHTML`.
174
+ - `allowHtmlOnly(allowed)`: enable only the provided tags; others use `UnsupportedHTML`.
175
+ - Accepts tag names like `'strong'` or tuples like `['div', MyDiv]` to plug in custom components.
176
+ - `excludeHtmlOnly(excluded, overrides?)`: disable only the listed tags (mapped to `UnsupportedHTML`), with optional overrides for non-excluded tags using tuples.
177
+ - **Markdown helpers (non-HTML)**
178
+ - `buildUnsupportedRenderers()`: returns a map where all markdown renderers (except `html`) use `Unsupported`.
179
+ - `allowRenderersOnly(allowed)`: enable only the provided markdown renderer keys; others use `Unsupported`.
180
+ - Accepts keys like `'paragraph'` or tuples like `['paragraph', MyParagraph]` to plug in custom components.
181
+ - `excludeRenderersOnly(excluded, overrides?)`: disable only the listed markdown renderer keys, with optional overrides for non-excluded keys using tuples.
182
+
183
+ ### HTML helpers in context
184
+
185
+ The HTML helpers return an `HtmlRenderers` map to be used inside the `html` key of the overall `renderers` map. They do not replace the entire `renderers` object by themselves.
186
+
187
+ Basic: keep markdown defaults, allow only a few HTML tags (others become `UnsupportedHTML`):
188
+
189
+ ```ts
190
+ import SvelteMarkdown, { defaultRenderers, allowHtmlOnly } from '@humanspeak/svelte-markdown'
191
+
192
+ const renderers = {
193
+ ...defaultRenderers, // keep markdown defaults
194
+ html: allowHtmlOnly(['strong', 'em', 'a']) // restrict HTML
195
+ }
196
+ ```
197
+
198
+ Allow a custom component for one tag while allowing others with defaults:
199
+
200
+ ```ts
201
+ import SvelteMarkdown, { defaultRenderers, allowHtmlOnly } from '@humanspeak/svelte-markdown'
202
+
203
+ const renderers = {
204
+ ...defaultRenderers,
205
+ html: allowHtmlOnly([['div', MyDiv], 'a'])
206
+ }
207
+ ```
208
+
209
+ Exclude just a few HTML tags; keep all other HTML tags as defaults:
210
+
211
+ ```ts
212
+ import SvelteMarkdown, { defaultRenderers, excludeHtmlOnly } from '@humanspeak/svelte-markdown'
213
+
214
+ const renderers = {
215
+ ...defaultRenderers,
216
+ html: excludeHtmlOnly(['span', 'iframe'])
217
+ }
218
+
219
+ // Or exclude 'span', but override 'a' to CustomA
220
+ const renderersWithOverride = {
221
+ ...defaultRenderers,
222
+ html: excludeHtmlOnly(['span'], [['a', CustomA]])
223
+ }
224
+ ```
225
+
226
+ Disable all HTML quickly (markdown defaults unchanged):
227
+
228
+ ```ts
229
+ import SvelteMarkdown, { defaultRenderers, buildUnsupportedHTML } from '@humanspeak/svelte-markdown'
230
+
231
+ const renderers = {
232
+ ...defaultRenderers,
233
+ html: buildUnsupportedHTML()
234
+ }
235
+ ```
236
+
237
+ ### Markdown-only (non-HTML) scenarios
238
+
239
+ Allow only paragraph and link with defaults, disable others:
240
+
241
+ ```ts
242
+ import { allowRenderersOnly } from '@humanspeak/svelte-markdown'
243
+
244
+ const md = allowRenderersOnly(['paragraph', 'link'])
245
+ ```
246
+
247
+ Exclude just link; keep others as defaults:
248
+
249
+ ```ts
250
+ import { excludeRenderersOnly } from '@humanspeak/svelte-markdown'
251
+
252
+ const md = excludeRenderersOnly(['link'])
253
+ ```
254
+
255
+ Disable all markdown renderers (except `html`) quickly:
256
+
257
+ ```ts
258
+ import { buildUnsupportedRenderers } from '@humanspeak/svelte-markdown'
259
+
260
+ const md = buildUnsupportedRenderers()
261
+ ```
262
+
263
+ ### Combine HTML and Markdown helpers
264
+
265
+ You can combine both maps in `renderers` for `SvelteMarkdown`.
266
+
267
+ ```svelte
268
+ <script lang="ts">
269
+ import SvelteMarkdown, { allowRenderersOnly, allowHtmlOnly } from '@humanspeak/svelte-markdown'
270
+
271
+ const renderers = {
272
+ // Only allow a minimal markdown set
273
+ ...allowRenderersOnly(['paragraph', 'link']),
274
+
275
+ // Configure HTML separately (only strong/em/a)
276
+ html: allowHtmlOnly(['strong', 'em', 'a'])
277
+ }
278
+
279
+ const source = `# Title\n\nThis has <strong>HTML</strong> and [a link](https://example.com).`
280
+ </script>
281
+
282
+ <SvelteMarkdown {source} {renderers} />
283
+ ```
284
+
125
285
  ## Custom Renderer Example
126
286
 
127
287
  Here's a complete example of a custom renderer with TypeScript support:
@@ -127,7 +127,8 @@
127
127
  {:else if type === 'list' && renderers.list}
128
128
  {#if ordered}
129
129
  <renderers.list {ordered} {...rest}>
130
- {@const { items, ...parserRest }: {items: Props[]} = rest}
130
+ {@const { items: _items, ...parserRest } = rest}
131
+ {@const items = (_items as Props[] | undefined) ?? []}
131
132
  {#each items as item, index (index)}
132
133
  {@const OrderedListComponent = renderers.orderedlistitem || renderers.listitem}
133
134
  {#if OrderedListComponent}
@@ -139,7 +140,8 @@
139
140
  </renderers.list>
140
141
  {:else}
141
142
  <renderers.list {ordered} {...rest}>
142
- {@const { items, ...parserRest }: {items: Props[]} = rest}
143
+ {@const { items: _items, ...parserRest } = rest}
144
+ {@const items = (_items as Props[] | undefined) ?? []}
143
145
  {#each items as item, index (index)}
144
146
  {@const UnorderedListComponent =
145
147
  renderers.unorderedlistitem || renderers.listitem}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,12 @@
1
- import type { HtmlRenderers } from './renderers/html/index.js';
2
- import type { RendererComponent, Renderers, Token, TokensList } from './utils/markdown-parser.js';
1
+ import { type HtmlRenderers } from './renderers/html/index.js';
3
2
  import SvelteMarkdown from './SvelteMarkdown.svelte';
4
3
  import type { SvelteMarkdownOptions, SvelteMarkdownProps } from './types.js';
4
+ import { defaultRenderers, type RendererComponent, type Renderers, type Token, type TokensList } from './utils/markdown-parser.js';
5
5
  export default SvelteMarkdown;
6
+ export { default as Html, UnsupportedHTML } from './renderers/html/index.js';
7
+ export { Unsupported } from './renderers/index.js';
8
+ export { allowHtmlOnly, buildUnsupportedHTML, excludeHtmlOnly } from './utils/unsupportedHtmlRenderers.js';
9
+ export { allowRenderersOnly, buildUnsupportedRenderers, excludeRenderersOnly } from './utils/unsupportedRenderers.js';
10
+ export { defaultRenderers };
11
+ export { htmlRendererKeysInternal as htmlRendererKeys, rendererKeysInternal as rendererKeys } from './utils/rendererKeys.js';
6
12
  export type { HtmlRenderers, RendererComponent, Renderers, SvelteMarkdownOptions, SvelteMarkdownProps, Token, TokensList };
package/dist/index.js CHANGED
@@ -1,2 +1,12 @@
1
+ // Reexport your entry components here
2
+ import {} from './renderers/html/index.js';
1
3
  import SvelteMarkdown from './SvelteMarkdown.svelte';
4
+ import { defaultRenderers } from './utils/markdown-parser.js';
2
5
  export default SvelteMarkdown;
6
+ export { default as Html, UnsupportedHTML } from './renderers/html/index.js';
7
+ export { Unsupported } from './renderers/index.js';
8
+ export { allowHtmlOnly, buildUnsupportedHTML, excludeHtmlOnly } from './utils/unsupportedHtmlRenderers.js';
9
+ export { allowRenderersOnly, buildUnsupportedRenderers, excludeRenderersOnly } from './utils/unsupportedRenderers.js';
10
+ export { defaultRenderers };
11
+ // Canonical key lists (public API names)
12
+ export { htmlRendererKeysInternal as htmlRendererKeys, rendererKeysInternal as rendererKeys } from './utils/rendererKeys.js';
@@ -0,0 +1,5 @@
1
+ <script lang="ts">
2
+ const { raw } = $props()
3
+ </script>
4
+
5
+ {raw}
@@ -0,0 +1,5 @@
1
+ declare const Unsupported: import("svelte").Component<{
2
+ raw: any;
3
+ }, {}, "">;
4
+ type Unsupported = ReturnType<typeof Unsupported>;
5
+ export default Unsupported;
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte'
3
+
4
+ const {
5
+ children,
6
+ tag,
7
+ attributes
8
+ }: { children?: Snippet; tag: string; attributes?: Record<string, string> } = $props()
9
+
10
+ const attributesString =
11
+ Object.entries(attributes || {})
12
+ .map(([key, value]) => `${key}="${value}"`)
13
+ .join(' ') || ''
14
+ </script>
15
+
16
+ &lt;{tag}{attributesString ? ` ${attributesString}` : ''}&gt;{@render children?.()}&lt;/{tag}&gt;
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ children?: Snippet;
4
+ tag: string;
5
+ attributes?: Record<string, string>;
6
+ };
7
+ declare const UnsupportedHtml: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type UnsupportedHtml = ReturnType<typeof UnsupportedHtml>;
9
+ export default UnsupportedHtml;
@@ -1,6 +1,8 @@
1
1
  import type { Component } from 'svelte';
2
+ import UnsupportedHTML from './_UnsupportedHTML.svelte';
2
3
  export interface HtmlRenderers {
3
4
  [key: string]: Component<any, any, any> | null;
4
5
  }
5
6
  export declare const Html: HtmlRenderers;
6
7
  export default Html;
8
+ export { UnsupportedHTML };
@@ -81,6 +81,7 @@ import Track from './Track.svelte';
81
81
  import U from './U.svelte';
82
82
  import Ul from './Ul.svelte';
83
83
  import Var from './Var.svelte';
84
+ import UnsupportedHTML from './_UnsupportedHTML.svelte';
84
85
  export const Html = {
85
86
  a: A,
86
87
  abbr: Abbr,
@@ -167,3 +168,4 @@ export const Html = {
167
168
  var: Var
168
169
  };
169
170
  export default Html;
171
+ export { UnsupportedHTML };
@@ -1,3 +1,4 @@
1
+ export { default as Unsupported } from './_Unsupported.svelte';
1
2
  export { default as Blockquote } from './Blockquote.svelte';
2
3
  export { default as Br } from './Br.svelte';
3
4
  export { default as Code } from './Code.svelte';
@@ -1,3 +1,4 @@
1
+ export { default as Unsupported } from './_Unsupported.svelte';
1
2
  export { default as Blockquote } from './Blockquote.svelte';
2
3
  export { default as Br } from './Br.svelte';
3
4
  export { default as Code } from './Code.svelte';
@@ -0,0 +1,6 @@
1
+ import Html from '../renderers/html/index.js';
2
+ import { type Renderers } from './markdown-parser.js';
3
+ export type RendererKey = Exclude<keyof Renderers, 'html'>;
4
+ export declare const rendererKeysInternal: RendererKey[];
5
+ export type HtmlKey = keyof typeof Html;
6
+ export declare const htmlRendererKeysInternal: HtmlKey[];
@@ -0,0 +1,4 @@
1
+ import Html from '../renderers/html/index.js';
2
+ import { defaultRenderers } from './markdown-parser.js';
3
+ export const rendererKeysInternal = Object.keys(defaultRenderers).filter((k) => k !== 'html');
4
+ export const htmlRendererKeysInternal = Object.keys(Html);
@@ -0,0 +1,62 @@
1
+ import { type HtmlRenderers } from '../renderers/html/index.js';
2
+ import { type HtmlKey } from './rendererKeys.js';
3
+ import type { Component } from 'svelte';
4
+ /**
5
+ * Builds a map of HTML renderers where every known HTML tag is mapped to `UnsupportedHTML`.
6
+ * This is useful when you want to disable all built‑in HTML rendering and provide
7
+ * explicit allow-lists or a minimal subset afterwards.
8
+ *
9
+ * @function buildUnsupportedHTML
10
+ * @returns {HtmlRenderers} A map containing all tags set to `UnsupportedHTML`.
11
+ * @example
12
+ * import { buildUnsupportedHTML } from '@humanspeak/svelte-markdown'
13
+ * const renderers = {
14
+ * html: buildUnsupportedHTML()
15
+ * }
16
+ */
17
+ export declare const buildUnsupportedHTML: () => HtmlRenderers;
18
+ /**
19
+ * Produces an HTML renderer map that allows only the specified tags.
20
+ * All non‑listed tags are set to `UnsupportedHTML`.
21
+ *
22
+ * Each entry can be either a tag name (to use the library’s default component for that tag),
23
+ * or a tuple `[tag, component]` to specify a custom component for that tag.
24
+ *
25
+ * @function allowHtmlOnly
26
+ * @param {Array<keyof HtmlRenderers | [keyof HtmlRenderers, Component | null]>} allowed
27
+ * Tag names to allow, or tuples specifying a custom component per allowed tag.
28
+ * Any tag not listed will be mapped to `UnsupportedHTML`.
29
+ * @returns {HtmlRenderers} A renderer map with only the provided tags enabled.
30
+ * @example
31
+ * // Only allow strong/em/a with default components; everything else UnsupportedHTML
32
+ * const html = allowHtmlOnly(['strong', 'em', 'a'])
33
+ *
34
+ * @example
35
+ * // Allow a custom component for div while allowing the default for a
36
+ * const html = allowHtmlOnly([['div', MyDiv], 'a'])
37
+ */
38
+ export declare const allowHtmlOnly: (allowed: Array<HtmlKey | [HtmlKey, Component | null]>) => HtmlRenderers;
39
+ /**
40
+ * Produces an HTML renderer map that excludes only the specified tags.
41
+ * Excluded tags are mapped to `UnsupportedHTML`, while all other tags use the
42
+ * library’s default components. Optionally, you can override specific non‑excluded
43
+ * tags with custom components using `[tag, component]` tuples.
44
+ *
45
+ * Exclusions take precedence over overrides. If a tag is listed in `excluded`, an
46
+ * override for the same tag will be ignored.
47
+ *
48
+ * @function excludeHtmlOnly
49
+ * @param {Array<keyof HtmlRenderers>} excluded
50
+ * Tag names to exclude (set to `UnsupportedHTML`).
51
+ * @param {Array<[keyof HtmlRenderers, Component | null]>} [overrides]
52
+ * Optional tuples mapping non‑excluded tags to custom components.
53
+ * @returns {HtmlRenderers} A renderer map with only the provided tags excluded.
54
+ * @example
55
+ * // Disable just span and div, keep others as defaults
56
+ * const html = excludeHtmlOnly(['span', 'div'])
57
+ *
58
+ * @example
59
+ * // Disable span; override 'a' to CustomA component
60
+ * const html = excludeHtmlOnly(['span'], [['a', CustomA]])
61
+ */
62
+ export declare const excludeHtmlOnly: (excluded: HtmlKey[], overrides?: Array<[HtmlKey, Component | null]>) => HtmlRenderers;
@@ -0,0 +1,99 @@
1
+ import Html, { UnsupportedHTML } from '../renderers/html/index.js';
2
+ import { htmlRendererKeysInternal } from './rendererKeys.js';
3
+ /**
4
+ * Builds a map of HTML renderers where every known HTML tag is mapped to `UnsupportedHTML`.
5
+ * This is useful when you want to disable all built‑in HTML rendering and provide
6
+ * explicit allow-lists or a minimal subset afterwards.
7
+ *
8
+ * @function buildUnsupportedHTML
9
+ * @returns {HtmlRenderers} A map containing all tags set to `UnsupportedHTML`.
10
+ * @example
11
+ * import { buildUnsupportedHTML } from '@humanspeak/svelte-markdown'
12
+ * const renderers = {
13
+ * html: buildUnsupportedHTML()
14
+ * }
15
+ */
16
+ export const buildUnsupportedHTML = () => {
17
+ const result = {};
18
+ for (const key of htmlRendererKeysInternal) {
19
+ result[key] = UnsupportedHTML;
20
+ }
21
+ return result;
22
+ };
23
+ /**
24
+ * Produces an HTML renderer map that allows only the specified tags.
25
+ * All non‑listed tags are set to `UnsupportedHTML`.
26
+ *
27
+ * Each entry can be either a tag name (to use the library’s default component for that tag),
28
+ * or a tuple `[tag, component]` to specify a custom component for that tag.
29
+ *
30
+ * @function allowHtmlOnly
31
+ * @param {Array<keyof HtmlRenderers | [keyof HtmlRenderers, Component | null]>} allowed
32
+ * Tag names to allow, or tuples specifying a custom component per allowed tag.
33
+ * Any tag not listed will be mapped to `UnsupportedHTML`.
34
+ * @returns {HtmlRenderers} A renderer map with only the provided tags enabled.
35
+ * @example
36
+ * // Only allow strong/em/a with default components; everything else UnsupportedHTML
37
+ * const html = allowHtmlOnly(['strong', 'em', 'a'])
38
+ *
39
+ * @example
40
+ * // Allow a custom component for div while allowing the default for a
41
+ * const html = allowHtmlOnly([['div', MyDiv], 'a'])
42
+ */
43
+ export const allowHtmlOnly = (allowed) => {
44
+ const result = buildUnsupportedHTML();
45
+ for (const entry of allowed) {
46
+ if (Array.isArray(entry)) {
47
+ const [tag, component] = entry;
48
+ // Only set if the tag exists in our Html map
49
+ if (tag in Html)
50
+ result[tag] = component;
51
+ }
52
+ else {
53
+ const tag = entry;
54
+ if (tag in Html)
55
+ result[tag] = Html[tag];
56
+ }
57
+ }
58
+ return result;
59
+ };
60
+ /**
61
+ * Produces an HTML renderer map that excludes only the specified tags.
62
+ * Excluded tags are mapped to `UnsupportedHTML`, while all other tags use the
63
+ * library’s default components. Optionally, you can override specific non‑excluded
64
+ * tags with custom components using `[tag, component]` tuples.
65
+ *
66
+ * Exclusions take precedence over overrides. If a tag is listed in `excluded`, an
67
+ * override for the same tag will be ignored.
68
+ *
69
+ * @function excludeHtmlOnly
70
+ * @param {Array<keyof HtmlRenderers>} excluded
71
+ * Tag names to exclude (set to `UnsupportedHTML`).
72
+ * @param {Array<[keyof HtmlRenderers, Component | null]>} [overrides]
73
+ * Optional tuples mapping non‑excluded tags to custom components.
74
+ * @returns {HtmlRenderers} A renderer map with only the provided tags excluded.
75
+ * @example
76
+ * // Disable just span and div, keep others as defaults
77
+ * const html = excludeHtmlOnly(['span', 'div'])
78
+ *
79
+ * @example
80
+ * // Disable span; override 'a' to CustomA component
81
+ * const html = excludeHtmlOnly(['span'], [['a', CustomA]])
82
+ */
83
+ export const excludeHtmlOnly = (excluded, overrides) => {
84
+ const result = { ...Html };
85
+ for (const tag of excluded) {
86
+ if (tag in Html)
87
+ result[tag] = UnsupportedHTML;
88
+ }
89
+ if (overrides) {
90
+ for (const [tag, component] of overrides) {
91
+ // Exclusions take precedence; do not override excluded tags
92
+ if (excluded.includes(tag))
93
+ continue;
94
+ if (tag in Html)
95
+ result[tag] = component;
96
+ }
97
+ }
98
+ return result;
99
+ };
@@ -0,0 +1,57 @@
1
+ import { type RendererComponent, type Renderers } from './markdown-parser.js';
2
+ import { type RendererKey } from './rendererKeys.js';
3
+ /**
4
+ * Builds a map where every markdown renderer (excluding the special `html` map)
5
+ * is set to the `Unsupported` component.
6
+ *
7
+ * @function buildUnsupportedRenderers
8
+ * @returns {Partial<Renderers>} A map with all non‑HTML renderers set to `Unsupported`.
9
+ * @example
10
+ * import { buildUnsupportedRenderers } from '@humanspeak/svelte-markdown'
11
+ * const renderers = {
12
+ * ...buildUnsupportedRenderers(),
13
+ * html: {} // customize HTML separately
14
+ * }
15
+ */
16
+ export declare const buildUnsupportedRenderers: () => Partial<Renderers>;
17
+ /**
18
+ * Produces a renderer map that allows only the specified markdown renderers (excluding `html`).
19
+ * All non‑listed renderer keys are set to `Unsupported`.
20
+ * Each entry can be either a renderer key (to use the library’s default component),
21
+ * or a tuple `[key, component]` to specify a custom component for that key.
22
+ *
23
+ * @function allowRenderersOnly
24
+ * @param {Array<RendererKey | [RendererKey, RendererComponent]>} allowed
25
+ * Renderer keys to allow, or tuples for custom component overrides.
26
+ * @returns {Partial<Renderers>} A renderer map with only the provided keys enabled.
27
+ * @example
28
+ * // Allow only paragraph and link with defaults
29
+ * const renderers = allowRenderersOnly(['paragraph', 'link'])
30
+ *
31
+ * @example
32
+ * // Allow paragraph with a custom component
33
+ * const renderers = allowRenderersOnly([['paragraph', MyParagraph]])
34
+ */
35
+ export declare const allowRenderersOnly: (allowed: Array<RendererKey | [RendererKey, RendererComponent]>) => Partial<Renderers>;
36
+ /**
37
+ * Produces a renderer map that excludes only the specified markdown renderer keys (excluding `html`).
38
+ * Excluded keys are mapped to `Unsupported`, while all other keys use the library’s default components.
39
+ * Optionally override specific non‑excluded keys with custom components via `[key, component]` tuples.
40
+ *
41
+ * Exclusions take precedence over overrides.
42
+ *
43
+ * @function excludeRenderersOnly
44
+ * @param {Array<RendererKey>} excluded
45
+ * Renderer keys to exclude (set to `Unsupported`).
46
+ * @param {Array<[RendererKey, RendererComponent]>} [overrides]
47
+ * Optional tuples mapping non‑excluded keys to custom components.
48
+ * @returns {Partial<Renderers>} A renderer map with only the provided keys excluded.
49
+ * @example
50
+ * // Disable just paragraph and link, keep others as defaults
51
+ * const renderers = excludeRenderersOnly(['paragraph', 'link'])
52
+ *
53
+ * @example
54
+ * // Disable link; override paragraph to a custom component
55
+ * const renderers = excludeRenderersOnly(['link'], [['paragraph', MyParagraph]])
56
+ */
57
+ export declare const excludeRenderersOnly: (excluded: RendererKey[], overrides?: Array<[RendererKey, RendererComponent]>) => Partial<Renderers>;
@@ -0,0 +1,98 @@
1
+ import { Unsupported } from '../renderers/index.js';
2
+ import { defaultRenderers } from './markdown-parser.js';
3
+ import { rendererKeysInternal } from './rendererKeys.js';
4
+ const allRendererKeys = rendererKeysInternal;
5
+ /**
6
+ * Builds a map where every markdown renderer (excluding the special `html` map)
7
+ * is set to the `Unsupported` component.
8
+ *
9
+ * @function buildUnsupportedRenderers
10
+ * @returns {Partial<Renderers>} A map with all non‑HTML renderers set to `Unsupported`.
11
+ * @example
12
+ * import { buildUnsupportedRenderers } from '@humanspeak/svelte-markdown'
13
+ * const renderers = {
14
+ * ...buildUnsupportedRenderers(),
15
+ * html: {} // customize HTML separately
16
+ * }
17
+ */
18
+ export const buildUnsupportedRenderers = () => {
19
+ const result = {};
20
+ for (const key of allRendererKeys) {
21
+ result[key] = Unsupported;
22
+ }
23
+ return result;
24
+ };
25
+ /**
26
+ * Produces a renderer map that allows only the specified markdown renderers (excluding `html`).
27
+ * All non‑listed renderer keys are set to `Unsupported`.
28
+ * Each entry can be either a renderer key (to use the library’s default component),
29
+ * or a tuple `[key, component]` to specify a custom component for that key.
30
+ *
31
+ * @function allowRenderersOnly
32
+ * @param {Array<RendererKey | [RendererKey, RendererComponent]>} allowed
33
+ * Renderer keys to allow, or tuples for custom component overrides.
34
+ * @returns {Partial<Renderers>} A renderer map with only the provided keys enabled.
35
+ * @example
36
+ * // Allow only paragraph and link with defaults
37
+ * const renderers = allowRenderersOnly(['paragraph', 'link'])
38
+ *
39
+ * @example
40
+ * // Allow paragraph with a custom component
41
+ * const renderers = allowRenderersOnly([['paragraph', MyParagraph]])
42
+ */
43
+ export const allowRenderersOnly = (allowed) => {
44
+ const result = buildUnsupportedRenderers();
45
+ for (const entry of allowed) {
46
+ if (Array.isArray(entry)) {
47
+ const [key, component] = entry;
48
+ if (allRendererKeys.includes(key))
49
+ result[key] = component;
50
+ }
51
+ else {
52
+ const key = entry;
53
+ if (allRendererKeys.includes(key))
54
+ result[key] = defaultRenderers[key];
55
+ }
56
+ }
57
+ return result;
58
+ };
59
+ /**
60
+ * Produces a renderer map that excludes only the specified markdown renderer keys (excluding `html`).
61
+ * Excluded keys are mapped to `Unsupported`, while all other keys use the library’s default components.
62
+ * Optionally override specific non‑excluded keys with custom components via `[key, component]` tuples.
63
+ *
64
+ * Exclusions take precedence over overrides.
65
+ *
66
+ * @function excludeRenderersOnly
67
+ * @param {Array<RendererKey>} excluded
68
+ * Renderer keys to exclude (set to `Unsupported`).
69
+ * @param {Array<[RendererKey, RendererComponent]>} [overrides]
70
+ * Optional tuples mapping non‑excluded keys to custom components.
71
+ * @returns {Partial<Renderers>} A renderer map with only the provided keys excluded.
72
+ * @example
73
+ * // Disable just paragraph and link, keep others as defaults
74
+ * const renderers = excludeRenderersOnly(['paragraph', 'link'])
75
+ *
76
+ * @example
77
+ * // Disable link; override paragraph to a custom component
78
+ * const renderers = excludeRenderersOnly(['link'], [['paragraph', MyParagraph]])
79
+ */
80
+ export const excludeRenderersOnly = (excluded, overrides) => {
81
+ const result = {};
82
+ for (const key of allRendererKeys) {
83
+ result[key] = defaultRenderers[key];
84
+ }
85
+ for (const key of excluded) {
86
+ if (allRendererKeys.includes(key))
87
+ result[key] = Unsupported;
88
+ }
89
+ if (overrides) {
90
+ for (const [key, component] of overrides) {
91
+ if (excluded.includes(key))
92
+ continue;
93
+ if (allRendererKeys.includes(key))
94
+ result[key] = component;
95
+ }
96
+ }
97
+ return result;
98
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanspeak/svelte-markdown",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "description": "A powerful, customizable markdown renderer for Svelte with TypeScript support",
5
5
  "keywords": [
6
6
  "svelte",
@@ -58,6 +58,7 @@
58
58
  "lint": "prettier --check . && eslint .",
59
59
  "lint:fix": "npm run format && eslint . --fix",
60
60
  "package": "svelte-kit sync && svelte-package && publint",
61
+ "prepare": "husky",
61
62
  "prepublishOnly": "npm run package",
62
63
  "preview": "vite preview",
63
64
  "test": "vitest run --coverage",
@@ -77,40 +78,41 @@
77
78
  "dependencies": {
78
79
  "github-slugger": "^2.0.0",
79
80
  "htmlparser2": "^10.0.0",
80
- "marked": "^16.1.1"
81
+ "marked": "^16.1.2"
81
82
  },
82
83
  "devDependencies": {
83
- "@eslint/compat": "^1.3.1",
84
- "@eslint/js": "^9.32.0",
85
- "@playwright/test": "^1.54.1",
86
- "@sveltejs/adapter-auto": "^6.0.1",
87
- "@sveltejs/kit": "^2.26.1",
88
- "@sveltejs/package": "^2.4.0",
89
- "@sveltejs/vite-plugin-svelte": "^6.1.0",
84
+ "@eslint/compat": "^1.3.2",
85
+ "@eslint/js": "^9.33.0",
86
+ "@playwright/test": "^1.54.2",
87
+ "@sveltejs/adapter-auto": "^6.0.2",
88
+ "@sveltejs/kit": "^2.27.3",
89
+ "@sveltejs/package": "^2.4.1",
90
+ "@sveltejs/vite-plugin-svelte": "^6.1.1",
90
91
  "@testing-library/jest-dom": "^6.6.4",
91
92
  "@testing-library/svelte": "^5.2.8",
92
93
  "@testing-library/user-event": "^14.6.1",
93
- "@types/node": "^24.1.0",
94
- "@typescript-eslint/eslint-plugin": "^8.38.0",
95
- "@typescript-eslint/parser": "^8.38.0",
94
+ "@types/node": "^24.2.1",
95
+ "@typescript-eslint/eslint-plugin": "^8.39.0",
96
+ "@typescript-eslint/parser": "^8.39.0",
96
97
  "@vitest/coverage-v8": "^3.2.4",
97
- "eslint": "^9.32.0",
98
+ "eslint": "^9.33.0",
98
99
  "eslint-config-prettier": "^10.1.8",
99
100
  "eslint-plugin-import": "^2.32.0",
100
101
  "eslint-plugin-svelte": "^3.11.0",
101
102
  "eslint-plugin-unused-imports": "^4.1.4",
102
103
  "globals": "^16.3.0",
104
+ "husky": "^9.1.7",
103
105
  "jsdom": "^26.1.0",
104
106
  "prettier": "^3.6.2",
105
107
  "prettier-plugin-organize-imports": "^4.2.0",
106
108
  "prettier-plugin-svelte": "^3.4.0",
107
109
  "prettier-plugin-tailwindcss": "^0.6.14",
108
110
  "publint": "^0.3.12",
109
- "svelte": "^5.37.0",
110
- "svelte-check": "^4.3.0",
111
- "typescript": "^5.8.3",
112
- "typescript-eslint": "^8.38.0",
113
- "vite": "^7.0.6",
111
+ "svelte": "^5.38.0",
112
+ "svelte-check": "^4.3.1",
113
+ "typescript": "^5.9.2",
114
+ "typescript-eslint": "^8.39.0",
115
+ "vite": "^7.1.1",
114
116
  "vitest": "^3.2.4"
115
117
  },
116
118
  "peerDependencies": {