@humanspeak/svelte-markdown 0.7.20 → 0.8.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.
- package/README.md +11 -0
- package/dist/Parser.svelte +9 -8
- package/dist/Parser.svelte.d.ts +2 -2
- package/dist/SvelteMarkdown.svelte +5 -6
- package/dist/index.d.ts +3 -3
- package/dist/renderers/Heading.svelte +1 -1
- package/dist/renderers/Heading.svelte.d.ts +1 -1
- package/dist/renderers/RawText.svelte +8 -0
- package/dist/renderers/RawText.svelte.d.ts +6 -0
- package/dist/renderers/index.d.ts +1 -0
- package/dist/renderers/index.js +1 -0
- package/dist/types.d.ts +7 -3
- package/dist/utils/markdown-parser.d.ts +3 -45
- package/dist/utils/markdown-parser.js +8 -14
- package/package.json +17 -17
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ A powerful, customizable markdown renderer for Svelte with TypeScript support. B
|
|
|
24
24
|
- ♿ WCAG 2.1 accessibility compliance
|
|
25
25
|
- 🧪 Comprehensive test coverage (vitest and playwright)
|
|
26
26
|
- 🔄 Svelte 5 runes compatibility
|
|
27
|
+
- 🛡️ XSS protection and sanitization
|
|
27
28
|
|
|
28
29
|
## Installation
|
|
29
30
|
|
|
@@ -175,6 +176,7 @@ Seamlessly mix HTML and Markdown:
|
|
|
175
176
|
- `codespan` - Inline code (`<code>`)
|
|
176
177
|
- `code` - Block of code (`<pre><code>`)
|
|
177
178
|
- `html` - HTML node
|
|
179
|
+
- `rawtext` - All other text that is going to be included in an object above
|
|
178
180
|
|
|
179
181
|
### Optional List Renderers
|
|
180
182
|
|
|
@@ -242,6 +244,15 @@ The component emits a `parsed` event when tokens are calculated:
|
|
|
242
244
|
| options | `SvelteMarkdownOptions` | Marked parser configuration |
|
|
243
245
|
| isInline | `boolean` | Toggle inline parsing mode |
|
|
244
246
|
|
|
247
|
+
## Security
|
|
248
|
+
|
|
249
|
+
The package includes several security features:
|
|
250
|
+
|
|
251
|
+
- XSS protection through HTML sanitization
|
|
252
|
+
- Secure HTML parsing with HTMLParser2
|
|
253
|
+
- Safe handling of HTML entities
|
|
254
|
+
- Protection against malicious markdown injection
|
|
255
|
+
|
|
245
256
|
## License
|
|
246
257
|
|
|
247
258
|
MIT © [Humanspeak, Inc.](LICENSE)
|
package/dist/Parser.svelte
CHANGED
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
RendererComponent
|
|
54
54
|
} from './utils/markdown-parser.js'
|
|
55
55
|
|
|
56
|
-
interface Props {
|
|
56
|
+
interface Props<T extends Renderers = Renderers> {
|
|
57
57
|
type?: string
|
|
58
58
|
tokens?: Token[] | TokensList
|
|
59
59
|
header?: Tokens.TableCell[]
|
|
60
60
|
rows?: Tokens.TableCell[][]
|
|
61
61
|
ordered?: boolean
|
|
62
|
-
renderers:
|
|
62
|
+
renderers: T
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
const {
|
|
@@ -116,8 +116,9 @@
|
|
|
116
116
|
}}
|
|
117
117
|
{@const { tag, ...localRest } = token}
|
|
118
118
|
{@const htmlTag = tag as keyof typeof Html}
|
|
119
|
-
{#if htmlTag in renderers.html}
|
|
120
|
-
{@const HtmlComponent =
|
|
119
|
+
{#if renderers.html && htmlTag in renderers.html}
|
|
120
|
+
{@const HtmlComponent =
|
|
121
|
+
renderers.html[htmlTag as keyof typeof renderers.html]}
|
|
121
122
|
<HtmlComponent {...token}>
|
|
122
123
|
{#if token.tokens?.length}
|
|
123
124
|
<Parser
|
|
@@ -167,8 +168,8 @@
|
|
|
167
168
|
{:else if type === 'html'}
|
|
168
169
|
{@const { tag, ...localRest } = rest}
|
|
169
170
|
{@const htmlTag = rest.tag as keyof typeof Html}
|
|
170
|
-
{#if htmlTag in renderers.html}
|
|
171
|
-
{@const HtmlComponent = renderers.html[htmlTag]}
|
|
171
|
+
{#if renderers.html && htmlTag in renderers.html}
|
|
172
|
+
{@const HtmlComponent = renderers.html[htmlTag as keyof typeof renderers.html]}
|
|
172
173
|
{@const tokens = (rest.tokens as Token[]) ?? ([] as Token[])}
|
|
173
174
|
<HtmlComponent {...rest}>
|
|
174
175
|
{#if tokens.length}
|
|
@@ -189,13 +190,13 @@
|
|
|
189
190
|
/>
|
|
190
191
|
{/if}
|
|
191
192
|
{:else}
|
|
192
|
-
{@const GeneralComponent = renderers[type as keyof
|
|
193
|
+
{@const GeneralComponent = renderers[type as keyof typeof renderers] as RendererComponent}
|
|
193
194
|
<GeneralComponent {...rest}>
|
|
194
195
|
{#if tokens}
|
|
195
196
|
{@const { text: _text, raw: _raw, ...parserRest } = rest}
|
|
196
197
|
<Parser {tokens} {renderers} {...parserRest} />
|
|
197
198
|
{:else}
|
|
198
|
-
{rest.raw}
|
|
199
|
+
<renderers.rawtext text={rest.raw} />
|
|
199
200
|
{/if}
|
|
200
201
|
</GeneralComponent>
|
|
201
202
|
{/if}
|
package/dist/Parser.svelte.d.ts
CHANGED
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
*/
|
|
44
44
|
import Parser from './Parser.svelte';
|
|
45
45
|
import type { Renderers, Token, TokensList, Tokens } from './utils/markdown-parser.js';
|
|
46
|
-
interface Props {
|
|
46
|
+
interface Props<T extends Renderers = Renderers> {
|
|
47
47
|
type?: string;
|
|
48
48
|
tokens?: Token[] | TokensList;
|
|
49
49
|
header?: Tokens.TableCell[];
|
|
50
50
|
rows?: Tokens.TableCell[][];
|
|
51
51
|
ordered?: boolean;
|
|
52
|
-
renderers:
|
|
52
|
+
renderers: T;
|
|
53
53
|
}
|
|
54
54
|
type $$ComponentProps = Props & {
|
|
55
55
|
[key: string]: unknown;
|
|
@@ -46,23 +46,22 @@
|
|
|
46
46
|
* - Provides parsed callback for external token access
|
|
47
47
|
*/
|
|
48
48
|
|
|
49
|
+
import Parser from './Parser.svelte'
|
|
50
|
+
import { type SvelteMarkdownProps } from './types.js'
|
|
49
51
|
import {
|
|
50
|
-
Lexer,
|
|
51
52
|
defaultOptions,
|
|
52
53
|
defaultRenderers,
|
|
54
|
+
Lexer,
|
|
53
55
|
Slugger,
|
|
54
56
|
type Token,
|
|
55
|
-
type TokensList
|
|
56
|
-
type SvelteMarkdownOptions
|
|
57
|
+
type TokensList
|
|
57
58
|
} from './utils/markdown-parser.js'
|
|
58
|
-
import Parser from './Parser.svelte'
|
|
59
59
|
import { shrinkHtmlTokens } from './utils/token-cleanup.js'
|
|
60
|
-
import { type SvelteMarkdownProps } from './types.js'
|
|
61
60
|
|
|
62
61
|
const {
|
|
63
62
|
source = [],
|
|
64
63
|
renderers = {},
|
|
65
|
-
options = {}
|
|
64
|
+
options = {},
|
|
66
65
|
isInline = false,
|
|
67
66
|
parsed = () => {},
|
|
68
67
|
...rest
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RendererComponent, Renderers, Token, TokensList } from './utils/markdown-parser.js';
|
|
2
2
|
import SvelteMarkdown from './SvelteMarkdown.svelte';
|
|
3
|
-
import type { SvelteMarkdownProps } from './types.js';
|
|
3
|
+
import type { SvelteMarkdownOptions, SvelteMarkdownProps } from './types.js';
|
|
4
4
|
export default SvelteMarkdown;
|
|
5
|
-
export type { SvelteMarkdownOptions, SvelteMarkdownProps, Token, TokensList };
|
|
5
|
+
export type { RendererComponent, Renderers, SvelteMarkdownOptions, SvelteMarkdownProps, Token, TokensList };
|
|
@@ -12,6 +12,7 @@ export { default as Link } from './Link.svelte';
|
|
|
12
12
|
export { default as List } from './List.svelte';
|
|
13
13
|
export { default as ListItem } from './ListItem.svelte';
|
|
14
14
|
export { default as Paragraph } from './Paragraph.svelte';
|
|
15
|
+
export { default as RawText } from './RawText.svelte';
|
|
15
16
|
export { default as Strong } from './Strong.svelte';
|
|
16
17
|
export { default as Table } from './Table.svelte';
|
|
17
18
|
export { default as TableBody } from './TableBody.svelte';
|
package/dist/renderers/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { default as Link } from './Link.svelte';
|
|
|
12
12
|
export { default as List } from './List.svelte';
|
|
13
13
|
export { default as ListItem } from './ListItem.svelte';
|
|
14
14
|
export { default as Paragraph } from './Paragraph.svelte';
|
|
15
|
+
export { default as RawText } from './RawText.svelte';
|
|
15
16
|
export { default as Strong } from './Strong.svelte';
|
|
16
17
|
export { default as Table } from './Table.svelte';
|
|
17
18
|
export { default as TableBody } from './TableBody.svelte';
|
package/dist/types.d.ts
CHANGED
|
@@ -18,11 +18,15 @@
|
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
20
20
|
import type { Token, TokensList } from 'marked';
|
|
21
|
-
import type {
|
|
22
|
-
export type SvelteMarkdownProps = {
|
|
21
|
+
import type { MarkedOptions, Renderers } from './utils/markdown-parser.js';
|
|
22
|
+
export type SvelteMarkdownProps<T extends Renderers = Renderers> = {
|
|
23
23
|
source: Token[] | string;
|
|
24
|
-
renderers?: Partial<
|
|
24
|
+
renderers?: Partial<T>;
|
|
25
25
|
options?: Partial<SvelteMarkdownOptions>;
|
|
26
26
|
isInline?: boolean;
|
|
27
27
|
parsed?: (tokens: Token[] | TokensList) => void;
|
|
28
28
|
};
|
|
29
|
+
export interface SvelteMarkdownOptions extends MarkedOptions {
|
|
30
|
+
headerIds?: boolean;
|
|
31
|
+
headerPrefix?: string;
|
|
32
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { default as Slugger } from 'github-slugger';
|
|
2
|
-
export { Lexer, type Token, type Tokens, type TokensList } from 'marked';
|
|
2
|
+
export { Lexer, type MarkedOptions, type Token, type Tokens, type TokensList } from 'marked';
|
|
3
3
|
import type { Component } from 'svelte';
|
|
4
4
|
import { type HtmlRenderers } from '../renderers/html/index.js';
|
|
5
|
+
import type { SvelteMarkdownOptions } from '../types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Represents a Svelte component that can be used as a renderer.
|
|
7
8
|
* Allows for flexible component types while maintaining type safety.
|
|
@@ -24,6 +25,7 @@ export type RendererComponent = Component<any, any, any> | undefined | null;
|
|
|
24
25
|
*/
|
|
25
26
|
export type Renderers = {
|
|
26
27
|
html: HtmlRenderers;
|
|
28
|
+
rawtext: RendererComponent;
|
|
27
29
|
heading: RendererComponent;
|
|
28
30
|
paragraph: RendererComponent;
|
|
29
31
|
blockquote: RendererComponent;
|
|
@@ -59,50 +61,6 @@ export type Renderers = {
|
|
|
59
61
|
* @const {Renderers}
|
|
60
62
|
*/
|
|
61
63
|
export declare const defaultRenderers: Renderers;
|
|
62
|
-
/**
|
|
63
|
-
* Configuration options for SvelteMarkdown parser.
|
|
64
|
-
* Extends marked options with additional Svelte-specific configurations.
|
|
65
|
-
*
|
|
66
|
-
* @interface SvelteMarkdownOptions
|
|
67
|
-
*
|
|
68
|
-
* @property {string|null} baseUrl - Base URL for relative links
|
|
69
|
-
* @property {boolean} breaks - Enable line breaks in output
|
|
70
|
-
* @property {boolean} gfm - Enable GitHub Flavored Markdown
|
|
71
|
-
* @property {boolean} headerIds - Auto-generate header IDs
|
|
72
|
-
* @property {string} headerPrefix - Prefix for header IDs
|
|
73
|
-
* @property {Function|null} highlight - Syntax highlighting function
|
|
74
|
-
* @property {string} langPrefix - Prefix for code block language classes
|
|
75
|
-
* @property {boolean} mangle - Encode email addresses
|
|
76
|
-
* @property {boolean} pedantic - Conform to original markdown spec
|
|
77
|
-
* @property {Object|null} renderer - Custom renderer
|
|
78
|
-
* @property {boolean} sanitize - Sanitize HTML input
|
|
79
|
-
* @property {Function|null} sanitizer - Custom sanitizer function
|
|
80
|
-
* @property {boolean} silent - Suppress error output
|
|
81
|
-
* @property {boolean} smartLists - Use smarter list behavior
|
|
82
|
-
* @property {boolean} smartypants - Use smart punctuation
|
|
83
|
-
* @property {Object|null} tokenizer - Custom tokenizer
|
|
84
|
-
* @property {boolean} xhtml - Generate XHTML-compliant tags
|
|
85
|
-
*/
|
|
86
|
-
export type SvelteMarkdownOptions = {
|
|
87
|
-
baseUrl: string | null;
|
|
88
|
-
breaks: boolean;
|
|
89
|
-
gfm: boolean;
|
|
90
|
-
headerIds: boolean;
|
|
91
|
-
tables: boolean;
|
|
92
|
-
headerPrefix: string;
|
|
93
|
-
highlight: null;
|
|
94
|
-
langPrefix: string;
|
|
95
|
-
mangle: boolean;
|
|
96
|
-
pedantic: boolean;
|
|
97
|
-
renderer: null;
|
|
98
|
-
sanitize: boolean;
|
|
99
|
-
sanitizer: null;
|
|
100
|
-
silent: boolean;
|
|
101
|
-
smartLists: boolean;
|
|
102
|
-
smartypants: boolean;
|
|
103
|
-
tokenizer: null;
|
|
104
|
-
xhtml: boolean;
|
|
105
|
-
};
|
|
106
64
|
/**
|
|
107
65
|
* Default configuration options for the markdown parser.
|
|
108
66
|
* Provides sensible defaults while allowing for customization.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { default as Slugger } from 'github-slugger';
|
|
2
2
|
export { Lexer } from 'marked';
|
|
3
3
|
import {} from '../renderers/html/index.js';
|
|
4
|
-
import { Blockquote, Br, Code, Codespan, Del, Em, Heading, Hr, Html, Image, Link, List, ListItem, Paragraph, Strong, Table, TableBody, TableCell, TableHead, TableRow, Text } from '../renderers/index.js';
|
|
4
|
+
import { Blockquote, Br, Code, Codespan, Del, Em, Heading, Hr, Html, Image, Link, List, ListItem, Paragraph, RawText, Strong, Table, TableBody, TableCell, TableHead, TableRow, Text } from '../renderers/index.js';
|
|
5
5
|
/**
|
|
6
6
|
* Default renderer configuration mapping markdown elements to Svelte components.
|
|
7
7
|
* Provides out-of-the-box rendering capabilities while allowing for customization.
|
|
@@ -36,7 +36,8 @@ export const defaultRenderers = {
|
|
|
36
36
|
html: Html,
|
|
37
37
|
blockquote: Blockquote,
|
|
38
38
|
code: Code,
|
|
39
|
-
br: Br
|
|
39
|
+
br: Br,
|
|
40
|
+
rawtext: RawText
|
|
40
41
|
};
|
|
41
42
|
/**
|
|
42
43
|
* Default configuration options for the markdown parser.
|
|
@@ -52,22 +53,15 @@ export const defaultRenderers = {
|
|
|
52
53
|
* @const {SvelteMarkdownOptions}
|
|
53
54
|
*/
|
|
54
55
|
export const defaultOptions = {
|
|
55
|
-
|
|
56
|
+
async: false,
|
|
56
57
|
breaks: false,
|
|
57
58
|
gfm: true,
|
|
58
|
-
tables: true,
|
|
59
|
-
headerIds: true,
|
|
60
|
-
headerPrefix: '',
|
|
61
|
-
highlight: null,
|
|
62
|
-
langPrefix: 'language-',
|
|
63
|
-
mangle: true,
|
|
64
59
|
pedantic: false,
|
|
65
60
|
renderer: null,
|
|
66
|
-
sanitize: false,
|
|
67
|
-
sanitizer: null,
|
|
68
61
|
silent: false,
|
|
69
|
-
smartLists: false,
|
|
70
|
-
smartypants: false,
|
|
71
62
|
tokenizer: null,
|
|
72
|
-
|
|
63
|
+
walkTokens: null,
|
|
64
|
+
// Custom options
|
|
65
|
+
headerIds: true,
|
|
66
|
+
headerPrefix: ''
|
|
73
67
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@humanspeak/svelte-markdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A powerful, customizable markdown renderer for Svelte with TypeScript support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|
|
@@ -75,24 +75,24 @@
|
|
|
75
75
|
"marked": "^15.0.7"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@eslint/compat": "^1.2.
|
|
79
|
-
"@eslint/js": "^9.
|
|
78
|
+
"@eslint/compat": "^1.2.8",
|
|
79
|
+
"@eslint/js": "^9.24.0",
|
|
80
80
|
"@playwright/test": "^1.51.1",
|
|
81
|
-
"@sveltejs/adapter-auto": "^
|
|
82
|
-
"@sveltejs/kit": "^2.20.
|
|
81
|
+
"@sveltejs/adapter-auto": "^6.0.0",
|
|
82
|
+
"@sveltejs/kit": "^2.20.4",
|
|
83
83
|
"@sveltejs/package": "^2.3.10",
|
|
84
84
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
85
85
|
"@testing-library/jest-dom": "^6.6.3",
|
|
86
86
|
"@testing-library/svelte": "^5.2.7",
|
|
87
87
|
"@testing-library/user-event": "^14.6.1",
|
|
88
|
-
"@types/node": "^22.
|
|
89
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
90
|
-
"@typescript-eslint/parser": "^8.
|
|
91
|
-
"@vitest/coverage-v8": "^3.
|
|
92
|
-
"eslint": "^9.
|
|
88
|
+
"@types/node": "^22.14.0",
|
|
89
|
+
"@typescript-eslint/eslint-plugin": "^8.29.0",
|
|
90
|
+
"@typescript-eslint/parser": "^8.29.0",
|
|
91
|
+
"@vitest/coverage-v8": "^3.1.1",
|
|
92
|
+
"eslint": "^9.24.0",
|
|
93
93
|
"eslint-config-prettier": "^10.1.1",
|
|
94
94
|
"eslint-plugin-import": "^2.31.0",
|
|
95
|
-
"eslint-plugin-svelte": "^3.
|
|
95
|
+
"eslint-plugin-svelte": "^3.5.1",
|
|
96
96
|
"eslint-plugin-unused-imports": "^4.1.4",
|
|
97
97
|
"globals": "^16.0.0",
|
|
98
98
|
"jsdom": "^26.0.0",
|
|
@@ -100,13 +100,13 @@
|
|
|
100
100
|
"prettier-plugin-organize-imports": "^4.1.0",
|
|
101
101
|
"prettier-plugin-svelte": "^3.3.3",
|
|
102
102
|
"prettier-plugin-tailwindcss": "^0.6.11",
|
|
103
|
-
"publint": "^0.3.
|
|
104
|
-
"svelte": "^5.25.
|
|
103
|
+
"publint": "^0.3.10",
|
|
104
|
+
"svelte": "^5.25.7",
|
|
105
105
|
"svelte-check": "^4.1.5",
|
|
106
|
-
"typescript": "^5.8.
|
|
107
|
-
"typescript-eslint": "^8.
|
|
108
|
-
"vite": "^6.2.
|
|
109
|
-
"vitest": "^3.
|
|
106
|
+
"typescript": "^5.8.3",
|
|
107
|
+
"typescript-eslint": "^8.29.0",
|
|
108
|
+
"vite": "^6.2.5",
|
|
109
|
+
"vitest": "^3.1.1"
|
|
110
110
|
},
|
|
111
111
|
"peerDependencies": {
|
|
112
112
|
"svelte": "^5.0.0"
|