marko/packages/babel-utils/src/template-string.js
2024-01-09 14:31:31 -07:00

57 lines
1.5 KiB
JavaScript

import { types as t } from "@marko/compiler";
import jsesc from "jsesc";
export function normalizeTemplateString(quasis, ...expressions) {
quasis = quasis.map((q) => (t.isTemplateElement(q) ? q.value.cooked : q));
for (let i = expressions.length; i--; ) {
let v = expressions[i];
if (t.isTemplateLiteral(v)) {
quasis[i] += v.quasis[0].value.cooked;
quasis[i + 1] =
v.quasis[v.quasis.length - 1].value.cooked + (quasis[i + 1] || "");
quasis.splice(
i + 1,
0,
...v.quasis.slice(1, -1).map((q) => q.value.cooked),
);
expressions.splice(i, 1, ...v.expressions);
i += v.expressions.length;
} else if (t.isStringLiteral(v) || typeof v === "string") {
const value = t.isStringLiteral(v) ? v.value : v;
quasis[i] += value + quasis[i + 1];
expressions.splice(i, 1);
quasis.splice(i + 1, 1);
}
}
if (!expressions.length) {
// No expression, just return a literal or empty.
const literal = quasis.join("");
return literal === "" ? undefined : t.stringLiteral(literal);
}
if (
expressions.length === 1 &&
quasis.length === 2 &&
quasis.every(isEmptyString)
) {
// Only expression `${expr}` just return the expr.
return expressions[0];
}
// Do it.
return t.templateLiteral(quasis.map(getTemplateElement), expressions);
}
function getTemplateElement(s = "") {
return t.templateElement({
cooked: s,
raw: jsesc(s, { quotes: "backtick" }),
});
}
function isEmptyString(s = "") {
return s === "";
}