deno.land / x / lume@v2.1.4 / plugins / mdx.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import loader from "../core/loaders/text.ts";import { merge } from "../core/utils/object.ts";import { compile, remarkGfm } from "../deps/mdx.ts";import { join, toFileUrl } from "../deps/path.ts";
import type Site from "../core/site.ts";import type { Engine } from "../core/renderer.ts";import type { PluggableList, RehypeOptions } from "../deps/remark.ts";
export interface Options { /** List of extensions this plugin applies to */ extensions?: string[];
/** List of recma plugins to use */ recmaPlugins?: PluggableList;
/** * List of remark plugins to use * @default `[remarkGfm]` */ remarkPlugins?: PluggableList;
/** Options to pass to rehype */ rehypeOptions?: RehypeOptions;
/** List of rehype plugins to use */ rehypePlugins?: PluggableList;
/** Set `false` to remove the default plugins */ useDefaultPlugins?: boolean;
/** Components to add/override */ components?: Record<string, unknown>;
/** * Custom includes path * @default `site.options.includes` */ includes?: string;}
// Default optionsexport const defaults: Options = { extensions: [".mdx"], useDefaultPlugins: true,};
const remarkDefaultPlugins = [ remarkGfm,];
/** Template engine to render Markdown files with Remark */export class MDXEngine implements Engine<string | { toString(): string }> { baseUrl: string; options: Required<Options>; jsxEngine: Engine; includes: string;
constructor(baseUrl: string, options: Required<Options>, jsxEngine: Engine) { this.baseUrl = baseUrl; this.options = options; this.jsxEngine = jsxEngine; this.includes = options.includes; }
deleteCache() {}
async render( content: string, data?: Record<string, unknown>, filename?: string, ) { const baseUrl = toFileUrl(join(this.baseUrl, filename || "/")).href; // @ts-ignore: special case for jsx engines const pragma = `/** @jsxImportSource ${this.jsxEngine.jsxImportSource} */`; const result = await compile(content, { baseUrl, jsx: true, format: "mdx", outputFormat: "function-body", recmaPlugins: this.options.recmaPlugins, remarkPlugins: this.options.remarkPlugins, rehypePlugins: this.options.rehypePlugins, remarkRehypeOptions: this.options.rehypeOptions, });
const destructure = `{${Object.keys(data!).join(",")}}`; const code = result.toString() .replace("/*@jsxRuntime automatic*/\n/*@jsxImportSource react*/", pragma) .replace( '"use strict";\n', `export default async function (${destructure}) {`, ) + "}";
const url = URL.createObjectURL(new Blob([code], { type: "text/jsx" })); const module = (await import(url)).default; const mdxContext = (await module(data)).default; URL.revokeObjectURL(url);
const body = mdxContext({ components: { comp: data?.comp, ...this.options.components }, }); return this.jsxEngine.renderComponent(body); }
renderComponent(content: string) { return content; }
addHelper() {}}
/** Register the plugin to support MDX */export default function (userOptions?: Options) { return function (site: Site) { const options = merge( { ...defaults, includes: site.options.includes }, userOptions, );
if (options.useDefaultPlugins) { options.remarkPlugins ||= []; options.remarkPlugins.unshift(...remarkDefaultPlugins); }
// Get the JSX stringify const format = site.formats.get(".jsx") || site.formats.get(".tsx");
if (!format?.engines) { throw new Error( "The JSX format is required to use the MDX plugin. Use jsx or jsx_preact plugins.", ); }
const engine = new MDXEngine(site.src(), options, format.engines[0]);
// Ignore includes folder if (options.includes) { site.ignore(options.includes); }
// Load the pages and register the engine site.loadPages(options.extensions, { loader, engine, });
// Register the filter const filter = async ( content: string, data?: Record<string, unknown>, ): Promise<string> => (await engine.render(content, data)).toString().trim();
site.filter("mdx", filter, true); };}
/** Extends Helpers interface */declare global { namespace Lume { export interface Helpers { /** @see https://lume.land/plugins/mdx/ */ mdx: (content: string, data?: Record<string, unknown>) => Promise<string>; } }}
lume

Version Info

Tagged at
5 months ago