@livemark/vite 0.0.0-stage → 0.44.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.md +9 -0
- package/README.md +21 -2
- package/build/index.d.ts +28 -0
- package/build/index.js +74 -0
- package/build/react.d.ts +2 -0
- package/build/react.js +3 -0
- package/package.json +45 -3
- package/source/env.d.ts +14 -0
- package/source/index.ts +104 -0
- package/source/react.ts +2 -0
- package/source/styles.css +1 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright © 2025 Evgeny Karev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @livemark/vite
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Render Markdown and MDX with Livemark's pipeline and article components in any Vite app: import
|
|
4
|
+
a `.md` or `.mdx` file and render it with the same callouts, tabs, code blocks and cards as a
|
|
5
|
+
[Livemark](https://livemark.dev) site.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
// vite.config.ts
|
|
9
|
+
import markdown from "@livemark/vite"
|
|
10
|
+
|
|
11
|
+
export default { plugins: [markdown({ allowDangerousHtml: false })] }
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import Post, { frontmatter, toc } from "./post.md"
|
|
16
|
+
|
|
17
|
+
export function PostPage() {
|
|
18
|
+
return <Post />
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Docs: [livemark.dev/markdown-vite-plugin](https://livemark.dev/markdown-vite-plugin/)
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { MarkdownPlugins } from "@livemark/markdown/models/plugins.ts";
|
|
2
|
+
import type { CodeThemeDark, CodeThemeLight } from "@livemark/markdown/models/theme.ts";
|
|
3
|
+
import type { Plugin } from "vite";
|
|
4
|
+
type IdPattern = string | RegExp;
|
|
5
|
+
/** Options of the `markdown` Vite plugin. */
|
|
6
|
+
export interface MarkdownPluginOptions {
|
|
7
|
+
/** The module ids compiled, as globs or patterns; `.md` and `.mdx` files when unset. */
|
|
8
|
+
include?: IdPattern | IdPattern[];
|
|
9
|
+
/** The module ids left alone, as globs or patterns. */
|
|
10
|
+
exclude?: IdPattern | IdPattern[];
|
|
11
|
+
/** The Shiki theme of code in light mode; Livemark's default when unset. */
|
|
12
|
+
codeThemeLight?: CodeThemeLight;
|
|
13
|
+
/** The Shiki theme of code in dark mode; Livemark's default when unset. */
|
|
14
|
+
codeThemeDark?: CodeThemeDark;
|
|
15
|
+
/** Plugins on the Markdown (`md`) and HTML (`html`) trees, as in a Livemark config. */
|
|
16
|
+
plugins?: MarkdownPlugins;
|
|
17
|
+
/** Keep raw HTML and allow MDX; `false` drops raw HTML and refuses MDX. @default true */
|
|
18
|
+
allowDangerousHtml?: boolean;
|
|
19
|
+
/** The directory image URLs count from; images keep their URLs when unset. */
|
|
20
|
+
root?: string;
|
|
21
|
+
/** The URL the app is served at, put before every root-relative image URL. */
|
|
22
|
+
base?: string;
|
|
23
|
+
}
|
|
24
|
+
/** A Vite plugin compiling imported Markdown and MDX with Livemark's pipeline into
|
|
25
|
+
* modules whose `default` renders with Livemark's components, plus `frontmatter` and
|
|
26
|
+
* `toc`. A `.mdx` file, or one whose frontmatter sets `format: mdx`, is MDX. */
|
|
27
|
+
export declare function markdown(options?: MarkdownPluginOptions): Plugin;
|
|
28
|
+
export default markdown;
|
package/build/index.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { compileMarkdown, detectMarkdownFormat, } from "@livemark/markdown/actions/markdown/compile.ts";
|
|
3
|
+
import { DIRECTIVE_NAMES } from "@livemark/markdown/actions/processor/create.ts";
|
|
4
|
+
import { findContentWarnings } from "@livemark/markdown/helpers/content-warnings.ts";
|
|
5
|
+
import { parseFrontmatter } from "@livemark/markdown/helpers/frontmatter.ts";
|
|
6
|
+
/** A Vite plugin compiling imported Markdown and MDX with Livemark's pipeline into
|
|
7
|
+
* modules whose `default` renders with Livemark's components, plus `frontmatter` and
|
|
8
|
+
* `toc`. A `.mdx` file, or one whose frontmatter sets `format: mdx`, is MDX. */
|
|
9
|
+
export function markdown(options = {}) {
|
|
10
|
+
return {
|
|
11
|
+
name: "livemark:markdown",
|
|
12
|
+
enforce: "pre",
|
|
13
|
+
// Its components ship as TypeScript, which Node cannot run from node_modules
|
|
14
|
+
config: () => ({ ssr: { noExternal: [MARKDOWN_PACKAGE] } }),
|
|
15
|
+
// The emitted modules import @livemark/markdown, a dependency of this package that
|
|
16
|
+
// an app under pnpm cannot resolve itself
|
|
17
|
+
resolveId: {
|
|
18
|
+
filter: { id: /^@livemark\/markdown\// },
|
|
19
|
+
handler(id) {
|
|
20
|
+
return this.resolve(id, PLUGIN_FILE, { skipSelf: true });
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
transform: {
|
|
24
|
+
filter: { id: { include: options.include ?? /\.mdx?$/, exclude: options.exclude } },
|
|
25
|
+
async handler(source, id) {
|
|
26
|
+
const document = parseFrontmatter(source);
|
|
27
|
+
const directives = DIRECTIVE_NAMES;
|
|
28
|
+
for (const warning of findContentWarnings({
|
|
29
|
+
text: source,
|
|
30
|
+
filePath: id,
|
|
31
|
+
directives,
|
|
32
|
+
})) {
|
|
33
|
+
this.warn(`${id}: ${warning}`);
|
|
34
|
+
}
|
|
35
|
+
const compiled = await compileMarkdown({
|
|
36
|
+
content: document.content,
|
|
37
|
+
filePath: id,
|
|
38
|
+
format: detectMarkdownFormat({
|
|
39
|
+
filePath: id,
|
|
40
|
+
format: Reflect.get(document.data, "format"),
|
|
41
|
+
}),
|
|
42
|
+
outputFormat: "program",
|
|
43
|
+
options,
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
code: wrapContent({ ...compiled, frontmatter: document.data }),
|
|
47
|
+
map: null,
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export default markdown;
|
|
54
|
+
const MARKDOWN_PACKAGE = "@livemark/markdown";
|
|
55
|
+
const MARKDOWN_MODULE = `${MARKDOWN_PACKAGE}/components/Markdown`;
|
|
56
|
+
const PLUGIN_FILE = fileURLToPath(import.meta.url);
|
|
57
|
+
const CONTENT_EXPORT = "export default function MDXContent(";
|
|
58
|
+
// The default export renders through <Markdown>, which supplies Livemark's components
|
|
59
|
+
// and the outline `:::toc` reads; MDX's own content function becomes its `component`
|
|
60
|
+
function wrapContent(props) {
|
|
61
|
+
if (!props.code.includes(CONTENT_EXPORT))
|
|
62
|
+
throw new Error("MDX emitted no MDXContent");
|
|
63
|
+
return [
|
|
64
|
+
props.code.replace(CONTENT_EXPORT, "function MDXContent("),
|
|
65
|
+
'import { jsx as __lmJsx } from "react/jsx-runtime"',
|
|
66
|
+
`import { Markdown as __LmMarkdown } from ${JSON.stringify(MARKDOWN_MODULE)}`,
|
|
67
|
+
`export const frontmatter = ${JSON.stringify(props.frontmatter)}`,
|
|
68
|
+
`export const toc = ${JSON.stringify(props.toc)}`,
|
|
69
|
+
"export default function MarkdownContent(props = {}) {",
|
|
70
|
+
" return __lmJsx(__LmMarkdown, { component: MDXContent, toc, components: props.components })",
|
|
71
|
+
"}",
|
|
72
|
+
].join("\n");
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUN4QyxPQUFPLEVBQ0wsZUFBZSxFQUNmLG9CQUFvQixHQUNyQixNQUFNLGdEQUFnRCxDQUFBO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQTtBQUNoRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQTtBQUNwRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQTtBQTJCNUU7O2lGQUVpRjtBQUNqRixNQUFNLFVBQVUsUUFBUSxDQUFDLE9BQU8sR0FBMEIsRUFBRTtJQUMxRCxPQUFPO1FBQ0wsSUFBSSxFQUFFLG1CQUFtQjtRQUN6QixPQUFPLEVBQUUsS0FBSztRQUNkLDZFQUE2RTtRQUM3RSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLFVBQVUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzNELG1GQUFtRjtRQUNuRiwwQ0FBMEM7UUFDMUMsU0FBUyxFQUFFO1lBQ1QsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLHdCQUF3QixFQUFFO1lBQ3hDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7WUFDMUQsQ0FBQztTQUNGO1FBQ0QsU0FBUyxFQUFFO1lBQ1QsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUksU0FBUyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbkYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDdEIsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUE7Z0JBQ3pDLE1BQU0sVUFBVSxHQUFHLGVBQWUsQ0FBQTtnQkFDbEMsS0FBSyxNQUFNLE9BQU8sSUFBSSxtQkFBbUIsQ0FBQztvQkFDeEMsSUFBSSxFQUFFLE1BQU07b0JBQ1osUUFBUSxFQUFFLEVBQUU7b0JBQ1osVUFBVTtpQkFDWCxDQUFDLEVBQUUsQ0FBQztvQkFDSCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLE9BQU8sRUFBRSxDQUFDLENBQUE7Z0JBQ2hDLENBQUM7Z0JBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxlQUFlLENBQUM7b0JBQ3JDLE9BQU8sRUFBRSxRQUFRLENBQUMsT0FBTztvQkFDekIsUUFBUSxFQUFFLEVBQUU7b0JBQ1osTUFBTSxFQUFFLG9CQUFvQixDQUFDO3dCQUMzQixRQUFRLEVBQUUsRUFBRTt3QkFDWixNQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztxQkFDN0MsQ0FBQztvQkFDRixZQUFZLEVBQUUsU0FBUztvQkFDdkIsT0FBTztpQkFDUixDQUFDLENBQUE7Z0JBQ0YsT0FBTztvQkFDTCxJQUFJLEVBQUUsV0FBVyxDQUFDLEVBQUUsR0FBRyxRQUFRLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDOUQsR0FBRyxFQUFFLElBQUk7aUJBQ1YsQ0FBQTtZQUNILENBQUM7U0FDRjtLQUNGLENBQUE7QUFDSCxDQUFDO0FBRUQsZUFBZSxRQUFRLENBQUE7QUFFdkIsTUFBTSxnQkFBZ0IsR0FBRyxvQkFBb0IsQ0FBQTtBQUM3QyxNQUFNLGVBQWUsR0FBRyxHQUFHLGdCQUFnQixzQkFBc0IsQ0FBQTtBQUNqRSxNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7QUFDbEQsTUFBTSxjQUFjLEdBQUcscUNBQXFDLENBQUE7QUFFNUQsc0ZBQXNGO0FBQ3RGLHFGQUFxRjtBQUNyRixTQUFTLFdBQVcsQ0FBQyxLQUEwRDtJQUM3RSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFBO0lBQ3RGLE9BQU87UUFDTCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsc0JBQXNCLENBQUM7UUFDMUQsb0RBQW9EO1FBQ3BELDRDQUE0QyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFO1FBQzdFLDhCQUE4QixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRTtRQUNqRSxzQkFBc0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDakQsdURBQXVEO1FBQ3ZELDhGQUE4RjtRQUM5RixHQUFHO0tBQ0osQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gXCJub2RlOnVybFwiXG5pbXBvcnQge1xuICBjb21waWxlTWFya2Rvd24sXG4gIGRldGVjdE1hcmtkb3duRm9ybWF0LFxufSBmcm9tIFwiQGxpdmVtYXJrL21hcmtkb3duL2FjdGlvbnMvbWFya2Rvd24vY29tcGlsZS50c1wiXG5pbXBvcnQgeyBESVJFQ1RJVkVfTkFNRVMgfSBmcm9tIFwiQGxpdmVtYXJrL21hcmtkb3duL2FjdGlvbnMvcHJvY2Vzc29yL2NyZWF0ZS50c1wiXG5pbXBvcnQgeyBmaW5kQ29udGVudFdhcm5pbmdzIH0gZnJvbSBcIkBsaXZlbWFyay9tYXJrZG93bi9oZWxwZXJzL2NvbnRlbnQtd2FybmluZ3MudHNcIlxuaW1wb3J0IHsgcGFyc2VGcm9udG1hdHRlciB9IGZyb20gXCJAbGl2ZW1hcmsvbWFya2Rvd24vaGVscGVycy9mcm9udG1hdHRlci50c1wiXG5pbXBvcnQgdHlwZSB7IE1hcmtkb3duUGx1Z2lucyB9IGZyb20gXCJAbGl2ZW1hcmsvbWFya2Rvd24vbW9kZWxzL3BsdWdpbnMudHNcIlxuaW1wb3J0IHR5cGUgeyBDb2RlVGhlbWVEYXJrLCBDb2RlVGhlbWVMaWdodCB9IGZyb20gXCJAbGl2ZW1hcmsvbWFya2Rvd24vbW9kZWxzL3RoZW1lLnRzXCJcbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSBcInZpdGVcIlxuXG50eXBlIElkUGF0dGVybiA9IHN0cmluZyB8IFJlZ0V4cFxuXG4vKiogT3B0aW9ucyBvZiB0aGUgYG1hcmtkb3duYCBWaXRlIHBsdWdpbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFya2Rvd25QbHVnaW5PcHRpb25zIHtcbiAgLyoqIFRoZSBtb2R1bGUgaWRzIGNvbXBpbGVkLCBhcyBnbG9icyBvciBwYXR0ZXJuczsgYC5tZGAgYW5kIGAubWR4YCBmaWxlcyB3aGVuIHVuc2V0LiAqL1xuICBpbmNsdWRlPzogSWRQYXR0ZXJuIHwgSWRQYXR0ZXJuW11cbiAgLyoqIFRoZSBtb2R1bGUgaWRzIGxlZnQgYWxvbmUsIGFzIGdsb2JzIG9yIHBhdHRlcm5zLiAqL1xuICBleGNsdWRlPzogSWRQYXR0ZXJuIHwgSWRQYXR0ZXJuW11cbiAgLyoqIFRoZSBTaGlraSB0aGVtZSBvZiBjb2RlIGluIGxpZ2h0IG1vZGU7IExpdmVtYXJrJ3MgZGVmYXVsdCB3aGVuIHVuc2V0LiAqL1xuICBjb2RlVGhlbWVMaWdodD86IENvZGVUaGVtZUxpZ2h0XG4gIC8qKiBUaGUgU2hpa2kgdGhlbWUgb2YgY29kZSBpbiBkYXJrIG1vZGU7IExpdmVtYXJrJ3MgZGVmYXVsdCB3aGVuIHVuc2V0LiAqL1xuICBjb2RlVGhlbWVEYXJrPzogQ29kZVRoZW1lRGFya1xuICAvKiogUGx1Z2lucyBvbiB0aGUgTWFya2Rvd24gKGBtZGApIGFuZCBIVE1MIChgaHRtbGApIHRyZWVzLCBhcyBpbiBhIExpdmVtYXJrIGNvbmZpZy4gKi9cbiAgcGx1Z2lucz86IE1hcmtkb3duUGx1Z2luc1xuICAvKiogS2VlcCByYXcgSFRNTCBhbmQgYWxsb3cgTURYOyBgZmFsc2VgIGRyb3BzIHJhdyBIVE1MIGFuZCByZWZ1c2VzIE1EWC4gQGRlZmF1bHQgdHJ1ZSAqL1xuICBhbGxvd0Rhbmdlcm91c0h0bWw/OiBib29sZWFuXG4gIC8qKiBUaGUgZGlyZWN0b3J5IGltYWdlIFVSTHMgY291bnQgZnJvbTsgaW1hZ2VzIGtlZXAgdGhlaXIgVVJMcyB3aGVuIHVuc2V0LiAqL1xuICByb290Pzogc3RyaW5nXG4gIC8qKiBUaGUgVVJMIHRoZSBhcHAgaXMgc2VydmVkIGF0LCBwdXQgYmVmb3JlIGV2ZXJ5IHJvb3QtcmVsYXRpdmUgaW1hZ2UgVVJMLiAqL1xuICBiYXNlPzogc3RyaW5nXG59XG5cbi8qKiBBIFZpdGUgcGx1Z2luIGNvbXBpbGluZyBpbXBvcnRlZCBNYXJrZG93biBhbmQgTURYIHdpdGggTGl2ZW1hcmsncyBwaXBlbGluZSBpbnRvXG4gKiAgbW9kdWxlcyB3aG9zZSBgZGVmYXVsdGAgcmVuZGVycyB3aXRoIExpdmVtYXJrJ3MgY29tcG9uZW50cywgcGx1cyBgZnJvbnRtYXR0ZXJgIGFuZFxuICogIGB0b2NgLiBBIGAubWR4YCBmaWxlLCBvciBvbmUgd2hvc2UgZnJvbnRtYXR0ZXIgc2V0cyBgZm9ybWF0OiBtZHhgLCBpcyBNRFguICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2Rvd24ob3B0aW9uczogTWFya2Rvd25QbHVnaW5PcHRpb25zID0ge30pOiBQbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IFwibGl2ZW1hcms6bWFya2Rvd25cIixcbiAgICBlbmZvcmNlOiBcInByZVwiLFxuICAgIC8vIEl0cyBjb21wb25lbnRzIHNoaXAgYXMgVHlwZVNjcmlwdCwgd2hpY2ggTm9kZSBjYW5ub3QgcnVuIGZyb20gbm9kZV9tb2R1bGVzXG4gICAgY29uZmlnOiAoKSA9PiAoeyBzc3I6IHsgbm9FeHRlcm5hbDogW01BUktET1dOX1BBQ0tBR0VdIH0gfSksXG4gICAgLy8gVGhlIGVtaXR0ZWQgbW9kdWxlcyBpbXBvcnQgQGxpdmVtYXJrL21hcmtkb3duLCBhIGRlcGVuZGVuY3kgb2YgdGhpcyBwYWNrYWdlIHRoYXRcbiAgICAvLyBhbiBhcHAgdW5kZXIgcG5wbSBjYW5ub3QgcmVzb2x2ZSBpdHNlbGZcbiAgICByZXNvbHZlSWQ6IHtcbiAgICAgIGZpbHRlcjogeyBpZDogL15AbGl2ZW1hcmtcXC9tYXJrZG93blxcLy8gfSxcbiAgICAgIGhhbmRsZXIoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZShpZCwgUExVR0lOX0ZJTEUsIHsgc2tpcFNlbGY6IHRydWUgfSlcbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cmFuc2Zvcm06IHtcbiAgICAgIGZpbHRlcjogeyBpZDogeyBpbmNsdWRlOiBvcHRpb25zLmluY2x1ZGUgPz8gL1xcLm1keD8kLywgZXhjbHVkZTogb3B0aW9ucy5leGNsdWRlIH0gfSxcbiAgICAgIGFzeW5jIGhhbmRsZXIoc291cmNlLCBpZCkge1xuICAgICAgICBjb25zdCBkb2N1bWVudCA9IHBhcnNlRnJvbnRtYXR0ZXIoc291cmNlKVxuICAgICAgICBjb25zdCBkaXJlY3RpdmVzID0gRElSRUNUSVZFX05BTUVTXG4gICAgICAgIGZvciAoY29uc3Qgd2FybmluZyBvZiBmaW5kQ29udGVudFdhcm5pbmdzKHtcbiAgICAgICAgICB0ZXh0OiBzb3VyY2UsXG4gICAgICAgICAgZmlsZVBhdGg6IGlkLFxuICAgICAgICAgIGRpcmVjdGl2ZXMsXG4gICAgICAgIH0pKSB7XG4gICAgICAgICAgdGhpcy53YXJuKGAke2lkfTogJHt3YXJuaW5nfWApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcGlsZWQgPSBhd2FpdCBjb21waWxlTWFya2Rvd24oe1xuICAgICAgICAgIGNvbnRlbnQ6IGRvY3VtZW50LmNvbnRlbnQsXG4gICAgICAgICAgZmlsZVBhdGg6IGlkLFxuICAgICAgICAgIGZvcm1hdDogZGV0ZWN0TWFya2Rvd25Gb3JtYXQoe1xuICAgICAgICAgICAgZmlsZVBhdGg6IGlkLFxuICAgICAgICAgICAgZm9ybWF0OiBSZWZsZWN0LmdldChkb2N1bWVudC5kYXRhLCBcImZvcm1hdFwiKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBvdXRwdXRGb3JtYXQ6IFwicHJvZ3JhbVwiLFxuICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29kZTogd3JhcENvbnRlbnQoeyAuLi5jb21waWxlZCwgZnJvbnRtYXR0ZXI6IGRvY3VtZW50LmRhdGEgfSksXG4gICAgICAgICAgbWFwOiBudWxsLFxuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbWFya2Rvd25cblxuY29uc3QgTUFSS0RPV05fUEFDS0FHRSA9IFwiQGxpdmVtYXJrL21hcmtkb3duXCJcbmNvbnN0IE1BUktET1dOX01PRFVMRSA9IGAke01BUktET1dOX1BBQ0tBR0V9L2NvbXBvbmVudHMvTWFya2Rvd25gXG5jb25zdCBQTFVHSU5fRklMRSA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKVxuY29uc3QgQ09OVEVOVF9FWFBPUlQgPSBcImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1EWENvbnRlbnQoXCJcblxuLy8gVGhlIGRlZmF1bHQgZXhwb3J0IHJlbmRlcnMgdGhyb3VnaCA8TWFya2Rvd24+LCB3aGljaCBzdXBwbGllcyBMaXZlbWFyaydzIGNvbXBvbmVudHNcbi8vIGFuZCB0aGUgb3V0bGluZSBgOjo6dG9jYCByZWFkczsgTURYJ3Mgb3duIGNvbnRlbnQgZnVuY3Rpb24gYmVjb21lcyBpdHMgYGNvbXBvbmVudGBcbmZ1bmN0aW9uIHdyYXBDb250ZW50KHByb3BzOiB7IGNvZGU6IHN0cmluZzsgdG9jOiB1bmtub3duOyBmcm9udG1hdHRlcjogb2JqZWN0IH0pIHtcbiAgaWYgKCFwcm9wcy5jb2RlLmluY2x1ZGVzKENPTlRFTlRfRVhQT1JUKSkgdGhyb3cgbmV3IEVycm9yKFwiTURYIGVtaXR0ZWQgbm8gTURYQ29udGVudFwiKVxuICByZXR1cm4gW1xuICAgIHByb3BzLmNvZGUucmVwbGFjZShDT05URU5UX0VYUE9SVCwgXCJmdW5jdGlvbiBNRFhDb250ZW50KFwiKSxcbiAgICAnaW1wb3J0IHsganN4IGFzIF9fbG1Kc3ggfSBmcm9tIFwicmVhY3QvanN4LXJ1bnRpbWVcIicsXG4gICAgYGltcG9ydCB7IE1hcmtkb3duIGFzIF9fTG1NYXJrZG93biB9IGZyb20gJHtKU09OLnN0cmluZ2lmeShNQVJLRE9XTl9NT0RVTEUpfWAsXG4gICAgYGV4cG9ydCBjb25zdCBmcm9udG1hdHRlciA9ICR7SlNPTi5zdHJpbmdpZnkocHJvcHMuZnJvbnRtYXR0ZXIpfWAsXG4gICAgYGV4cG9ydCBjb25zdCB0b2MgPSAke0pTT04uc3RyaW5naWZ5KHByb3BzLnRvYyl9YCxcbiAgICBcImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1hcmtkb3duQ29udGVudChwcm9wcyA9IHt9KSB7XCIsXG4gICAgXCIgIHJldHVybiBfX2xtSnN4KF9fTG1NYXJrZG93biwgeyBjb21wb25lbnQ6IE1EWENvbnRlbnQsIHRvYywgY29tcG9uZW50czogcHJvcHMuY29tcG9uZW50cyB9KVwiLFxuICAgIFwifVwiLFxuICBdLmpvaW4oXCJcXG5cIilcbn1cbiJdfQ==
|
package/build/react.d.ts
ADDED
package/build/react.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { IconsProvider } from "@livemark/markdown/hooks/icons";
|
|
2
|
+
export { MessagesProvider } from "@livemark/markdown/hooks/messages";
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvcmVhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBZ0IsTUFBTSxnQ0FBZ0MsQ0FBQTtBQUM1RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IEljb25zUHJvdmlkZXIsIHR5cGUgSWNvbk1hcCB9IGZyb20gXCJAbGl2ZW1hcmsvbWFya2Rvd24vaG9va3MvaWNvbnNcIlxuZXhwb3J0IHsgTWVzc2FnZXNQcm92aWRlciB9IGZyb20gXCJAbGl2ZW1hcmsvbWFya2Rvd24vaG9va3MvbWVzc2FnZXNcIlxuIl19
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livemark/vite",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.44.2",
|
|
4
|
+
"description": "Render Markdown and MDX with Livemark's pipeline and components in any Vite app",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Evgeny Karev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/datisthq/livemark",
|
|
10
|
+
"directory": "vite"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"build",
|
|
14
|
+
"source",
|
|
15
|
+
"!source/**/*.unit.ts",
|
|
16
|
+
"!source/**/fixtures"
|
|
17
|
+
],
|
|
18
|
+
"type": "module",
|
|
19
|
+
"sideEffects": [
|
|
20
|
+
"*.css"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./build/index.d.ts",
|
|
25
|
+
"default": "./build/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./react": "./source/react.ts",
|
|
28
|
+
"./env": "./source/env.d.ts",
|
|
29
|
+
"./styles.css": "./source/styles.css"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@livemark/markdown": "0.44.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"lucide-react": "0.577.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": "^19.0.0",
|
|
39
|
+
"react-dom": "^19.0.0",
|
|
40
|
+
"vite": "8.3.4"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": "^24.11.0"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsgo --project tsconfig.build.json"
|
|
47
|
+
}
|
|
6
48
|
}
|
package/source/env.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare module "*.md" {
|
|
2
|
+
/** The compiled content, rendered with Livemark's components. */
|
|
3
|
+
const Content: import("react").ComponentType<{ components?: object }>
|
|
4
|
+
export default Content
|
|
5
|
+
export const frontmatter: Record<string, unknown>
|
|
6
|
+
export const toc: import("@livemark/markdown/models/toc.ts").TocItem[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module "*.mdx" {
|
|
10
|
+
const Content: import("react").ComponentType<{ components?: object }>
|
|
11
|
+
export default Content
|
|
12
|
+
export const frontmatter: Record<string, unknown>
|
|
13
|
+
export const toc: import("@livemark/markdown/models/toc.ts").TocItem[]
|
|
14
|
+
}
|
package/source/index.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url"
|
|
2
|
+
import {
|
|
3
|
+
compileMarkdown,
|
|
4
|
+
detectMarkdownFormat,
|
|
5
|
+
} from "@livemark/markdown/actions/markdown/compile.ts"
|
|
6
|
+
import { DIRECTIVE_NAMES } from "@livemark/markdown/actions/processor/create.ts"
|
|
7
|
+
import { findContentWarnings } from "@livemark/markdown/helpers/content-warnings.ts"
|
|
8
|
+
import { parseFrontmatter } from "@livemark/markdown/helpers/frontmatter.ts"
|
|
9
|
+
import type { MarkdownPlugins } from "@livemark/markdown/models/plugins.ts"
|
|
10
|
+
import type { CodeThemeDark, CodeThemeLight } from "@livemark/markdown/models/theme.ts"
|
|
11
|
+
import type { Plugin } from "vite"
|
|
12
|
+
|
|
13
|
+
type IdPattern = string | RegExp
|
|
14
|
+
|
|
15
|
+
/** Options of the `markdown` Vite plugin. */
|
|
16
|
+
export interface MarkdownPluginOptions {
|
|
17
|
+
/** The module ids compiled, as globs or patterns; `.md` and `.mdx` files when unset. */
|
|
18
|
+
include?: IdPattern | IdPattern[]
|
|
19
|
+
/** The module ids left alone, as globs or patterns. */
|
|
20
|
+
exclude?: IdPattern | IdPattern[]
|
|
21
|
+
/** The Shiki theme of code in light mode; Livemark's default when unset. */
|
|
22
|
+
codeThemeLight?: CodeThemeLight
|
|
23
|
+
/** The Shiki theme of code in dark mode; Livemark's default when unset. */
|
|
24
|
+
codeThemeDark?: CodeThemeDark
|
|
25
|
+
/** Plugins on the Markdown (`md`) and HTML (`html`) trees, as in a Livemark config. */
|
|
26
|
+
plugins?: MarkdownPlugins
|
|
27
|
+
/** Keep raw HTML and allow MDX; `false` drops raw HTML and refuses MDX. @default true */
|
|
28
|
+
allowDangerousHtml?: boolean
|
|
29
|
+
/** The directory image URLs count from; images keep their URLs when unset. */
|
|
30
|
+
root?: string
|
|
31
|
+
/** The URL the app is served at, put before every root-relative image URL. */
|
|
32
|
+
base?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A Vite plugin compiling imported Markdown and MDX with Livemark's pipeline into
|
|
36
|
+
* modules whose `default` renders with Livemark's components, plus `frontmatter` and
|
|
37
|
+
* `toc`. A `.mdx` file, or one whose frontmatter sets `format: mdx`, is MDX. */
|
|
38
|
+
export function markdown(options: MarkdownPluginOptions = {}): Plugin {
|
|
39
|
+
return {
|
|
40
|
+
name: "livemark:markdown",
|
|
41
|
+
enforce: "pre",
|
|
42
|
+
// Its components ship as TypeScript, which Node cannot run from node_modules
|
|
43
|
+
config: () => ({ ssr: { noExternal: [MARKDOWN_PACKAGE] } }),
|
|
44
|
+
// The emitted modules import @livemark/markdown, a dependency of this package that
|
|
45
|
+
// an app under pnpm cannot resolve itself
|
|
46
|
+
resolveId: {
|
|
47
|
+
filter: { id: /^@livemark\/markdown\// },
|
|
48
|
+
handler(id) {
|
|
49
|
+
return this.resolve(id, PLUGIN_FILE, { skipSelf: true })
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
transform: {
|
|
53
|
+
filter: { id: { include: options.include ?? /\.mdx?$/, exclude: options.exclude } },
|
|
54
|
+
async handler(source, id) {
|
|
55
|
+
const document = parseFrontmatter(source)
|
|
56
|
+
const directives = DIRECTIVE_NAMES
|
|
57
|
+
for (const warning of findContentWarnings({
|
|
58
|
+
text: source,
|
|
59
|
+
filePath: id,
|
|
60
|
+
directives,
|
|
61
|
+
})) {
|
|
62
|
+
this.warn(`${id}: ${warning}`)
|
|
63
|
+
}
|
|
64
|
+
const compiled = await compileMarkdown({
|
|
65
|
+
content: document.content,
|
|
66
|
+
filePath: id,
|
|
67
|
+
format: detectMarkdownFormat({
|
|
68
|
+
filePath: id,
|
|
69
|
+
format: Reflect.get(document.data, "format"),
|
|
70
|
+
}),
|
|
71
|
+
outputFormat: "program",
|
|
72
|
+
options,
|
|
73
|
+
})
|
|
74
|
+
return {
|
|
75
|
+
code: wrapContent({ ...compiled, frontmatter: document.data }),
|
|
76
|
+
map: null,
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default markdown
|
|
84
|
+
|
|
85
|
+
const MARKDOWN_PACKAGE = "@livemark/markdown"
|
|
86
|
+
const MARKDOWN_MODULE = `${MARKDOWN_PACKAGE}/components/Markdown`
|
|
87
|
+
const PLUGIN_FILE = fileURLToPath(import.meta.url)
|
|
88
|
+
const CONTENT_EXPORT = "export default function MDXContent("
|
|
89
|
+
|
|
90
|
+
// The default export renders through <Markdown>, which supplies Livemark's components
|
|
91
|
+
// and the outline `:::toc` reads; MDX's own content function becomes its `component`
|
|
92
|
+
function wrapContent(props: { code: string; toc: unknown; frontmatter: object }) {
|
|
93
|
+
if (!props.code.includes(CONTENT_EXPORT)) throw new Error("MDX emitted no MDXContent")
|
|
94
|
+
return [
|
|
95
|
+
props.code.replace(CONTENT_EXPORT, "function MDXContent("),
|
|
96
|
+
'import { jsx as __lmJsx } from "react/jsx-runtime"',
|
|
97
|
+
`import { Markdown as __LmMarkdown } from ${JSON.stringify(MARKDOWN_MODULE)}`,
|
|
98
|
+
`export const frontmatter = ${JSON.stringify(props.frontmatter)}`,
|
|
99
|
+
`export const toc = ${JSON.stringify(props.toc)}`,
|
|
100
|
+
"export default function MarkdownContent(props = {}) {",
|
|
101
|
+
" return __lmJsx(__LmMarkdown, { component: MDXContent, toc, components: props.components })",
|
|
102
|
+
"}",
|
|
103
|
+
].join("\n")
|
|
104
|
+
}
|
package/source/react.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "@livemark/markdown/standalone.css";
|