@md-plugins/vite-md-plugin 0.1.0-alpha.1

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 ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024-present, Jeff Galbraith
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # @md-plugins/viteMdPlugin
2
+
3
+ An **opinionated Vite plugin** that transforms Markdown files into Vue Single File Components (SFCs). This plugin integrates Markdown processing directly into your Vite-based Vue project, enabling seamless Markdown-to-Vue workflows.
4
+
5
+ ## Features
6
+
7
+ - **Markdown to Vue SFC Transformation**: Converts Markdown files into Vue Single File Components, enabling dynamic content rendering.
8
+ - **Navigation Menu Integration**: Supports generating a navigation structure based on your Markdown files.
9
+ - **Configurable Path Prefix**: Allows setting a base path for routing or file resolution.
10
+ - **Opinionated and Minimal**: Focuses on simplicity, leveraging the power of Vue and Markdown for content-driven applications.
11
+
12
+ ## md-plugins Used
13
+
14
+ The `viteMdPlugin` is built on top of the following plugins:
15
+
16
+ | Plugin | Description | Readme |
17
+ | ----------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------- |
18
+ | `@md-plugins/md-plugin-imports` | Extracts and processes `<script import>` blocks from Markdown. | [README](packages/md-plugin-imports/README.md) |
19
+ | `@md-plugins/md-plugin-codeblocks` | Enhances code block rendering with syntax highlighting, tabs, and more. | [README](packages/md-plugin-codeblocks/README.md) |
20
+ | `@md-plugins/md-plugin-blockquote` | Adds customizable CSS classes to blockquotes. | [README](packages/md-plugin-blockquote/README.md) |
21
+ | `@md-plugins/md-plugin-headers` | Extracts and processes headers for generating ToCs or managing headers. | [README](packages/md-plugin-headers/README.md) |
22
+ | `@md-plugins/md-plugin-inlinecode` | Adds a custom class to inline code blocks for styling. | [README](packages/md-plugin-inlinecode/README.md) |
23
+ | `@md-plugins/md-plugin-link` | Converts Markdown links into Vue components for SPA-friendly routing. | [README](packages/md-plugin-link/README.md) |
24
+ | `@md-plugins/md-plugin-table` | Adds custom classes and attributes to Markdown tables. | [README](packages/md-plugin-table/README.md) |
25
+ | `@md-plugins/md-plugin-title` | Extracts the first header in Markdown as the page title. | [README](packages/md-plugin-title/README.md) |
26
+ | `@md-plugins/md-plugin-frontmatter` | Extracts and processes frontmatter content from Markdown files. | [README](packages/md-plugin-frontmatter/README.md) |
27
+ | `@md-plugins/md-plugin-containers` | Adds custom containers for callouts, warnings, and more. | [README](packages/md-plugin-containers/README.md) |
28
+ | `@md-plugins/shared` | Shared utilities and types for the plugins. | [README](packages/shared/README.md) |
29
+
30
+ ## Installation
31
+
32
+ Install the plugin via your preferred package manager:
33
+
34
+ ```bash
35
+ # With npm:
36
+ npm install @md-plugins/vite-md-plugin
37
+ # Or with Yarn:
38
+ yarn add @md-plugins/vite-md-plugin
39
+ # Or with pnpm:
40
+ pnpm add @md-plugins/vite-md-plugin
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### Basic Setup with Vite
46
+
47
+ To use the `viteMdPlugin`, configure it in your Vite project:
48
+
49
+ ```js
50
+ import { defineConfig } from 'vite';
51
+ import vue from '@vitejs/plugin-vue';
52
+ import { viteMdPlugin } from 'vite-md-plugin';
53
+
54
+ const menu = []; // Define your navigation menu structure here
55
+ const basePath = '/docs'; // Base path prefix
56
+
57
+ export default defineConfig({
58
+ plugins: [vue(), viteMdPlugin(basePath, menu)],
59
+ });
60
+ ```
61
+
62
+ ## Quasar Framework Configuration
63
+
64
+ If you’re using the Quasar Framework, additional configuration is needed to enable support for `.md` files:
65
+
66
+ 1. Update `quasar.config.(js|ts)`:
67
+
68
+ ```js
69
+ import { viteMdPlugin } from '@md-plugins/vite-md-plugin';
70
+ import { menu } from './src/assets/menu'; // be sure to create this file
71
+
72
+ export default defineConfig((ctx) => {
73
+ // ...
74
+ ```
75
+
76
+ ```js
77
+ build: {
78
+ vueRouterMode: 'history', // Required for proper hash link handling
79
+
80
+ viteVuePluginOptions: {
81
+ include: [/\.(vue|md)$/], // Include Markdown files
82
+ },
83
+
84
+ vitePlugins: [
85
+ viteMdPlugin(ctx.appPaths.srcDir + '/pages', menu),
86
+ // ...
87
+ ],
88
+ },
89
+
90
+ framework: {
91
+ autoImportVueExtensions: ['vue', 'md'], // Enable auto-import for Markdown extensions
92
+ },
93
+ ```
94
+
95
+ 2. Ensure that your routes and hash links are compatible with Vue Router's history mode.
96
+
97
+ ## Navigation Menu Integration
98
+
99
+ The `viteMdPlugin` allows you to define a navigation structure that can be updated dynamically based on the Markdown files in your project:
100
+
101
+ ```js
102
+ const menu = [
103
+ { title: 'Home', path: '/home' },
104
+ { title: 'About', path: '/about' },
105
+ ];
106
+ ```
107
+
108
+ This menu is passed as a parameter to the plugin and can be used to build a dynamic sidebar or navigation bar in your application.
109
+
110
+ ## Options
111
+
112
+ The `viteMdPlugin` accepts the following parameters:
113
+
114
+ | Parameter | Type | Description |
115
+ | --------- | ---------- | ------------------------------------------------------------------------------------------ |
116
+ | path | string | The base path prefix for routing or file resolution. |
117
+ | menu | MenuItem[] | An array representing the navigation menu structure. Each item should have title and path. |
118
+
119
+ ## MenuItem Type
120
+
121
+ The `menu` parameter should conform to the following structure:
122
+
123
+ ```ts
124
+ export interface MenuItem {
125
+ name: string;
126
+ path?: string;
127
+ icon?: string;
128
+ iconColor?: string;
129
+ rightIcon?: string;
130
+ rightIconColor?: string;
131
+ badge?: string;
132
+ children?: MenuItem[];
133
+ external?: boolean;
134
+ expanded?: boolean;
135
+ }
136
+ ```
137
+
138
+ ## Testing
139
+
140
+ To run the tests for this plugin, use the following command:
141
+
142
+ ```bash
143
+ pnpm test
144
+ ```
145
+
146
+ ## License
147
+
148
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
@@ -0,0 +1,62 @@
1
+ interface MenuItem {
2
+ name: string;
3
+ path?: string;
4
+ icon?: string;
5
+ iconColor?: string;
6
+ rightIcon?: string;
7
+ rightIconColor?: string;
8
+ badge?: string;
9
+ children?: MenuItem[];
10
+ external?: boolean;
11
+ expanded?: boolean;
12
+ }
13
+ interface MenuNode {
14
+ name: string;
15
+ path?: string;
16
+ external?: boolean;
17
+ children?: MenuNode[];
18
+ }
19
+ interface FlatMenuEntry {
20
+ name: string;
21
+ category: string | null;
22
+ path: string;
23
+ prev?: FlatMenuEntry;
24
+ next?: FlatMenuEntry;
25
+ }
26
+ type FlatMenu = Record<string, FlatMenuEntry>;
27
+ interface NavItem extends FlatMenuEntry {
28
+ classes: string;
29
+ }
30
+ interface RelatedItem {
31
+ name: string;
32
+ category: string;
33
+ path: string;
34
+ }
35
+
36
+ /**
37
+ * Transforms markdown content into Vue Single File Component (SFC) format.
38
+ *
39
+ * @param code - The markdown content to be transformed.
40
+ * @param id - The identifier (typically the file path) of the markdown file.
41
+ * @returns The transformed Vue SFC content, or null if the file is not a markdown file.
42
+ * @throws Will throw an error if the markdown transformation process fails.
43
+ */
44
+ declare function transform(code: string, id: string): {
45
+ code: string;
46
+ map: null;
47
+ } | null;
48
+ /**
49
+ * Creates a Vite plugin for processing Markdown files.
50
+ * This plugin transforms Markdown content into Vue Single File Components (SFCs).
51
+ *
52
+ * @param path - The base path prefix to be used for routing or file resolution.
53
+ * @param menu - An array of MenuItem objects representing the navigation menu structure.
54
+ * @returns A Vite plugin object with pre-configured settings for Markdown processing.
55
+ */
56
+ declare function viteMdPlugin(path: string, menu: MenuItem[]): {
57
+ name: string;
58
+ enforce: string;
59
+ transform: typeof transform;
60
+ };
61
+
62
+ export { type FlatMenu, type FlatMenuEntry, type MenuItem, type MenuNode, type NavItem, type RelatedItem, viteMdPlugin };
@@ -0,0 +1,62 @@
1
+ interface MenuItem {
2
+ name: string;
3
+ path?: string;
4
+ icon?: string;
5
+ iconColor?: string;
6
+ rightIcon?: string;
7
+ rightIconColor?: string;
8
+ badge?: string;
9
+ children?: MenuItem[];
10
+ external?: boolean;
11
+ expanded?: boolean;
12
+ }
13
+ interface MenuNode {
14
+ name: string;
15
+ path?: string;
16
+ external?: boolean;
17
+ children?: MenuNode[];
18
+ }
19
+ interface FlatMenuEntry {
20
+ name: string;
21
+ category: string | null;
22
+ path: string;
23
+ prev?: FlatMenuEntry;
24
+ next?: FlatMenuEntry;
25
+ }
26
+ type FlatMenu = Record<string, FlatMenuEntry>;
27
+ interface NavItem extends FlatMenuEntry {
28
+ classes: string;
29
+ }
30
+ interface RelatedItem {
31
+ name: string;
32
+ category: string;
33
+ path: string;
34
+ }
35
+
36
+ /**
37
+ * Transforms markdown content into Vue Single File Component (SFC) format.
38
+ *
39
+ * @param code - The markdown content to be transformed.
40
+ * @param id - The identifier (typically the file path) of the markdown file.
41
+ * @returns The transformed Vue SFC content, or null if the file is not a markdown file.
42
+ * @throws Will throw an error if the markdown transformation process fails.
43
+ */
44
+ declare function transform(code: string, id: string): {
45
+ code: string;
46
+ map: null;
47
+ } | null;
48
+ /**
49
+ * Creates a Vite plugin for processing Markdown files.
50
+ * This plugin transforms Markdown content into Vue Single File Components (SFCs).
51
+ *
52
+ * @param path - The base path prefix to be used for routing or file resolution.
53
+ * @param menu - An array of MenuItem objects representing the navigation menu structure.
54
+ * @returns A Vite plugin object with pre-configured settings for Markdown processing.
55
+ */
56
+ declare function viteMdPlugin(path: string, menu: MenuItem[]): {
57
+ name: string;
58
+ enforce: string;
59
+ transform: typeof transform;
60
+ };
61
+
62
+ export { type FlatMenu, type FlatMenuEntry, type MenuItem, type MenuNode, type NavItem, type RelatedItem, viteMdPlugin };
package/dist/index.mjs ADDED
@@ -0,0 +1,338 @@
1
+ import MarkdownIt from 'markdown-it';
2
+ import { frontmatterPlugin } from '@md-plugins/md-plugin-frontmatter';
3
+ import { importsPlugin } from '@md-plugins/md-plugin-imports';
4
+ import { headersPlugin } from '@md-plugins/md-plugin-headers';
5
+ import { linkPlugin } from '@md-plugins/md-plugin-link';
6
+ import { inlinecodePlugin } from '@md-plugins/md-plugin-inlinecode';
7
+ import { imagePlugin } from '@md-plugins/md-plugin-image';
8
+ import { codeblocksPlugin } from '@md-plugins/md-plugin-codeblocks';
9
+ import { blockquotePlugin } from '@md-plugins/md-plugin-blockquote';
10
+ import { tablePlugin } from '@md-plugins/md-plugin-table';
11
+ import { titlePlugin } from '@md-plugins/md-plugin-title';
12
+ import { containersPlugin } from '@md-plugins/md-plugin-containers';
13
+ import { join } from 'node:path';
14
+
15
+ const createContainer = (container, containerType, defaultTitle) => {
16
+ const containerTypeLen = containerType.length;
17
+ return [
18
+ container,
19
+ containerType,
20
+ {
21
+ render(tokens, idx) {
22
+ const token = tokens[idx];
23
+ if (!token) {
24
+ return "";
25
+ }
26
+ const title = token.info.trim().slice(containerTypeLen).trim() || defaultTitle;
27
+ if (containerType === "details") {
28
+ return token.nesting === 1 ? `<details class="markdown-note markdown-note--${containerType}"><summary class="markdown-note__title">${title}</summary>
29
+ ` : "</details>\n";
30
+ }
31
+ return token.nesting === 1 ? `<div class="markdown-note markdown-note--${containerType}"><p class="markdown-note__title">${title}</p>
32
+ ` : "</div>\n";
33
+ }
34
+ }
35
+ ];
36
+ };
37
+ function createMarkdownRenderer(options = {}) {
38
+ const md2 = new MarkdownIt({
39
+ html: true,
40
+ linkify: true,
41
+ typographer: true,
42
+ ...options,
43
+ breaks: true
44
+ });
45
+ md2.use(frontmatterPlugin);
46
+ md2.use(importsPlugin);
47
+ md2.use(titlePlugin);
48
+ md2.use(headersPlugin, { level: [2, 3] });
49
+ const containers = [
50
+ { type: "tip", defaultTitle: "TIP" },
51
+ { type: "warning", defaultTitle: "WARNING" },
52
+ { type: "danger", defaultTitle: "WARNING" },
53
+ { type: "details", defaultTitle: "Details" }
54
+ ];
55
+ md2.use(containersPlugin, containers, createContainer);
56
+ md2.use(blockquotePlugin, { blockquoteClass: "markdown-note" });
57
+ md2.use(tablePlugin, {
58
+ tableClass: "markdown-page-table",
59
+ tableHeaderClass: "text-left",
60
+ tableToken: "q-markup-table",
61
+ tableAttributes: [
62
+ [":wrap-cells", "true"],
63
+ [":flat", "true"],
64
+ [":bordered", "true"]
65
+ ]
66
+ });
67
+ md2.use(codeblocksPlugin, {
68
+ containerComponent: "MarkdownPrerender",
69
+ copyButtonComponent: "MarkdownCopyButton",
70
+ pageScripts: [
71
+ "import MarkdownPrerender from 'components/md/MarkdownPrerender'",
72
+ "import MarkdownCopyButton from 'components/md/MarkdownCopyButton.vue'"
73
+ ]
74
+ });
75
+ md2.use(linkPlugin);
76
+ md2.use(inlinecodePlugin);
77
+ md2.use(imagePlugin);
78
+ return {
79
+ // env: Environment for storing metadata
80
+ render(code, env = {}) {
81
+ const html = md2.render(code, env);
82
+ return {
83
+ html,
84
+ frontmatter: env.frontmatter || {},
85
+ // comes from md_plugin_frontmatter
86
+ title: env.title || "",
87
+ // comes from md_plugin_title
88
+ env
89
+ };
90
+ }
91
+ };
92
+ }
93
+ const md = createMarkdownRenderer();
94
+
95
+ let prev = null;
96
+ function menuWalk(prefix, menuNodes, node, path, parentName) {
97
+ const newPath = path + (node.path ? `/${node.path}` : "");
98
+ if (node.children) {
99
+ node.children.forEach((childNode) => {
100
+ menuWalk(prefix, menuNodes, childNode, newPath, node.name);
101
+ });
102
+ } else if (!node.external) {
103
+ const current = {
104
+ name: node.name,
105
+ category: parentName,
106
+ path: newPath
107
+ };
108
+ if (prev) {
109
+ prev.next = {
110
+ name: current.name,
111
+ category: current.category,
112
+ path: current.path
113
+ };
114
+ current.prev = {
115
+ name: prev.name,
116
+ category: prev.category,
117
+ path: prev.path
118
+ };
119
+ }
120
+ menuNodes[join(prefix, newPath + ".md")] = current;
121
+ if (node.path) {
122
+ menuNodes[join(prefix, newPath + "/" + node.path + ".md")] = current;
123
+ }
124
+ prev = current;
125
+ }
126
+ }
127
+ function generateFlatMenu(prefix, menu) {
128
+ const menuNodes = {};
129
+ prev = null;
130
+ if (menu) {
131
+ menu.forEach((node) => {
132
+ menuWalk(prefix, menuNodes, node, "", null);
133
+ });
134
+ }
135
+ return menuNodes;
136
+ }
137
+ function convertToRelated(prefix, menuNodes, entry, id) {
138
+ const menuEntry = menuNodes[join(prefix, entry + ".md")];
139
+ if (!menuEntry) {
140
+ console.error("[flat-menu] ERROR - wrong related link:", entry, "@id", id);
141
+ return {
142
+ name: "",
143
+ category: "",
144
+ path: ""
145
+ };
146
+ }
147
+ return {
148
+ name: menuEntry.name,
149
+ category: menuEntry.category,
150
+ path: menuEntry.path
151
+ };
152
+ }
153
+
154
+ function splitRenderedContent(mdPageContent) {
155
+ const scriptRE = /<script import>\n((.|\n)*?)\n<\/script>/g;
156
+ const userScripts = /* @__PURE__ */ new Set();
157
+ const mdContent = mdPageContent.replace(scriptRE, (_, p1) => {
158
+ userScripts.add(p1);
159
+ return "";
160
+ });
161
+ return { mdContent, userScripts };
162
+ }
163
+ function createNav(id, env, flatMenu) {
164
+ if (flatMenu) {
165
+ const menuItem = flatMenu[id];
166
+ const nav = [];
167
+ if (menuItem !== void 0) {
168
+ const { prev, next } = menuItem;
169
+ if (prev !== void 0) {
170
+ nav.push({ ...prev, classes: "markdown-page__related--left" });
171
+ }
172
+ if (next !== void 0) {
173
+ nav.push({ ...next, classes: "markdown-page__related--right" });
174
+ }
175
+ }
176
+ if (nav.length > 0) {
177
+ env.frontmatter.nav = nav;
178
+ }
179
+ }
180
+ }
181
+ function parseToc(toc) {
182
+ let wasHeader = true;
183
+ let headerIndex = 1;
184
+ let subheaderIndex;
185
+ const list = toc.map((entry) => {
186
+ if (entry.sub === true) {
187
+ if (wasHeader === true) {
188
+ subheaderIndex = 1;
189
+ } else {
190
+ subheaderIndex++;
191
+ }
192
+ wasHeader = false;
193
+ } else {
194
+ wasHeader = true;
195
+ headerIndex++;
196
+ }
197
+ return {
198
+ ...entry,
199
+ title: entry.sub === true ? `${headerIndex}.${subheaderIndex}. ${entry.title}` : `${headerIndex}. ${entry.title}`
200
+ };
201
+ });
202
+ return JSON.stringify(list);
203
+ }
204
+ function getVueComponent(rendered, code, id, prefix, menu) {
205
+ let flatMenu;
206
+ if (menu) {
207
+ flatMenu = generateFlatMenu(prefix, menu);
208
+ createNav(id, rendered.env, flatMenu);
209
+ }
210
+ const frontmatter = rendered?.frontmatter || {};
211
+ if (frontmatter.editLink !== false) {
212
+ frontmatter.editLink = id.substring(
213
+ id.indexOf("src/pages/") + 10,
214
+ id.length - 3
215
+ );
216
+ }
217
+ const title = frontmatter.title || rendered.env.title || rendered.title || "Generic Page";
218
+ const desc = frontmatter.desc || false;
219
+ const overline = frontmatter.overline || false;
220
+ const heading = rendered.env.heading || !!title || false;
221
+ const related = frontmatter.related && Array.isArray(frontmatter.related) && frontmatter.related.map(
222
+ (entry) => convertToRelated(prefix, flatMenu, entry, id)
223
+ ) || false;
224
+ const nav = frontmatter.nav || false;
225
+ const badge = frontmatter.badge || false;
226
+ const toc = rendered.env.toc || false;
227
+ const editLink = frontmatter.editLink || false;
228
+ frontmatter.components || false;
229
+ const scope = frontmatter.scope || false;
230
+ const examples = frontmatter.examples || false;
231
+ const { mdContent, userScripts } = splitRenderedContent(rendered.html);
232
+ const pageScripts = [
233
+ ...Array.from(rendered.env.pageScripts || []),
234
+ ...Array.from(userScripts || [])
235
+ ].join("\n");
236
+ return `<template>
237
+ <markdown-page
238
+ title="${title}"
239
+ ${desc !== false ? `desc="${desc}"` : ""}
240
+ ${overline !== false ? `overline="${overline}"` : ""}
241
+ ${badge !== false ? `badge="${badge}"` : ""}
242
+ ${heading !== false ? "heading" : ""}
243
+ ${editLink !== false ? `edit-link="${editLink}"` : ""}
244
+ ${toc !== false ? ':toc="toc"' : ""}
245
+ ${related !== false ? ':related="related"' : ""}
246
+ ${nav !== false ? ':nav="nav"' : ""}>${mdContent}</markdown-page>
247
+ </template>
248
+ <script setup>
249
+ import { copyHeading } from 'components/md/markdown-utils'
250
+ ${examples !== false ? `
251
+ import { provide } from 'vue'
252
+ provide('_markdown_examples_', process.env.CLIENT
253
+ ? { name: '${examples}', list: import('examples:${examples}') }
254
+ : { name: '${examples}' })
255
+ ` : ""}
256
+ ${related !== false ? `const related = ${JSON.stringify(related)}` : ""}
257
+ ${nav !== false ? `const nav = ${JSON.stringify(nav)}` : ""}
258
+ ${toc !== false ? `const toc = ${parseToc(toc)}` : ""}
259
+ ${scope !== false ? `const scope = ${JSON.stringify(scope)}` : ""}
260
+ ${pageScripts}
261
+ <\/script>`;
262
+ }
263
+
264
+ const markdownLinkRE = /<MarkdownLink /;
265
+ const markdownApiRE = /<MarkdownApi /;
266
+ const markdownInstallationRE = /<MarkdownInstallation /;
267
+ const markdownTreeRE = /<MarkdownTree /;
268
+ function mdParse(code, id, prefix, menu) {
269
+ const env = {
270
+ frontmatter: {
271
+ id
272
+ },
273
+ pageScripts: /* @__PURE__ */ new Set()
274
+ };
275
+ env.pageScripts.add(
276
+ "import MarkdownPage from 'src/layouts/MarkdownPage.vue'"
277
+ );
278
+ if (markdownApiRE.test(code) === true) {
279
+ env.pageScripts.add(
280
+ "import MarkdownApi from 'components/md/MarkdownApi.vue'"
281
+ );
282
+ }
283
+ if (markdownInstallationRE.test(code) === true) {
284
+ env.pageScripts.add(
285
+ "import MarkdownInstallation from 'components/md/MarkdownInstallation.vue'"
286
+ );
287
+ }
288
+ if (markdownTreeRE.test(code) === true) {
289
+ env.pageScripts.add(
290
+ "import MarkdownTree from 'components/md/MarkdownTree.vue'"
291
+ );
292
+ }
293
+ const results = md.render(code, env);
294
+ if (env.frontmatter.examples !== void 0) {
295
+ env.pageScripts.add(
296
+ "import MarkdownExample from 'components/md/MarkdownExample.vue'"
297
+ );
298
+ }
299
+ if (markdownLinkRE.test(code) === true) {
300
+ env.pageScripts.add(
301
+ "import MarkdownLink from 'components/md/MarkdownLink.vue'"
302
+ );
303
+ }
304
+ const component = getVueComponent(results, code, id, prefix, menu);
305
+ return {
306
+ code: component,
307
+ map: null
308
+ // No source map provided
309
+ };
310
+ }
311
+
312
+ const mdRE = /\.md$/;
313
+ let globalMenu = [];
314
+ let globalPrefix = "";
315
+ function transform(code, id) {
316
+ if (!mdRE.test(id)) return null;
317
+ try {
318
+ return mdParse(code, id, globalPrefix, globalMenu);
319
+ } catch (err) {
320
+ console.error(`Error processing Markdown file: ${id}`, err);
321
+ throw new Error(
322
+ `Markdown transform failed: ${err instanceof Error ? err.message : String(err)}`
323
+ );
324
+ }
325
+ }
326
+ const mdPlugins = {
327
+ name: "md-plugins:vitePlugin",
328
+ enforce: "pre",
329
+ // before vue
330
+ transform
331
+ };
332
+ function viteMdPlugin(path, menu) {
333
+ globalMenu = menu;
334
+ globalPrefix = path;
335
+ return mdPlugins;
336
+ }
337
+
338
+ export { viteMdPlugin };
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@md-plugins/vite-md-plugin",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "A very opinionated Vite plugin for @md-plugins.",
5
+ "keywords": [
6
+ "markdown-it",
7
+ "quasarframework",
8
+ "vue",
9
+ "utils",
10
+ "vite",
11
+ "vite-plugin"
12
+ ],
13
+ "homepage": "https://github.com/md-plugins",
14
+ "bugs": {
15
+ "url": "https://github.com/md-plugins/md-plugins/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/md-plugins/md-plugins.git"
20
+ },
21
+ "license": "MIT",
22
+ "author": "hawkeye64 <galbraith64@gmail.com>",
23
+ "type": "module",
24
+ "exports": {
25
+ ".": {
26
+ "import": {
27
+ "types": "./dist/index.d.mts",
28
+ "default": "./dist/index.mjs"
29
+ }
30
+ }
31
+ },
32
+ "module": "./dist/index.mjs",
33
+ "types": "./dist/index.d.ts",
34
+ "files": [
35
+ "./dist"
36
+ ],
37
+ "devDependencies": {
38
+ "@types/markdown-it": "^14.1.2",
39
+ "markdown-it": "^14.1.0",
40
+ "@md-plugins/shared": "0.1.0-alpha.1",
41
+ "@md-plugins/md-plugin-containers": "0.1.0-alpha.1",
42
+ "@md-plugins/md-plugin-headers": "0.1.0-alpha.1",
43
+ "@md-plugins/md-plugin-frontmatter": "0.1.0-alpha.1",
44
+ "@md-plugins/md-plugin-inlinecode": "0.1.0-alpha.1",
45
+ "@md-plugins/md-plugin-imports": "0.1.0-alpha.1",
46
+ "@md-plugins/md-plugin-table": "0.1.0-alpha.1",
47
+ "@md-plugins/md-plugin-title": "0.1.0-alpha.1",
48
+ "@md-plugins/md-plugin-codeblocks": "0.1.0-alpha.1",
49
+ "@md-plugins/md-plugin-blockquote": "0.1.0-alpha.1",
50
+ "@md-plugins/md-plugin-image": "0.1.0-alpha.1",
51
+ "@md-plugins/md-plugin-link": "0.1.0-alpha.1"
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ },
56
+ "scripts": {
57
+ "build": "unbuild",
58
+ "clean": "rm -rf dist"
59
+ }
60
+ }