vite-plugin-svelte-md 0.3.0 → 0.4.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 +123 -4
- package/lib/markdown-it-svelte-curly-braces-escape/index.d.ts +2 -2
- package/lib/markdown-it-svelte-curly-braces-escape/index.js +6 -6
- package/lib/markdown-it-svelte-tags/index.d.ts +2 -2
- package/lib/markdown.d.ts +1 -1
- package/lib/markdown.js +5 -5
- package/lib/options.d.ts +15 -6
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ _`vite-plugin-svelte-md` is heavily inspired by [vite-plugin-md](https://github.
|
|
|
16
16
|
|
|
17
17
|
## 📛 Features
|
|
18
18
|
|
|
19
|
-
This plugin converts markdown files to Svelte component templates
|
|
19
|
+
This plugin converts markdown files to Svelte component templates.<br>
|
|
20
20
|
Combined with [the Svelte plugin](https://github.com/sveltejs/vite-plugin-svelte), you can convert markdown files to Svelte components.
|
|
21
21
|
|
|
22
22
|
For example, Input:
|
|
@@ -135,6 +135,7 @@ import svelteMd from "vite-plugin-svelte-md";
|
|
|
135
135
|
svelteMd({
|
|
136
136
|
headEnabled: true,
|
|
137
137
|
markdownItOptions: {},
|
|
138
|
+
use: (md) => { /* ... */ },
|
|
138
139
|
markdownItUses: [],
|
|
139
140
|
wrapperClasses: "markdown-body",
|
|
140
141
|
});
|
|
@@ -146,12 +147,28 @@ Enables head tag generation from frontmatter. The default is `true`.
|
|
|
146
147
|
|
|
147
148
|
#### `markdownItOptions`
|
|
148
149
|
|
|
149
|
-
[markdown-
|
|
150
|
-
See [markdown-
|
|
150
|
+
[markdown-exit](https://github.com/serkodev/markdown-exit)'s option.
|
|
151
|
+
See [markdown-exit's docs](https://markdown-exit.pages.dev/reference/api/Interface.MarkdownExitOptions.html) for more details.
|
|
152
|
+
|
|
153
|
+
markdown-exit is a TypeScript rewrite of [markdown-it](https://github.com/markdown-it/markdown-it), designed as a drop-in replacement. The name `markdownItOptions` was preserved for backwards compatibility.
|
|
154
|
+
|
|
155
|
+
#### `use`
|
|
156
|
+
|
|
157
|
+
A hook to register [markdown-exit](https://github.com/serkodev/markdown-exit) or [markdown-it](https://github.com/markdown-it/markdown-it) plugins, in a type-safe way.
|
|
158
|
+
|
|
159
|
+
Example:
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
svelteMd({
|
|
163
|
+
use: (md) => md.use(plugin1).use(plugin2, options),
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Note: you may encounter benign type errors when using markdown-it plugins that are not yet compatible with markdown-exit.
|
|
151
168
|
|
|
152
169
|
#### `markdownItUses`
|
|
153
170
|
|
|
154
|
-
An array of [markdown-it](https://github.com/markdown-it/markdown-it)
|
|
171
|
+
An array of [markdown-exit](https://github.com/serkodev/markdown-exit) or [markdown-it](https://github.com/markdown-it/markdown-it) plugins.
|
|
155
172
|
|
|
156
173
|
Example:
|
|
157
174
|
|
|
@@ -161,10 +178,112 @@ svelteMd({
|
|
|
161
178
|
});
|
|
162
179
|
```
|
|
163
180
|
|
|
181
|
+
You should favor `use` over `markdownItUses` as it enables better auto-completion and type-safety.
|
|
182
|
+
|
|
164
183
|
#### `wrapperClasses`
|
|
165
184
|
|
|
166
185
|
The class name of the div that wraps the content.
|
|
167
186
|
|
|
187
|
+
## 🎏 Comparison
|
|
188
|
+
|
|
189
|
+
`vite-plugin-svelte-md` is not the only library that converts Markdown to Svelte components:
|
|
190
|
+
|
|
191
|
+
<table>
|
|
192
|
+
<tr>
|
|
193
|
+
<th></th>
|
|
194
|
+
<th>
|
|
195
|
+
<a href="https://github.com/ota-meshi/vite-plugin-svelte-md">ota-meshi/vite-plugin-svelte-md</a>
|
|
196
|
+
</th>
|
|
197
|
+
<th>
|
|
198
|
+
<a href="https://github.com/pngwn/MDsveX">pngwn/MDsveX</a>
|
|
199
|
+
</th>
|
|
200
|
+
</tr>
|
|
201
|
+
<tr>
|
|
202
|
+
<td>Popularity</td>
|
|
203
|
+
<td><a href="https://npmx.dev/package/vite-plugin-svelte-md"><img alt="NPM Downloads" src="https://img.shields.io/npm/dw/vite-plugin-svelte-md?style=flat-square&color=d73d36"></a> <a href="https://github.com/ota-meshi/vite-plugin-svelte-md"><img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/ota-meshi/vite-plugin-svelte-md?style=flat-square&color=eac54f"></a></td>
|
|
204
|
+
<td><a href="https://npmx.dev/package/mdsvex"><img alt="NPM Downloads" src="https://img.shields.io/npm/dw/mdsvex?style=flat-square&color=d73d36"></a> <a href="https://github.com/pngwn/MDsveX"><img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/pngwn/MDsveX?style=flat-square&color=eac54f"></a></td>
|
|
205
|
+
</tr>
|
|
206
|
+
<tr>
|
|
207
|
+
<td>License</td>
|
|
208
|
+
<td><a href="https://github.com/ota-meshi/vite-plugin-svelte-md/blob/main/LICENSE">MIT</a></td>
|
|
209
|
+
<td><a href="https://github.com/pngwn/MDsveX/blob/main/LICENSE">MIT</a></td>
|
|
210
|
+
</tr>
|
|
211
|
+
<tr>
|
|
212
|
+
<th colspan="3">Architecture</th>
|
|
213
|
+
</tr>
|
|
214
|
+
<tr>
|
|
215
|
+
<td>Markdown parser</td>
|
|
216
|
+
<td><a href="https://npmx.dev/package/markdown-exit">markdown-exit</a> (supports sync and async plugins)</td>
|
|
217
|
+
<td><a href="https://npmx.dev/package/remark">remark</a> + <a href="https://npmx.dev/package/rehype">rehype</a> (supports plugins)</td>
|
|
218
|
+
</tr>
|
|
219
|
+
<tr>
|
|
220
|
+
<td>Transformation step</td>
|
|
221
|
+
<td>Vite plugin (compatible with other Vite plugins, e.g. <a href="https://svelte.dev/docs/kit/images#sveltejs-enhanced-img"><code>@sveltejs/enhanced-img</code></a>)</td>
|
|
222
|
+
<td>Svelte preprocessor</td>
|
|
223
|
+
</tr>
|
|
224
|
+
<tr>
|
|
225
|
+
<th colspan="3">Features</th>
|
|
226
|
+
</tr>
|
|
227
|
+
<tr>
|
|
228
|
+
<td>Frontmatter</td>
|
|
229
|
+
<td><a href="https://npmx.dev/package/gray-matter">✅ (YAML, JSON or JS)</a><br>
|
|
230
|
+
Accessible through <code>{frontmatter.variable}</code></td>
|
|
231
|
+
<td>✅ (YAML, <a href="https://mdsvex.pngwn.io/docs#frontmatter">can be changed</a>)<br>
|
|
232
|
+
Accessible through <code>{variable}</code>
|
|
233
|
+
</td>
|
|
234
|
+
</tr>
|
|
235
|
+
<tr>
|
|
236
|
+
<td><code><head></code> tag generation</td>
|
|
237
|
+
<td>✅ (from frontmatter, <a href="#headenabled">can be disabled</a>)</td>
|
|
238
|
+
<td>⚙️ (possible with layouts)</td>
|
|
239
|
+
</tr>
|
|
240
|
+
<tr>
|
|
241
|
+
<td>Syntax highlighting</td>
|
|
242
|
+
<td>⚙️ (bring your own in <a href="https://github.com/markdown-it/markdown-it#syntax-highlighting"><code>markdownItOptions.highlight</code></a>)</td>
|
|
243
|
+
<td>✅ (defaults to <a href="https://github.com/PrismJS/prism/">Prism</a>, <a href="https://mdsvex.pngwn.io/docs#highlight">can be changed</a>)</td>
|
|
244
|
+
</tr>
|
|
245
|
+
<tr>
|
|
246
|
+
<td>Replace any HTML tag after Markdown processing</td>
|
|
247
|
+
<td>❌</td>
|
|
248
|
+
<td><a href="https://mdsvex.pngwn.io/docs#custom-components">✅</a></td>
|
|
249
|
+
</tr>
|
|
250
|
+
<tr>
|
|
251
|
+
<td>Layout</td>
|
|
252
|
+
<td>Optional wrapper <code><div></code> with classes</td>
|
|
253
|
+
<td>Svelte components, configurable in frontmatter</td>
|
|
254
|
+
</td>
|
|
255
|
+
<tr>
|
|
256
|
+
<td>Fancy typography replacements<br>(e.g. <code>...</code> → <code>…</code>)</td>
|
|
257
|
+
<td>✅</td>
|
|
258
|
+
<td>✅</td>
|
|
259
|
+
</tr>
|
|
260
|
+
<tr>
|
|
261
|
+
<td>+page.md (in SvelteKit)</td>
|
|
262
|
+
<td>✅</td>
|
|
263
|
+
<td>✅</td>
|
|
264
|
+
</tr>
|
|
265
|
+
</table>
|
|
266
|
+
|
|
267
|
+
## 🍊 Svelte Compatibility
|
|
268
|
+
|
|
269
|
+
You might encounter issues with markdown-it plugins that produce invalid Svelte code, e.g. a TeX plugin that outputs unescaped `{` and `}` characters. In this case, the simplest workaround is to wrap the plugin output in a Svelte [`{@html ...}`](https://svelte.dev/docs/svelte/@html) tag:
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
import { tex } from '@mdit/plugin-tex';
|
|
273
|
+
import katex from 'katex';
|
|
274
|
+
|
|
275
|
+
mdSvelte({
|
|
276
|
+
use: (md) =>
|
|
277
|
+
md.use(tex, {
|
|
278
|
+
// `katex.renderToString` produces HTML with unescaped `{` and `}` characters,
|
|
279
|
+
// wrap its output with {@html JSON.stringify(...)} to avoid Svelte parsing errors.
|
|
280
|
+
render: (content, displayMode) =>
|
|
281
|
+
`{@html ${JSON.stringify(katex.renderToString(content, { displayMode }))}}`,
|
|
282
|
+
}),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
|
|
168
287
|
## :beers: Contributing
|
|
169
288
|
|
|
170
289
|
Welcome contributing!
|
|
@@ -4,15 +4,15 @@ import { escapeBraces } from "../utils.js";
|
|
|
4
4
|
*/
|
|
5
5
|
export default function plugin(md) {
|
|
6
6
|
const originalCodeBlock = md.renderer.rules.code_block;
|
|
7
|
-
md.renderer.rules.code_block = (...args) => {
|
|
8
|
-
return escapeBraces(originalCodeBlock(...args));
|
|
7
|
+
md.renderer.rules.code_block = async (...args) => {
|
|
8
|
+
return escapeBraces(await originalCodeBlock(...args));
|
|
9
9
|
};
|
|
10
10
|
const originalCodeInline = md.renderer.rules.code_inline;
|
|
11
|
-
md.renderer.rules.code_inline = (...args) => {
|
|
12
|
-
return escapeBraces(originalCodeInline(...args));
|
|
11
|
+
md.renderer.rules.code_inline = async (...args) => {
|
|
12
|
+
return escapeBraces(await originalCodeInline(...args));
|
|
13
13
|
};
|
|
14
14
|
const originalFence = md.renderer.rules.fence;
|
|
15
|
-
md.renderer.rules.fence = (...args) => {
|
|
16
|
-
return escapeBraces(originalFence(...args));
|
|
15
|
+
md.renderer.rules.fence = async (...args) => {
|
|
16
|
+
return escapeBraces(await originalFence(...args));
|
|
17
17
|
};
|
|
18
18
|
}
|
package/lib/markdown.d.ts
CHANGED
package/lib/markdown.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createMarkdownExit } from "markdown-exit";
|
|
2
2
|
import grayMatter from "gray-matter";
|
|
3
3
|
import markdownItSvelteTags from "./markdown-it-svelte-tags/index.js";
|
|
4
4
|
import markdownItSvelteCurlyBracesEscape from "./markdown-it-svelte-curly-braces-escape/index.js";
|
|
@@ -69,14 +69,13 @@ function parseHtml(html) {
|
|
|
69
69
|
* Creates md processor
|
|
70
70
|
*/
|
|
71
71
|
export function createMarkdownProcessor(options) {
|
|
72
|
-
const markdownIt =
|
|
72
|
+
const markdownIt = createMarkdownExit({
|
|
73
73
|
html: true,
|
|
74
74
|
linkify: true,
|
|
75
75
|
typographer: true,
|
|
76
76
|
...options.markdownItOptions,
|
|
77
77
|
});
|
|
78
78
|
markdownIt.linkify.set({ fuzzyLink: false });
|
|
79
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method -- ignore
|
|
80
79
|
const originalValidateLink = markdownIt.validateLink;
|
|
81
80
|
markdownIt.validateLink = (url) => {
|
|
82
81
|
if (!originalValidateLink(url)) {
|
|
@@ -85,16 +84,17 @@ export function createMarkdownProcessor(options) {
|
|
|
85
84
|
return !IS_SVELTE_TAG_NAME_RE.test(url);
|
|
86
85
|
};
|
|
87
86
|
markdownIt.use(markdownItSvelteTags).use(markdownItSvelteCurlyBracesEscape);
|
|
87
|
+
options.use?.(markdownIt);
|
|
88
88
|
options.markdownItUses.forEach((e) => {
|
|
89
89
|
const [plugin, ...opts] = toArray(e);
|
|
90
90
|
markdownIt.use(plugin, ...opts);
|
|
91
91
|
});
|
|
92
|
-
return (id, text) => {
|
|
92
|
+
return async (id, text) => {
|
|
93
93
|
const raw = text.trimEnd();
|
|
94
94
|
const { wrapperClasses, headEnabled } = options;
|
|
95
95
|
const parsedFrontmatter = grayMatter(raw);
|
|
96
96
|
const plainMarkdown = parsedFrontmatter?.content ?? raw;
|
|
97
|
-
let html = markdownIt.
|
|
97
|
+
let html = await markdownIt.renderAsync(plainMarkdown, { id });
|
|
98
98
|
if (wrapperClasses) {
|
|
99
99
|
html = `<div class="${wrapperClasses}">${html}</div>`;
|
|
100
100
|
}
|
package/lib/options.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type { MarkdownExit, MarkdownExitOptions } from "markdown-exit";
|
|
2
2
|
export interface Options {
|
|
3
3
|
/**
|
|
4
4
|
* Enable head support
|
|
@@ -7,13 +7,22 @@ export interface Options {
|
|
|
7
7
|
*/
|
|
8
8
|
headEnabled?: boolean;
|
|
9
9
|
/**
|
|
10
|
-
* Options passed to Markdown
|
|
10
|
+
* Options passed to Markdown Exit
|
|
11
11
|
*/
|
|
12
|
-
markdownItOptions?:
|
|
12
|
+
markdownItOptions?: MarkdownExitOptions;
|
|
13
13
|
/**
|
|
14
|
-
* Plugins for Markdown
|
|
14
|
+
* Plugins for Markdown Exit
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* use: (md) => md.use(plugin1).use(plugin2, options)
|
|
18
|
+
*/
|
|
19
|
+
use?: (md: MarkdownExit) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Plugins for Markdown Exit
|
|
22
|
+
*
|
|
23
|
+
* Prefer the `use` option for better type safety
|
|
15
24
|
*/
|
|
16
|
-
markdownItUses?:
|
|
25
|
+
markdownItUses?: any[];
|
|
17
26
|
/**
|
|
18
27
|
* Class names for wrapper div
|
|
19
28
|
*
|
|
@@ -23,7 +32,7 @@ export interface Options {
|
|
|
23
32
|
include?: (string | RegExp)[] | string | RegExp | undefined;
|
|
24
33
|
exclude?: (string | RegExp)[] | string | RegExp | undefined;
|
|
25
34
|
}
|
|
26
|
-
export type ResolvedOptions = Required<Omit<Options, "include" | "exclude">> & Pick<Options, "include" | "exclude"> & {
|
|
35
|
+
export type ResolvedOptions = Required<Omit<Options, "include" | "exclude" | "use">> & Pick<Options, "include" | "exclude" | "use"> & {
|
|
27
36
|
wrapperClasses: string;
|
|
28
37
|
};
|
|
29
38
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-svelte-md",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vite plugin to convert markdown to svelte template",
|
|
6
6
|
"files": [
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"vite-plugin",
|
|
41
41
|
"svelte",
|
|
42
42
|
"markdown",
|
|
43
|
-
"markdown-it"
|
|
43
|
+
"markdown-it",
|
|
44
|
+
"markdown-exit"
|
|
44
45
|
],
|
|
45
46
|
"author": "Yosuke Ota",
|
|
46
47
|
"funding": "https://github.com/sponsors/ota-meshi",
|
|
@@ -53,8 +54,10 @@
|
|
|
53
54
|
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
57
|
+
"@types/linkify-it": "^5.0.0",
|
|
58
|
+
"@types/mdurl": "^2.0.0",
|
|
56
59
|
"gray-matter": "^4.0.3",
|
|
57
|
-
"markdown-
|
|
60
|
+
"markdown-exit": "^1.0.0-beta.8"
|
|
58
61
|
},
|
|
59
62
|
"devDependencies": {
|
|
60
63
|
"@changesets/cli": "^2.29.5",
|
|
@@ -62,7 +65,6 @@
|
|
|
62
65
|
"@ota-meshi/eslint-plugin": "^0.20.0",
|
|
63
66
|
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
|
|
64
67
|
"@types/escape-html": "^1.0.1",
|
|
65
|
-
"@types/markdown-it": "^14.0.0",
|
|
66
68
|
"@types/node": "^24.0.0",
|
|
67
69
|
"@types/prismjs": "^1.16.6",
|
|
68
70
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
@@ -73,9 +75,9 @@
|
|
|
73
75
|
"eslint-config-prettier": "^10.0.0",
|
|
74
76
|
"eslint-plugin-jsdoc": "^62.0.0",
|
|
75
77
|
"eslint-plugin-json-schema-validator": "^6.0.0",
|
|
76
|
-
"eslint-plugin-jsonc": "^
|
|
78
|
+
"eslint-plugin-jsonc": "^3.0.0",
|
|
77
79
|
"eslint-plugin-n": "^17.0.0",
|
|
78
|
-
"eslint-plugin-node-dependencies": "^
|
|
80
|
+
"eslint-plugin-node-dependencies": "^2.0.0",
|
|
79
81
|
"eslint-plugin-prettier": "^5.0.0",
|
|
80
82
|
"eslint-plugin-regexp": "^3.0.0",
|
|
81
83
|
"prettier": "^3.0.0",
|