@rasenganjs/mdx 1.2.0-beta.7 → 1.2.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/CHANGELOG.md +4 -0
- package/dist/chunk-U2MZHTHK.js +89 -0
- package/dist/index.cjs +922 -0
- package/dist/index.d.cts +150 -0
- package/dist/index.d.ts +150 -0
- package/dist/index.js +798 -0
- package/dist/plugin.cjs +289 -0
- package/dist/plugin.d.cts +20 -0
- package/dist/plugin.d.ts +20 -0
- package/dist/plugin.js +174 -0
- package/package.json +15 -15
- package/tsup.config.ts +11 -0
- package/types/client.d.ts +1 -1
- package/lib/components/codeblock.d.ts +0 -15
- package/lib/components/codeblock.js +0 -62
- package/lib/components/codeblock.js.map +0 -1
- package/lib/components/codeblock2.d.ts +0 -14
- package/lib/components/codeblock2.js +0 -47
- package/lib/components/codeblock2.js.map +0 -1
- package/lib/components/heading.d.ts +0 -2
- package/lib/components/heading.js +0 -27
- package/lib/components/heading.js.map +0 -1
- package/lib/components/index.d.ts +0 -5
- package/lib/components/index.js +0 -8
- package/lib/components/index.js.map +0 -1
- package/lib/components/markdown.d.ts +0 -7
- package/lib/components/markdown.js +0 -28
- package/lib/components/markdown.js.map +0 -1
- package/lib/components/renderer.d.ts +0 -12
- package/lib/components/renderer.js +0 -45
- package/lib/components/renderer.js.map +0 -1
- package/lib/components/table.d.ts +0 -3
- package/lib/components/table.js +0 -5
- package/lib/components/table.js.map +0 -1
- package/lib/components/toc.d.ts +0 -7
- package/lib/components/toc.js +0 -26
- package/lib/components/toc.js.map +0 -1
- package/lib/hooks/use-toc-observer.d.ts +0 -8
- package/lib/hooks/use-toc-observer.js +0 -60
- package/lib/hooks/use-toc-observer.js.map +0 -1
- package/lib/index.d.ts +0 -13
- package/lib/index.js +0 -16
- package/lib/index.js.map +0 -1
- package/lib/styles/rasengan-mdx.min.css +0 -1
- package/lib/types/index.d.ts +0 -67
- package/lib/types/index.js +0 -2
- package/lib/types/index.js.map +0 -1
- package/lib/utils/create-filter.d.ts +0 -8
- package/lib/utils/create-filter.js +0 -23
- package/lib/utils/create-filter.js.map +0 -1
- package/lib/utils/create-heading.d.ts +0 -4
- package/lib/utils/create-heading.js +0 -19
- package/lib/utils/create-heading.js.map +0 -1
- package/lib/utils/define-mdx-config.d.ts +0 -2
- package/lib/utils/define-mdx-config.js +0 -4
- package/lib/utils/define-mdx-config.js.map +0 -1
- package/lib/utils/extract-toc.d.ts +0 -23
- package/lib/utils/extract-toc.js +0 -113
- package/lib/utils/extract-toc.js.map +0 -1
- package/lib/utils/generate-navigation.d.ts +0 -0
- package/lib/utils/generate-navigation.js +0 -75
- package/lib/utils/generate-navigation.js.map +0 -1
- package/lib/utils/index.d.ts +0 -15
- package/lib/utils/index.js +0 -4
- package/lib/utils/index.js.map +0 -1
- package/lib/utils/mark-to-html.d.ts +0 -1
- package/lib/utils/mark-to-html.js +0 -15
- package/lib/utils/mark-to-html.js.map +0 -1
- package/lib/utils/plugin.d.ts +0 -26
- package/lib/utils/plugin.js +0 -149
- package/lib/utils/plugin.js.map +0 -1
- package/lib/utils/polyfill.d.ts +0 -10
- package/lib/utils/polyfill.js +0 -15
- package/lib/utils/polyfill.js.map +0 -1
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/plugin.ts
|
|
30
|
+
var plugin_exports = {};
|
|
31
|
+
__export(plugin_exports, {
|
|
32
|
+
default: () => plugin_default
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(plugin_exports);
|
|
35
|
+
|
|
36
|
+
// src/utils/plugin.ts
|
|
37
|
+
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
38
|
+
|
|
39
|
+
// src/utils/create-filter.ts
|
|
40
|
+
var import_micromatch = __toESM(require("micromatch"), 1);
|
|
41
|
+
function createFilter(include, exclude) {
|
|
42
|
+
return function(id) {
|
|
43
|
+
if (typeof id !== "string") return false;
|
|
44
|
+
const matcher = import_micromatch.default.matcher(include);
|
|
45
|
+
if (exclude) {
|
|
46
|
+
const excluder = import_micromatch.default.matcher(exclude);
|
|
47
|
+
return matcher(id) && !excluder(id);
|
|
48
|
+
} else {
|
|
49
|
+
return matcher(id);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/utils/plugin.ts
|
|
55
|
+
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
56
|
+
var import_rehype_stringify = __toESM(require("rehype-stringify"), 1);
|
|
57
|
+
var import_remark_parse = __toESM(require("remark-parse"), 1);
|
|
58
|
+
var import_remark_rehype = __toESM(require("remark-rehype"), 1);
|
|
59
|
+
var import_rehype_pretty_code = __toESM(require("rehype-pretty-code"), 1);
|
|
60
|
+
|
|
61
|
+
// src/utils/extract-toc.ts
|
|
62
|
+
var import_react = __toESM(require("react"), 1);
|
|
63
|
+
function extractTOC(markdown) {
|
|
64
|
+
const lines = markdown.split("\n");
|
|
65
|
+
const toc = [];
|
|
66
|
+
lines.forEach((line) => {
|
|
67
|
+
const h2Match = line.match(/^## (.+)/);
|
|
68
|
+
const h3Match = line.match(/^### (.+)/);
|
|
69
|
+
if (h2Match) {
|
|
70
|
+
const title = h2Match[1].trim();
|
|
71
|
+
const anchor = generateAnchor(title);
|
|
72
|
+
toc.push({
|
|
73
|
+
title,
|
|
74
|
+
anchor,
|
|
75
|
+
level: 2,
|
|
76
|
+
children: []
|
|
77
|
+
});
|
|
78
|
+
} else if (h3Match && toc.length > 0) {
|
|
79
|
+
const title = h3Match[1].trim();
|
|
80
|
+
const anchor = generateAnchor(title);
|
|
81
|
+
toc[toc.length - 1].children.push({
|
|
82
|
+
title,
|
|
83
|
+
anchor,
|
|
84
|
+
level: 3
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return toc;
|
|
89
|
+
}
|
|
90
|
+
var generateAnchor = (title) => {
|
|
91
|
+
if (Array.isArray(title)) {
|
|
92
|
+
const text2 = title.map((item) => {
|
|
93
|
+
if (import_react.default.isValidElement(item)) {
|
|
94
|
+
return item.props["children"].toString().trim();
|
|
95
|
+
}
|
|
96
|
+
return item.toString().trim();
|
|
97
|
+
}).join(" ");
|
|
98
|
+
const lastItem = title[title.length - 1];
|
|
99
|
+
if (typeof lastItem === "string") {
|
|
100
|
+
const match1 = text2.match(/\s\[#([^\]]+)\]$/);
|
|
101
|
+
if (match1) {
|
|
102
|
+
return {
|
|
103
|
+
id: match1[1],
|
|
104
|
+
// remove the last element from title
|
|
105
|
+
text: title.slice(0, title.length - 1)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
id: text2.replace(/\s+/g, "-").toLowerCase(),
|
|
111
|
+
text: title
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (import_react.default.isValidElement(title)) {
|
|
115
|
+
return {
|
|
116
|
+
id: title.props["children"].toString().trim().replace(/\s+/g, "-").toLowerCase(),
|
|
117
|
+
text: title
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const strippedTitle = String(toText(title).trim());
|
|
121
|
+
const match = strippedTitle.match(/\s\[#([^\]]+)\]$/);
|
|
122
|
+
let id;
|
|
123
|
+
let text;
|
|
124
|
+
if (match) {
|
|
125
|
+
id = match[1].trim().replace(/\s+/g, "-").toLowerCase();
|
|
126
|
+
text = strippedTitle.replace(match[0], "").trim();
|
|
127
|
+
} else {
|
|
128
|
+
id = strippedTitle.replace(/\s+/g, "-").toLowerCase();
|
|
129
|
+
text = strippedTitle;
|
|
130
|
+
}
|
|
131
|
+
return { id, text };
|
|
132
|
+
};
|
|
133
|
+
function toText(input) {
|
|
134
|
+
if (input == null) return "";
|
|
135
|
+
if (typeof input === "string") return input;
|
|
136
|
+
if (Array.isArray(input)) return input.map(toText).join(" ");
|
|
137
|
+
if (input instanceof Uint8Array)
|
|
138
|
+
return new TextDecoder().decode(input);
|
|
139
|
+
try {
|
|
140
|
+
return String(input);
|
|
141
|
+
} catch {
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/utils/plugin.ts
|
|
147
|
+
async function plugin(options) {
|
|
148
|
+
const mdx = (await import("@mdx-js/rollup")).default;
|
|
149
|
+
const userConfig = {
|
|
150
|
+
rehypePlugins: options?.rehypePlugins ?? [],
|
|
151
|
+
remarkPlugins: options?.rehypePlugins ?? [],
|
|
152
|
+
code: {
|
|
153
|
+
theme: options?.code?.theme ?? {
|
|
154
|
+
light: "one-light",
|
|
155
|
+
dark: "one-dark-pro"
|
|
156
|
+
},
|
|
157
|
+
keepBackground: options?.code?.keepBackground ?? true
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
let config;
|
|
161
|
+
const filter = createFilter("**/*.md?(x)");
|
|
162
|
+
const mdxInstance = mdx({
|
|
163
|
+
remarkPlugins: [import_remark_parse.default, import_remark_gfm.default, ...userConfig.remarkPlugins],
|
|
164
|
+
rehypePlugins: [
|
|
165
|
+
import_remark_rehype.default,
|
|
166
|
+
import_rehype_stringify.default,
|
|
167
|
+
[
|
|
168
|
+
import_rehype_pretty_code.default,
|
|
169
|
+
{
|
|
170
|
+
theme: userConfig.code.theme,
|
|
171
|
+
keepBackground: userConfig.code.keepBackground
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
// Developer rehype plugin list
|
|
175
|
+
...userConfig.rehypePlugins
|
|
176
|
+
]
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
name: "vite-plugin-rasengan-mdx",
|
|
180
|
+
// Apply transformation of the mdx file before other plugins
|
|
181
|
+
enforce: "pre",
|
|
182
|
+
config(config2, env) {
|
|
183
|
+
mdxInstance.config(config2, env);
|
|
184
|
+
},
|
|
185
|
+
/**
|
|
186
|
+
* Stores the resolved Vite configuration for later use.
|
|
187
|
+
*
|
|
188
|
+
* @param resolvedConfig - The resolved Vite configuration object.
|
|
189
|
+
*/
|
|
190
|
+
configResolved(resolvedConfig) {
|
|
191
|
+
config = resolvedConfig;
|
|
192
|
+
},
|
|
193
|
+
/**
|
|
194
|
+
* Transforms an MDX file by applying the `@mdx-js/rollup` transformation, extracting frontmatter data, and appending a `metadata` object to the transformed content.
|
|
195
|
+
*
|
|
196
|
+
* @param code - The content of the MDX file.
|
|
197
|
+
* @param id - The ID of the MDX file.
|
|
198
|
+
* @returns An object containing the transformed MDX code and a source map, or `null` if the file is not an MDX file.
|
|
199
|
+
*/
|
|
200
|
+
async transform(code, id) {
|
|
201
|
+
if (!filter(id)) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
const { content, data: frontmatter } = (0, import_gray_matter.default)(code);
|
|
205
|
+
const isTocVisible = frontmatter.toc !== void 0 ? frontmatter.toc : false;
|
|
206
|
+
const toc = extractTOC(content);
|
|
207
|
+
const result = await mdxInstance.transform(content, id);
|
|
208
|
+
const fileName = id.split("/").pop().replace(/.page.mdx?$/, "");
|
|
209
|
+
const metadata = {
|
|
210
|
+
path: frontmatter.path || `/${fileName}`,
|
|
211
|
+
metadata: frontmatter.metadata || {
|
|
212
|
+
title: fileName
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
let newCode = result.code;
|
|
216
|
+
newCode = newCode.replace(/export default\s+/, "const MDXContent = ");
|
|
217
|
+
return {
|
|
218
|
+
code: `
|
|
219
|
+
import { MDXRenderer } from "@rasenganjs/mdx";
|
|
220
|
+
import mdxConfig from "virtual:rasengan/mdx-components";
|
|
221
|
+
|
|
222
|
+
${newCode}
|
|
223
|
+
|
|
224
|
+
const metadata = ${JSON.stringify(metadata)};
|
|
225
|
+
const toc = ${isTocVisible ? JSON.stringify(toc) : void 0};
|
|
226
|
+
const raw = ${content};
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
// This object is handled by packages/rasengan itself
|
|
230
|
+
// It will turn it into a PageComponent component
|
|
231
|
+
const MDXWrapper = {
|
|
232
|
+
raw,
|
|
233
|
+
metadata,
|
|
234
|
+
toc,
|
|
235
|
+
type: "MDXPageComponent", // Helps to differentiate PageComponent from MDXPageComponent
|
|
236
|
+
Content: MDXContent, // The content of the MDX file
|
|
237
|
+
Renderer: MDXRenderer, // The renderer component
|
|
238
|
+
config: mdxConfig, // The MDX config coming from mdx-components virtual module
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
export default MDXWrapper;
|
|
243
|
+
`,
|
|
244
|
+
map: result.map
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function loadMDXComponentsPlugin() {
|
|
250
|
+
const virtualModuleId = "virtual:rasengan/mdx-components";
|
|
251
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
252
|
+
return {
|
|
253
|
+
name: "vite-plugin-rasengan-mdx-components",
|
|
254
|
+
resolveId(id) {
|
|
255
|
+
if (id === virtualModuleId) {
|
|
256
|
+
return resolvedVirtualModuleId;
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
async load(id) {
|
|
260
|
+
if (id === resolvedVirtualModuleId) {
|
|
261
|
+
return `
|
|
262
|
+
const modules = import.meta.glob(
|
|
263
|
+
[
|
|
264
|
+
'/mdx-components.{js,jsx,ts,tsx}',
|
|
265
|
+
],
|
|
266
|
+
{ eager: true }
|
|
267
|
+
);
|
|
268
|
+
let config = {};
|
|
269
|
+
|
|
270
|
+
const modulesArray = Object.entries(modules);
|
|
271
|
+
|
|
272
|
+
if (modulesArray.length > 0) {
|
|
273
|
+
const [filePath, mod] = modulesArray[0];
|
|
274
|
+
config = mod.default;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export default config;
|
|
278
|
+
`;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/plugin.ts
|
|
285
|
+
var plugin2 = (options) => [
|
|
286
|
+
plugin(options),
|
|
287
|
+
loadMDXComponentsPlugin()
|
|
288
|
+
];
|
|
289
|
+
var plugin_default = plugin2;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as vite from 'vite';
|
|
2
|
+
import { Options } from 'rehype-pretty-code';
|
|
3
|
+
import { PluggableList } from 'unified';
|
|
4
|
+
|
|
5
|
+
type MDXConfig = {
|
|
6
|
+
remarkPlugins?: PluggableList;
|
|
7
|
+
rehypePlugins?: PluggableList;
|
|
8
|
+
code?: {
|
|
9
|
+
theme?: Options['theme'];
|
|
10
|
+
keepBackground?: Options['keepBackground'];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
declare const plugin: (options?: MDXConfig) => (Promise<vite.Plugin<any>> | {
|
|
15
|
+
name: string;
|
|
16
|
+
resolveId(id: string): string;
|
|
17
|
+
load(id: string): Promise<string>;
|
|
18
|
+
})[];
|
|
19
|
+
|
|
20
|
+
export { plugin as default };
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as vite from 'vite';
|
|
2
|
+
import { Options } from 'rehype-pretty-code';
|
|
3
|
+
import { PluggableList } from 'unified';
|
|
4
|
+
|
|
5
|
+
type MDXConfig = {
|
|
6
|
+
remarkPlugins?: PluggableList;
|
|
7
|
+
rehypePlugins?: PluggableList;
|
|
8
|
+
code?: {
|
|
9
|
+
theme?: Options['theme'];
|
|
10
|
+
keepBackground?: Options['keepBackground'];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
declare const plugin: (options?: MDXConfig) => (Promise<vite.Plugin<any>> | {
|
|
15
|
+
name: string;
|
|
16
|
+
resolveId(id: string): string;
|
|
17
|
+
load(id: string): Promise<string>;
|
|
18
|
+
})[];
|
|
19
|
+
|
|
20
|
+
export { plugin as default };
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractTOC
|
|
3
|
+
} from "./chunk-U2MZHTHK.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/plugin.ts
|
|
6
|
+
import matter from "gray-matter";
|
|
7
|
+
|
|
8
|
+
// src/utils/create-filter.ts
|
|
9
|
+
import micromatch from "micromatch";
|
|
10
|
+
function createFilter(include, exclude) {
|
|
11
|
+
return function(id) {
|
|
12
|
+
if (typeof id !== "string") return false;
|
|
13
|
+
const matcher = micromatch.matcher(include);
|
|
14
|
+
if (exclude) {
|
|
15
|
+
const excluder = micromatch.matcher(exclude);
|
|
16
|
+
return matcher(id) && !excluder(id);
|
|
17
|
+
} else {
|
|
18
|
+
return matcher(id);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/utils/plugin.ts
|
|
24
|
+
import remarkGfm from "remark-gfm";
|
|
25
|
+
import rehypeStringify from "rehype-stringify";
|
|
26
|
+
import remarkParse from "remark-parse";
|
|
27
|
+
import remarkRehype from "remark-rehype";
|
|
28
|
+
import rehypePrettyCode from "rehype-pretty-code";
|
|
29
|
+
async function plugin(options) {
|
|
30
|
+
const mdx = (await import("@mdx-js/rollup")).default;
|
|
31
|
+
const userConfig = {
|
|
32
|
+
rehypePlugins: options?.rehypePlugins ?? [],
|
|
33
|
+
remarkPlugins: options?.rehypePlugins ?? [],
|
|
34
|
+
code: {
|
|
35
|
+
theme: options?.code?.theme ?? {
|
|
36
|
+
light: "one-light",
|
|
37
|
+
dark: "one-dark-pro"
|
|
38
|
+
},
|
|
39
|
+
keepBackground: options?.code?.keepBackground ?? true
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
let config;
|
|
43
|
+
const filter = createFilter("**/*.md?(x)");
|
|
44
|
+
const mdxInstance = mdx({
|
|
45
|
+
remarkPlugins: [remarkParse, remarkGfm, ...userConfig.remarkPlugins],
|
|
46
|
+
rehypePlugins: [
|
|
47
|
+
remarkRehype,
|
|
48
|
+
rehypeStringify,
|
|
49
|
+
[
|
|
50
|
+
rehypePrettyCode,
|
|
51
|
+
{
|
|
52
|
+
theme: userConfig.code.theme,
|
|
53
|
+
keepBackground: userConfig.code.keepBackground
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
// Developer rehype plugin list
|
|
57
|
+
...userConfig.rehypePlugins
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
name: "vite-plugin-rasengan-mdx",
|
|
62
|
+
// Apply transformation of the mdx file before other plugins
|
|
63
|
+
enforce: "pre",
|
|
64
|
+
config(config2, env) {
|
|
65
|
+
mdxInstance.config(config2, env);
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* Stores the resolved Vite configuration for later use.
|
|
69
|
+
*
|
|
70
|
+
* @param resolvedConfig - The resolved Vite configuration object.
|
|
71
|
+
*/
|
|
72
|
+
configResolved(resolvedConfig) {
|
|
73
|
+
config = resolvedConfig;
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Transforms an MDX file by applying the `@mdx-js/rollup` transformation, extracting frontmatter data, and appending a `metadata` object to the transformed content.
|
|
77
|
+
*
|
|
78
|
+
* @param code - The content of the MDX file.
|
|
79
|
+
* @param id - The ID of the MDX file.
|
|
80
|
+
* @returns An object containing the transformed MDX code and a source map, or `null` if the file is not an MDX file.
|
|
81
|
+
*/
|
|
82
|
+
async transform(code, id) {
|
|
83
|
+
if (!filter(id)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const { content, data: frontmatter } = matter(code);
|
|
87
|
+
const isTocVisible = frontmatter.toc !== void 0 ? frontmatter.toc : false;
|
|
88
|
+
const toc = extractTOC(content);
|
|
89
|
+
const result = await mdxInstance.transform(content, id);
|
|
90
|
+
const fileName = id.split("/").pop().replace(/.page.mdx?$/, "");
|
|
91
|
+
const metadata = {
|
|
92
|
+
path: frontmatter.path || `/${fileName}`,
|
|
93
|
+
metadata: frontmatter.metadata || {
|
|
94
|
+
title: fileName
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
let newCode = result.code;
|
|
98
|
+
newCode = newCode.replace(/export default\s+/, "const MDXContent = ");
|
|
99
|
+
return {
|
|
100
|
+
code: `
|
|
101
|
+
import { MDXRenderer } from "@rasenganjs/mdx";
|
|
102
|
+
import mdxConfig from "virtual:rasengan/mdx-components";
|
|
103
|
+
|
|
104
|
+
${newCode}
|
|
105
|
+
|
|
106
|
+
const metadata = ${JSON.stringify(metadata)};
|
|
107
|
+
const toc = ${isTocVisible ? JSON.stringify(toc) : void 0};
|
|
108
|
+
const raw = ${content};
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
// This object is handled by packages/rasengan itself
|
|
112
|
+
// It will turn it into a PageComponent component
|
|
113
|
+
const MDXWrapper = {
|
|
114
|
+
raw,
|
|
115
|
+
metadata,
|
|
116
|
+
toc,
|
|
117
|
+
type: "MDXPageComponent", // Helps to differentiate PageComponent from MDXPageComponent
|
|
118
|
+
Content: MDXContent, // The content of the MDX file
|
|
119
|
+
Renderer: MDXRenderer, // The renderer component
|
|
120
|
+
config: mdxConfig, // The MDX config coming from mdx-components virtual module
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
export default MDXWrapper;
|
|
125
|
+
`,
|
|
126
|
+
map: result.map
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function loadMDXComponentsPlugin() {
|
|
132
|
+
const virtualModuleId = "virtual:rasengan/mdx-components";
|
|
133
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
134
|
+
return {
|
|
135
|
+
name: "vite-plugin-rasengan-mdx-components",
|
|
136
|
+
resolveId(id) {
|
|
137
|
+
if (id === virtualModuleId) {
|
|
138
|
+
return resolvedVirtualModuleId;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
async load(id) {
|
|
142
|
+
if (id === resolvedVirtualModuleId) {
|
|
143
|
+
return `
|
|
144
|
+
const modules = import.meta.glob(
|
|
145
|
+
[
|
|
146
|
+
'/mdx-components.{js,jsx,ts,tsx}',
|
|
147
|
+
],
|
|
148
|
+
{ eager: true }
|
|
149
|
+
);
|
|
150
|
+
let config = {};
|
|
151
|
+
|
|
152
|
+
const modulesArray = Object.entries(modules);
|
|
153
|
+
|
|
154
|
+
if (modulesArray.length > 0) {
|
|
155
|
+
const [filePath, mod] = modulesArray[0];
|
|
156
|
+
config = mod.default;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export default config;
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/plugin.ts
|
|
167
|
+
var plugin2 = (options) => [
|
|
168
|
+
plugin(options),
|
|
169
|
+
loadMDXComponentsPlugin()
|
|
170
|
+
];
|
|
171
|
+
var plugin_default = plugin2;
|
|
172
|
+
export {
|
|
173
|
+
plugin_default as default
|
|
174
|
+
};
|
package/package.json
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rasenganjs/mdx",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.2.0
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"description": "RasenganJS plugin for MDX support",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"main": "
|
|
7
|
+
"main": "dist/index.js",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
13
|
},
|
|
14
|
-
"./css": "./lib/styles/rasengan-mdx.min.css",
|
|
15
14
|
"./plugin": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
15
|
+
"types": "./dist/plugin.d.ts",
|
|
16
|
+
"import": "./dist/plugin.js",
|
|
17
|
+
"require": "./dist/plugin.cjs"
|
|
19
18
|
},
|
|
20
19
|
"./types/client": {
|
|
21
20
|
"types": "./types/client.d.ts"
|
|
@@ -45,8 +44,8 @@
|
|
|
45
44
|
"dependencies": {
|
|
46
45
|
"@mdx-js/rollup": "^3.1.1",
|
|
47
46
|
"gray-matter": "^4.0.3",
|
|
47
|
+
"lucide-react": "^0.477.0",
|
|
48
48
|
"micromatch": "^4.0.8",
|
|
49
|
-
"path-browserify": "^1.0.1",
|
|
50
49
|
"prism-react-renderer": "^2.4.1",
|
|
51
50
|
"react-markdown": "^10.1.0",
|
|
52
51
|
"rehype-pretty-code": "^0.14.1",
|
|
@@ -55,17 +54,18 @@
|
|
|
55
54
|
"remark-gfm": "^4.0.1",
|
|
56
55
|
"remark-parse": "^11.0.0",
|
|
57
56
|
"remark-rehype": "^11.1.2",
|
|
58
|
-
"remark-toc": "^9.0.0",
|
|
59
57
|
"unified": "^11.0.5"
|
|
60
58
|
},
|
|
61
59
|
"peerDependencies": {
|
|
62
60
|
"react": "^19.0.0",
|
|
63
|
-
"react-dom": "^19.0.0"
|
|
61
|
+
"react-dom": "^19.0.0",
|
|
62
|
+
"vite": "^7.*"
|
|
64
63
|
},
|
|
65
64
|
"scripts": {
|
|
66
|
-
"build:clean": "rimraf ./
|
|
67
|
-
"build
|
|
68
|
-
"
|
|
65
|
+
"build:clean": "rimraf ./dist",
|
|
66
|
+
"build": "pnpm build:clean && tsup",
|
|
67
|
+
"lint": "eslint src --ext .ts",
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
69
69
|
"pack": "pnpm pack --pack-destination ./release",
|
|
70
70
|
"deploy": "pnpm publish --access public"
|
|
71
71
|
}
|
package/tsup.config.ts
ADDED
package/types/client.d.ts
CHANGED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { CodeBlockProps, ComponentWithTextChildrenProps } from '../types/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* A React component that renders a code block with syntax highlighting and a copy button.
|
|
5
|
-
*
|
|
6
|
-
* The component uses the `prism-react-renderer` library to provide syntax highlighting for the code block.
|
|
7
|
-
* It also includes a copy button that allows the user to copy the code to their clipboard.
|
|
8
|
-
*
|
|
9
|
-
* @param {object} props - The component props.
|
|
10
|
-
* @param {string} props.children - The code content to be displayed in the code block.
|
|
11
|
-
* @param {string} [props.className] - The CSS class name to apply to the code block.
|
|
12
|
-
* @returns {React.ReactElement} - The rendered code block component.
|
|
13
|
-
*/
|
|
14
|
-
export declare const CodeBlock: ({ children, className, ...rest }: CodeBlockProps) => React.ReactElement;
|
|
15
|
-
export declare const SimpleBlock: ({ children, }: ComponentWithTextChildrenProps) => React.ReactElement;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { renderToString } from 'react-dom/server';
|
|
4
|
-
/**
|
|
5
|
-
* A React component that renders a code block with syntax highlighting and a copy button.
|
|
6
|
-
*
|
|
7
|
-
* The component uses the `prism-react-renderer` library to provide syntax highlighting for the code block.
|
|
8
|
-
* It also includes a copy button that allows the user to copy the code to their clipboard.
|
|
9
|
-
*
|
|
10
|
-
* @param {object} props - The component props.
|
|
11
|
-
* @param {string} props.children - The code content to be displayed in the code block.
|
|
12
|
-
* @param {string} [props.className] - The CSS class name to apply to the code block.
|
|
13
|
-
* @returns {React.ReactElement} - The rendered code block component.
|
|
14
|
-
*/
|
|
15
|
-
export const CodeBlock = ({ children = '', className = '', ...rest }) => {
|
|
16
|
-
const language = rest['data-language'] || '';
|
|
17
|
-
const numbers = rest['data-line-numbers'];
|
|
18
|
-
const [hover, setHover] = React.useState(false);
|
|
19
|
-
const [copied, setCopied] = React.useState(false);
|
|
20
|
-
React.useEffect(() => {
|
|
21
|
-
/**
|
|
22
|
-
* Sets the `copied` state to `false` after 2 seconds, effectively hiding the "copied" indicator.
|
|
23
|
-
* This function is called after the user's clipboard is updated with the code content.
|
|
24
|
-
*/
|
|
25
|
-
const timer = setTimeout(() => {
|
|
26
|
-
setCopied(false);
|
|
27
|
-
}, 2000);
|
|
28
|
-
return () => clearTimeout(timer);
|
|
29
|
-
}, [copied]);
|
|
30
|
-
/**
|
|
31
|
-
* Copies the trimmed text content of the `children` prop to the user's clipboard.
|
|
32
|
-
* This function is called when the "Copy" button is clicked in the code block component.
|
|
33
|
-
* It sets the `copied` state to `true` for 2 seconds to display a "copied" indicator.
|
|
34
|
-
*/
|
|
35
|
-
const handleCopy = () => {
|
|
36
|
-
const content = renderToString(children);
|
|
37
|
-
const code = extractTextFromHTML(content);
|
|
38
|
-
navigator.clipboard.writeText(code);
|
|
39
|
-
setCopied(true);
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Extracts the text content from an HTML string.
|
|
43
|
-
*
|
|
44
|
-
* This function takes an HTML string as input and returns the plain text content of the HTML, excluding any HTML tags or markup.
|
|
45
|
-
*
|
|
46
|
-
* @param htmlString - The HTML string to extract text from.
|
|
47
|
-
* @returns The plain text content of the HTML string.
|
|
48
|
-
*/
|
|
49
|
-
const extractTextFromHTML = (htmlString) => {
|
|
50
|
-
const parser = new DOMParser();
|
|
51
|
-
const doc = parser.parseFromString(htmlString, 'text/html');
|
|
52
|
-
return doc.body.textContent || '';
|
|
53
|
-
};
|
|
54
|
-
if (!language) {
|
|
55
|
-
return _jsx(SimpleBlock, { children: children });
|
|
56
|
-
}
|
|
57
|
-
return (_jsxs("div", { onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), children: [hover ? (_jsx("button", { className: "copy-button", onClick: handleCopy, children: copied ? (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "16", height: "16", color: "#f0f0f0", fill: "none", children: [_jsx("path", { d: "M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12Z", stroke: "currentColor", strokeWidth: "1.5" }), _jsx("path", { d: "M8 12.5L10.5 15L16 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] })) : (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "16", height: "16", color: "#f0f0f0", fill: "none", children: [_jsx("path", { d: "M9 15C9 12.1716 9 10.7574 9.87868 9.87868C10.7574 9 12.1716 9 15 9L16 9C18.8284 9 20.2426 9 21.1213 9.87868C22 10.7574 22 12.1716 22 15V16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H15C12.1716 22 10.7574 22 9.87868 21.1213C9 20.2426 9 18.8284 9 16L9 15Z", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M16.9999 9C16.9975 6.04291 16.9528 4.51121 16.092 3.46243C15.9258 3.25989 15.7401 3.07418 15.5376 2.90796C14.4312 2 12.7875 2 9.5 2C6.21252 2 4.56878 2 3.46243 2.90796C3.25989 3.07417 3.07418 3.25989 2.90796 3.46243C2 4.56878 2 6.21252 2 9.5C2 12.7875 2 14.4312 2.90796 15.5376C3.07417 15.7401 3.25989 15.9258 3.46243 16.092C4.51121 16.9528 6.04291 16.9975 9 16.9999", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] })) })) : (_jsx("span", { className: "lang", children: language })), _jsx("code", { className: `${className} code-block`, "data-line-numbers": numbers !== undefined ? '' : undefined, children: children })] }));
|
|
58
|
-
};
|
|
59
|
-
export const SimpleBlock = ({ children, }) => {
|
|
60
|
-
return _jsx("code", { className: "simple-block", children: children });
|
|
61
|
-
};
|
|
62
|
-
//# sourceMappingURL=codeblock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codeblock.js","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"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"}
|