vite-plugin-emt
Version:
emt support for vite
279 lines (278 loc) • 8.61 kB
JavaScript
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, "&").replace(/</g, "<").replace(/>/g, ">");
}, 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 = "${" + 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
};