UNPKG

vite-plugin-emt

Version:

emt support for vite

279 lines (278 loc) 8.61 kB
import H, { tagProcs as k } from "emmetlite"; export * from "emmetlite"; import { basename as C, posix as I, resolve as P } from "path"; import z from "readline"; import Q from "events"; import F from "magic-string"; import { readFileSync as B, writeFile as D, existsSync as v, promises as V, createReadStream as G } from "fs"; import { all as J } from "known-css-properties"; import M from "picocolors"; import { render as U } from "stylus"; import { transformWithEsbuild as K } from "vite"; let O = []; const L = (e) => e.length && e.join ? "\0" + e.join("\0") : Object.getOwnPropertyNames(e).join("\0"), R = (e, a = "[", r = "]") => { if (e = e.trimStart(), e[0] != a) return ""; let o = 1, s = 1; for (; s < e.length && (e[s] == a ? o++ : e[s] == r && o--, !!o); s++) ; return e.substring(1, s); }, j = (e) => { let a = e[0] == ":"; a && (e = e.substring(1)); let r = ""; for (const o of O) if (e in o) { r = o[e]; break; } return typeof r == "object" && (r = L(r)), a ? r : (r + "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); }, A = () => { O.unshift({}); }, N = () => { O.shift(); }, $ = (e, a = 5) => { let r = ""; do { let o = e.indexOf("$") + 1; if (!o) break; r += e.substring(0, o - 1), e = e.substring(o); let s, c = ""; if (e[0] == "{") { if (s = R(e, "{", "}"), !s) break; if (!a) throw new Error("MaxDepth exceeded"); if (s.trimStart().startsWith("include")) try { c = (0, eval)(s); } catch (p) { console.error(p); } else c = "&#36;{" + s + "}"; A(), r += $(c, a - 1), N(), e = e.substring(s.length + 2); continue; } let d = /^:?[a-z0-9_.]+/i, h = d.exec(e); if (!h) continue; const [E] = h, x = j(E); if (e = e.substring(E.length), d = /^\s*\?\s*/, h = d.exec(e), h && (c = e.substring(h[0].length), s = R(c), s)) { const p = x && x != "0" && x != "false"; if (p && (r += $(s, a)), c = c.substring(s.length + 2).trimStart(), c[0] == ":") { let g = c.substring(1).trimStart(); s = R(g), s && (p || (r += $(s, a)), c = g.substring(s.length + 2)); } e = c; continue; } if (d = /^\s*:\s*/, h = d.exec(e), h) { c = e.substring(h[0].length), d = /^([a-z0-9_.]+)(?:\s+([a-z0-9_.]+))?/i, h = d.exec(c); let [p, g, w] = h || [""]; if (w || (w = g, g = ""), c = c.substring(p.length).trimStart(), p = R(c), p) { const T = x[0] == "\0"; if (x.length > +T) { A(); const W = x.substring(+T).split("\0"), _ = O[0]; for (o = 0; o < W.length; o++) { if (T) g && (_[g] = o), w && (_[w] = W[o]); else { let t = E + "." + W[o]; if (t.length > 256) throw new Error("Name too long"); g && (_[g] = t), w && (_[w] = j(t)); } r += $(p, a); } N(); } e = c.substring(p.length + 2); continue; } } r += x || "$" + E; } while (e); return r + e; }, X = (e, a = {}, r = 5) => (globalThis.REQUEST_PATH = a.REQUEST_PATH, O = [a], $(e, r)), Y = (e, a) => e.startsWith(a + "/") ? I.relative(a, e) : e, Z = (e, a) => e.config.logger.info( M.green("page reload ") + M.dim(Y(a, e.config.root)), { clear: !0, timestamp: !0 } ), fe = (e) => { const a = e?.literal ?? "styl"; return { name: "inline-stylus", enforce: "pre", transformIndexHtml: (r) => r.replace( /(<style[^>]*)\slang=(?:"styl"|'styl')([^>]*?>)(.*?)(?=<\/style>)/gs, (o, s, c, d) => s + c + U(d, e) ), // parse styl`...` transform(r, o) { if (a && (o.endsWith(".js") || o.endsWith(".ts"))) { const s = new F(r); return { code: s.replace( new RegExp("\\b" + a + "\\s*`(.*?)(?<!\\\\)`", "gs"), (c, d) => "`" + U(d, e) + "`" ).toString(), map: s.generateMap({ source: o }) }; } if (o.includes("&direct") && o.endsWith(".css")) return { code: U(r, e) }; } }; }, ue = (e) => ({ name: "inline-ts", transform(a, r) { if (r.includes("html-proxy&") && r.endsWith(".js")) return K( a, C(r.replace(/\?.+/, "")) + ".ts", e ); } }), me = (e = {}) => { const a = (t) => { const i = t ? W(t) : ""; return i.replace(/@unocss-placeholder/g, (f) => { let n = ""; const l = / class="(.+?)"/gs; for (let u; u = l.exec(i); ) n += u[1] + " "; return (n &&= "/* " + n + "*/ ") + f; }); }, { classy: r = !0, literal: o = "emt", log: s = Z, read: c = a, render: d = X, tplFile: h = "page.emt", paths: E = [], templated: x = !0, writeHtml: p } = e; let g = e.root; if (r) { const { cssProps: t = new Set(J) } = e; k.unshift((i) => { const { match: f, token: n, result: l } = i; if (f != n) { const u = t.has(f), b = u ? ' style="' : ' class="', y = l.length, m = l[y - 1], S = n.replace(/\$/g, "$$$$").replace(u ? /\s/ : /\s/g, u ? ":" : "-"); return l[y - 1] = m.replace(/>.+/gs, ">").includes(b) ? m.replace( RegExp(`(${b}.+?)"`, "s"), "$1" + (u ? ";" : " ") + S + '"' ) : m.replace(">", b + S + '">'), i.tag = "", !0; } }); } const w = (t, i = g, f = !1) => { let n = t.indexOf("?"); t = P(process.cwd(), i, n < 0 ? t : t.substring(0, n)); let l = t; if (!v(l) && (l += ".emt", v(l) || (l = t + ".html"), !v(l))) { if (f) throw new Error("Failed to resolve " + t); return ""; } return l; }, T = (t, i = !0) => { let f; for (const n of E) if (f = w(t, n), f) break; return f || w(t, g, i); }, W = globalThis.include = (t) => { t = T(t); const i = B(t, "utf8"); return t?.endsWith(".emt") ? H(i, " ") : i; }; k.push((t) => { const { tag: i, attr: f } = t; let n; if (i.includes("-")) n = i; else for (let l = 1; l < f.length; ) { const u = /^is="(.+?)"/is.exec(f[l++]); if (u) { n = u[1]; break; } } if (n) { const l = c(T(n, !1)); t.content = (_?.has(n) ? l.replace(/<script [^>]*?type="module"[^>]*?>.*?<\/script>/gis, "") : l) + t.content, _?.add(n); } }); const _ = x ? /* @__PURE__ */ new Set() : null; return { name: "emt-template", enforce: "pre", configureServer(t) { g = P(g || t.config.root); const i = {}; async function f(n, l) { const u = { REQUEST_PATH: n, DOCUMENT_ROOT: g }, b = (await V.stat(l)).mtime.getTime(); if (n in i && b == i[n].time) u.doc_title = i[n].title; else { const y = z.createInterface({ input: G(l), crlfDelay: 1 / 0 }); y.on("line", (m) => { if (m = m.trimStart(), m.startsWith("title") && (m = m.substring(5).trimStart(), m[0] == "{")) { let S; (S = /\{(.*)}\*/.exec(m)) && (u.doc_title = S[1], i[n] = { title: S[1], time: b }, y.close()); } }), await Q.once(y, "close"); } return u; } t.middlewares.use(async (n, l, u) => { const b = n.originalUrl?.substring(1) || "index.emt"; if (!b.endsWith(".emt")) return u(); const y = w(b); if (!y) return u(); _?.clear(); const m = await f(b, y), S = d(W("doc_title" in m ? h : y), m); p && D(m.DOCUMENT_ROOT + "/" + C(b, ".emt") + ".html", S, (q) => { }), l.setHeader("Content-Type", "text/html; charset=utf-8"), l.end("doc_title" in m ? await t.transformIndexHtml?.(n.originalUrl, S, n.originalUrl) : S); }); }, handleHotUpdate({ file: t, server: i }) { if (t.endsWith(".emt")) return i.ws.send({ type: "full-reload", path: e.alwaysReload ? "*" : t }), s(i, t), []; }, // parse emt`...` transform(t, i) { if (o && (i.endsWith(".js") || i.endsWith(".ts"))) { const f = new F(t); return { code: f.replace( RegExp("\\b" + o + "\\s*`(.*?)(?<!\\\\)`", "gs"), (n, l) => "`" + H(l, " ") + "`" ).toString(), map: f.generateMap({ source: i }) }; } }, ...e }; }; export { O as appdata, me as default, fe as inlineStylus, ue as inlineTS, Z as logger, X as render };