UNPKG

@maizzle/framework

Version:

Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.

49 lines (48 loc) 2.19 kB
import { readFileSync } from "node:fs"; import { dirname, resolve } from "node:path"; //#region src/render/plugins/markdownExtract.ts /** * Vite plugin that pre-processes <Markdown> tags: * - Extracts slot content, dedents it, and passes as :content prop * - Resolves `src` prop to read file contents at build time */ function markdownExtract() { const re = /<(Markdown|markdown)((?:\s[^>]*?)?)>([\s\S]*?)<\/\1>/g; const selfClosingRe = /<(Markdown|markdown)((?:\s[^>]*?\bsrc\s*=\s*"[^"]*"[^>]*?))\/>/g; return { name: "maizzle:markdown-extract", enforce: "pre", transform(code, id) { if (!id.endsWith(".vue") && !id.endsWith(".md")) return; if (!code.includes("Markdown") && !code.includes("markdown")) return; let transformed = code; transformed = transformed.replace(re, (_match, tag, attrs, content) => { if (/(?:^|\s):?content\b/.test(attrs) || /v-bind:content\b/.test(attrs)) return _match; const stripped = content.replace(/^\n+/, "").replace(/\s+$/, ""); if (!stripped) return _match; const minIndent = stripped.match(/^[ \t]*(?=\S)/gm)?.reduce((min, ws) => Math.min(min, ws.length), Infinity) ?? 0; return `<${tag}${attrs} content="${(minIndent > 0 ? stripped.replace(new RegExp(`^[ \\t]{${minIndent}}`, "gm"), "") : stripped).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}" />`; }); transformed = transformed.replace(selfClosingRe, (_match, tag, attrs) => { const srcMatch = attrs.match(/\bsrc\s*=\s*"([^"]*)"/); if (!srcMatch) return _match; const srcPath = srcMatch[1]; const resolvedPath = resolve(dirname(id), srcPath); let fileContent; try { fileContent = readFileSync(resolvedPath, "utf-8").trim(); } catch { return _match; } return `<${tag}${attrs.replace(/\s*\bsrc\s*=\s*"[^"]*"/, "").replace(/\s*\bcontent\s*=\s*"[^"]*"/, "")} content="${fileContent.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}" />`; }); if (transformed !== code) return { code: transformed, map: null }; } }; } //#endregion export { markdownExtract }; //# sourceMappingURL=markdownExtract.js.map