🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

prettier-plugin-marko

Package Overview
Dependencies
Maintainers
7
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prettier-plugin-marko - npm Package Compare versions

Comparing version
4.0.5
to
4.0.6
+238
-277
dist/index.js

@@ -774,56 +774,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

print(path, opts, print) {
const { node } = path;
switch (node.type) {
case NodeType.AttrArgs:
case NodeType.AttrMethod:
case NodeType.AttrNamed:
case NodeType.AttrSpread:
case NodeType.Class:
case NodeType.Export:
case NodeType.Import:
case NodeType.OpenTagName:
case NodeType.Placeholder:
case NodeType.Scriptlet:
case NodeType.ShorthandClassName:
case NodeType.ShorthandId:
case NodeType.Static:
case NodeType.Style:
case NodeType.TagArgs:
case NodeType.TagParams:
case NodeType.TagTypeArgs:
case NodeType.TagTypeParams:
case NodeType.TagVar: return printExact(path, opts, print);
case NodeType.CDATA: return printCDATA(path, opts, print);
case NodeType.Comment: return printComment(path, opts, print);
case NodeType.Doctype: return printDoctype(path, opts, print);
case NodeType.Declaration: return printDeclaration(path, opts, print);
case NodeType.Program: return printProgram(path, opts, print);
case NodeType.Tag:
case NodeType.AttrTag: return printTag(path, opts, print);
case NodeType.Text: return printText(path, opts, print);
default: throw new Error(`Unknown node type in Marko template: ${NodeType[node.type] || node.type}`);
}
const { type } = path.node;
const handler = printHandlers[type];
if (handler) return handler(path, opts, print);
/* c8 ignore next */
throw new Error(`Unknown node type in Marko template: ${NodeType[type] || type}`);
},
embed(path, opts) {
switch (path.node?.type) {
case NodeType.AttrNamed: return embedAttrNamed;
case NodeType.AttrSpread: return embedAttrSpread;
case NodeType.Class: return embedClass;
case NodeType.Export: return embedExport;
case NodeType.Import: return embedImport;
case NodeType.OpenTagName: return embedOpenTagName;
case NodeType.Placeholder: return embedPlaceholder;
case NodeType.Scriptlet: return embedScriptlet;
case NodeType.ShorthandClassName: return embedShorthandClassName;
case NodeType.ShorthandId: return embedShorthandId;
case NodeType.Static: return embedStatic;
case NodeType.Style: return embedStyle;
case NodeType.Tag: return embedTag(path, opts);
case NodeType.TagArgs: return embedTagArgs;
case NodeType.TagParams: return embedTagParams;
case NodeType.TagTypeArgs: return embedTagTypeArgs;
case NodeType.TagTypeParams: return embedTagTypeParams;
case NodeType.TagVar: return embedTagVar;
}
return null;
embed(path) {
return embedHandlers[path.node.type] ?? null;
},

@@ -834,47 +788,208 @@ getVisitorKeys(node) {

} };
const printProgram = (path, opts, print) => {
const body = printBody(path, opts, print);
const lastStatic = path.node.static.length - (body ? 0 : 1);
let programDoc = path.map((child, i) => i !== lastStatic && hasExplicitLine(child, opts) ? [child.call(print), b.hardline] : child.call(print), "static");
if (body) if (body.inline) programDoc.push(wrapConciseText(body.content));
else programDoc = [...programDoc, ...body.content];
return [b.join(b.hardline, programDoc), b.hardline];
const printHandlers = {
[NodeType.AttrArgs]: printExact,
[NodeType.AttrMethod]: printExact,
[NodeType.AttrNamed]: printExact,
[NodeType.AttrSpread]: printExact,
[NodeType.Class]: printExact,
[NodeType.Export]: printExact,
[NodeType.Import]: printExact,
[NodeType.OpenTagName]: printExact,
[NodeType.Placeholder]: printExact,
[NodeType.Scriptlet]: printExact,
[NodeType.ShorthandClassName]: printExact,
[NodeType.ShorthandId]: printExact,
[NodeType.Static]: printExact,
[NodeType.Style]: printExact,
[NodeType.TagArgs]: printExact,
[NodeType.TagParams]: printExact,
[NodeType.TagTypeArgs]: printExact,
[NodeType.TagTypeParams]: printExact,
[NodeType.TagVar]: printExact,
[NodeType.Tag]: printTag,
[NodeType.AttrTag]: printTag,
[NodeType.CDATA]: (path, opts) => `<![CDATA[${read(path.node.value, opts)}]]>`,
[NodeType.Comment]: (path, opts) => {
const { node } = path;
const code = read(node, opts);
if (node.block) {
if (code.includes("\n")) {
const lines = code.split("\n");
const len = lines.length;
let indent = Infinity;
for (let i = 1; i < len; i++) {
const match = lines[i].match(/^(\s+)/);
if (match) indent = Math.min(indent, match[1].length);
else {
indent = 0;
break;
}
}
const parts = [lines[0]];
for (let i = 1; i < len; i++) parts.push(b.hardline, indent ? lines[i].slice(indent) : lines[i]);
return parts;
}
return code;
}
return b.lineSuffix(code);
},
[NodeType.Doctype]: (path, opts) => `<!${read(path.node.value, opts).replace(/\s+/g, " ").trim()}>`,
[NodeType.Declaration]: (path, opts) => `<?${read(path.node.value, opts).trim()}?>`,
[NodeType.Program]: (path, opts, print) => {
const body = printBody(path, opts, print);
const lastStatic = path.node.static.length - (body ? 0 : 1);
let programDoc = path.map((child, i) => i !== lastStatic && hasExplicitLine(child, opts) ? [child.call(print), b.hardline] : child.call(print), "static");
if (body) if (body.inline) programDoc.push(wrapConciseText(body.content));
else programDoc = [...programDoc, ...body.content];
return [b.join(b.hardline, programDoc), b.hardline];
},
[NodeType.Text]: (path, opts) => {
const text = read(path.node, opts).replace(/\\/g, "\\\\");
return /^\$!?{/.test(text) ? "\\" + text : text;
}
};
const printDoctype = (path, opts) => {
return `<!${read(path.node.value, opts).replace(/\s+/g, " ").trim()}>`;
};
const printDeclaration = (path, opts) => {
return `<?${read(path.node.value, opts).trim()}?>`;
};
const printCDATA = (path, opts) => {
return `<![CDATA[${read(path.node.value, opts)}]]>`;
};
const printComment = (path, opts) => {
const { node } = path;
const code = read(node, opts);
if (node.block) {
if (code.includes("\n")) {
const lines = code.split("\n");
const len = lines.length;
let indent = Infinity;
for (let i = 1; i < len; i++) {
const match = lines[i].match(/^(\s+)/);
if (match) indent = Math.min(indent, match[1].length);
else {
indent = 0;
break;
const embedHandlers = {
[NodeType.Class]: (toDoc, _print, path, opts) => toDoc(read(path.node, opts), exprParse),
[NodeType.Import]: (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse),
[NodeType.Export]: (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse),
[NodeType.Style]: async (toDoc, _print, path, opts) => {
const { node } = path;
const code = read(node.value, opts).trim();
const parser = getParserFromExt(node.ext?.slice(node.ext.lastIndexOf(".")) || ".css");
if (parser) return b.group([
`style${node.ext || ""} {`,
b.indent([b.line, await toDoc(code, { parser })]),
b.line,
"}"
]);
},
[NodeType.Static]: async (toDoc, _print, path, opts) => {
const { node } = path;
const code = opts._markoParsed.code.slice(node.start + node.target.length + 1, node.end).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [`${node.target} `, withBlockIfNeeded(await toDoc(code, stmtParse))] : [];
},
[NodeType.Scriptlet]: async (toDoc, _print, path, opts) => {
const code = read(path.node.value, opts).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [
b.breakParent,
"$ ",
withBlockIfNeeded(await toDoc(code, stmtParse))
] : [];
},
[NodeType.OpenTagName]: (toDoc, _print, path, opts) => templateToDoc(toDoc, path, opts),
[NodeType.Placeholder]: async (toDoc, _print, path, opts) => {
const { node } = path;
const code = read(node.value, opts);
if (code === "\" \"" || code === "' '") return getVisibleSpace(opts);
return b.group([
node.escape ? "${" : "$!{",
b.indent([b.softline, await toDoc(code, exprParse)]),
b.softline,
"}"
]);
},
[NodeType.TagArgs]: (toDoc, _print, path, opts) => argsToDoc(path.node, opts, toDoc),
[NodeType.AttrNamed]: async (toDoc, _print, path, opts) => {
const { node } = path;
const name = read(node.name, opts);
if (!(node.args || node.value)) return name;
const attrDoc = [name];
if (node.args && !isEmpty(node.args.value, opts)) {
const argsDoc = await argsToDoc(node.args, opts, toDoc);
if (argsDoc) attrDoc.push(argsDoc);
else return unexpectedDoc(opts, node);
}
if (node.value) if (node.value.type === NodeType.AttrMethod) {
const attrMethodDoc = await toDoc(`function${read(node.value, opts)}`, exprParse);
if (Array.isArray(attrMethodDoc) && attrMethodDoc.length && typeof attrMethodDoc[0] === "string") {
attrMethodDoc[0] = attrMethodDoc[0].replace(/^function\s*/, "");
attrDoc.push(attrMethodDoc);
} else return unexpectedDoc(opts, node);
} else attrDoc.push(node.value.bound ? ":=" : "=", withParensIfNeeded(await toDoc(read(node.value.value, opts), exprParse), isConcise(opts)));
return b.group(attrDoc);
},
[NodeType.AttrSpread]: async (toDoc, _print, path, opts) => {
return b.group(["...", withParensIfNeeded(await toDoc(read(path.node.value, opts), exprParse), isConcise(opts))]);
},
[NodeType.ShorthandId]: async (toDoc, _print, path, opts) => ["#", await templateToDoc(toDoc, path, opts)],
[NodeType.ShorthandClassName]: async (toDoc, _print, path, opts) => [".", await templateToDoc(toDoc, path, opts)],
[NodeType.Tag]: async (toDoc, print, path, opts) => {
const parser = getTagParser(path.node, opts);
if (parser === void 0) return void 0;
return printTag(path, opts, print, {
inline: true,
preserve: parser === false,
content: await getFormattedBody(path, parser, toDoc, print, opts)
});
},
[NodeType.TagVar]: async (toDoc, _print, path, opts) => {
const { node } = path;
let doc = await toDoc(`var ${read(node.value, opts).trim()}=_`, stmtParse);
if (Array.isArray(doc) && doc.length === 1) doc = doc[0];
if (typeof doc === "object" && !Array.isArray(doc) && doc.type === "group") doc = doc.contents;
if (Array.isArray(doc) && doc.length > 1) {
const varPart = doc[1];
if (typeof varPart === "object" && "type" in varPart && varPart.type === "group" && Array.isArray(varPart.contents)) {
const varContents = varPart.contents;
for (let i = varContents.length; i--;) {
const item = varContents[i];
if (typeof item === "string") {
const match = /\s*=\s*$/.exec(item);
if (match) {
varContents[i] = item.slice(0, -match[0].length);
varContents.length = i + 1;
return ["/", varContents];
}
}
}
}
const parts = [lines[0]];
for (let i = 1; i < len; i++) parts.push(b.hardline, indent ? lines[i].slice(indent) : lines[i]);
return parts;
}
return code;
return unexpectedDoc(opts, node);
/* c8 ignore stop */
},
[NodeType.TagTypeArgs]: async (toDoc, _print, path, opts) => {
const { node } = path;
if (isEmpty(node.value, opts)) return "";
const doc = await toDoc(`_<${read(node.value, opts).trim()}>`, exprParse);
if (typeof doc === "string") return doc.replace(/^_/, "");
if (Array.isArray(doc) && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
/* c8 ignore next */
return unexpectedDoc(opts, node);
},
[NodeType.TagParams]: async (toDoc, _print, path, opts) => {
const { node } = path;
if (isEmpty(node.value, opts)) return "";
const doc = await toDoc(`function _(${read(node.value, opts).trim()}){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) {
const paramsGroup = doc[1];
if (paramsGroup && typeof paramsGroup === "object" && "type" in paramsGroup && paramsGroup.type === "group" && Array.isArray(paramsGroup.contents)) {
const paramsContents = [...paramsGroup.contents];
const first = paramsContents[0];
const last = paramsContents[paramsContents.length - 1];
if (typeof first === "string" && typeof last === "string") {
paramsContents[0] = first.replace(/^\(/, "|");
paramsContents[paramsContents.length - 1] = last.replace(/\)$/, "|");
}
return b.group(paramsContents);
}
}
/* c8 ignore next */
return unexpectedDoc(opts, node);
},
[NodeType.TagTypeParams]: async (toDoc, _print, path, opts) => {
const { node } = path;
if (isEmpty(node.parent.params?.value, opts) || isEmpty(node.value, opts)) return "";
const doc = await toDoc(`function _<${read(node.value, opts).trim()}>(){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) return doc[1];
/* c8 ignore next */
return unexpectedDoc(opts, node);
}
return b.lineSuffix(code);
};
const printTag = ((path, opts, print, body = printBody(path, opts, print)) => {
function printTag(path, opts, print, body = printBody(path, opts, print)) {
return (isConcise(opts) ? printConciseTag : printHTMLTag)(path, opts, print, body);
});
const printHTMLTag = ((path, opts, print, body) => {
}
function printHTMLTag(path, opts, print, body) {
const { node } = path;

@@ -909,4 +1024,4 @@ const openTagDoc = ["<", printTagBeforeAttrs(path, opts, print)];

return b.group(openTagDoc);
});
const printConciseTag = ((path, opts, print, body) => {
}
function printConciseTag(path, opts, print, body) {
const { node } = path;

@@ -930,14 +1045,14 @@ const tagDoc = [printTagBeforeAttrs(path, opts, print)];

return b.group(tagDoc);
});
const printTagBeforeAttrs = (path, _opts, print) => {
}
function printTagBeforeAttrs(path, opts, print) {
const { node } = path;
const name = path.call(print, "name");
const doc = [name];
if (pathHas(path, "typeArgs")) doc.push(path.call(print, "typeArgs"));
if (pathHas(path, "typeArgs") && !isEmpty(path.node.typeArgs.value, opts)) doc.push(path.call(print, "typeArgs"));
if (pathHas(path, "shorthandId")) doc.push(path.call(print, "shorthandId"));
if (pathHas(path, "shorthandClassNames")) doc.push(path.map(print, "shorthandClassNames"));
if (pathHas(path, "args")) doc.push(path.call(print, "args"));
if (pathHas(path, "args") && !isEmpty(path.node.args.value, opts)) doc.push(path.call(print, "args"));
if (pathHas(path, "var")) doc.push(path.call(print, "var"));
if (pathHas(path, "params")) {
if (pathHas(path, "typeParams")) {
if (pathHas(path, "params") && !isEmpty(path.node.params.value, opts)) {
if (pathHas(path, "typeParams") && !isEmpty(path.node.typeParams.value, opts)) {
if (!(node.typeArgs || node.args || node.var)) doc.push(" ");

@@ -949,4 +1064,4 @@ doc.push(path.call(print, "typeParams"));

return doc.length === 1 ? name : doc;
};
const printBody = (path, opts, print) => {
}
function printBody(path, opts, print) {
const { node } = path;

@@ -963,3 +1078,2 @@ if (!node.body) return;

const childDoc = child.call(print);
if (!childDoc) return;
content ||= [];

@@ -1031,7 +1145,3 @@ if (isInline(child.node)) {

if (typeof childDoc === "string" && isVisibleSpace(childDoc)) {
if (endsWithLine(inline)) {
const last = inline.length - 1;
if (inline[last] === b.softline) inline[last] = b.line;
return;
}
if (endsWithLine(inline)) return;
childDoc = b.line;

@@ -1074,162 +1184,7 @@ }

}
};
const printText = (path, opts) => {
const text = read(path.node, opts).replace(/\\/g, "\\\\");
if (/^\$!?{/.test(text)) return "\\" + text;
return text;
};
const printExact = (path, opts) => read(path.node, opts);
const embedClass = (toDoc, _print, path, opts) => toDoc(read(path.node, opts), exprParse);
const embedImport = (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse);
const embedExport = (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse);
const embedStyle = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
const parser = getParserFromExt(node.ext?.slice(node.ext.lastIndexOf(".")) || ".css");
if (parser) return b.group([
`style${node.ext || ""} {`,
b.indent([b.line, await toDoc(code, { parser })]),
b.line,
"}"
]);
};
const embedStatic = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = opts._markoParsed.code.slice(node.start + node.target.length + 1, node.end).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [`${node.target} `, withBlockIfNeeded(await toDoc(code, stmtParse))] : [];
};
const embedScriptlet = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [
b.breakParent,
"$ ",
withBlockIfNeeded(await toDoc(code, stmtParse))
] : [];
};
const embedOpenTagName = async (toDoc, _print, path, opts) => embedTemplate(toDoc, _print, path, opts);
const embedPlaceholder = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts);
if (code === "\" \"" || code === "' '") return getVisibleSpace(opts);
return b.group([
node.escape ? "${" : "$!{",
b.indent([b.softline, await toDoc(code, exprParse)]),
b.softline,
"}"
]);
};
const embedTagArgs = (toDoc, _print, path, opts) => {
return argsToDoc(path.node, opts, toDoc);
};
const embedAttrNamed = async (toDoc, _print, path, opts) => {
const node = path.node;
const name = read(node.name, opts);
if (!(node.args || node.value)) return name;
const attrDoc = [name];
if (node.args) {
const argsDoc = await argsToDoc(node.args, opts, toDoc);
if (argsDoc) attrDoc.push(argsDoc);
else return unexpectedDoc(opts, node);
}
if (node.value) if (node.value.type === NodeType.AttrMethod) {
const attrMethodDoc = await toDoc(`function${read(node.value, opts)}`, exprParse);
if (Array.isArray(attrMethodDoc) && attrMethodDoc.length && typeof attrMethodDoc[0] === "string") {
attrMethodDoc[0] = attrMethodDoc[0].replace(/^function\s*/, "");
attrDoc.push(attrMethodDoc);
} else return unexpectedDoc(opts, node);
} else attrDoc.push(node.value.bound ? ":=" : "=", withParensIfNeeded(await toDoc(read(node.value.value, opts), exprParse), isConcise(opts)));
return b.group(attrDoc);
};
const embedAttrSpread = async (toDoc, _print, path, opts) => {
const node = path.node;
return b.group(["...", withParensIfNeeded(await toDoc(read(node.value, opts), exprParse), isConcise(opts))]);
};
const embedShorthandId = async (toDoc, print, path, opts) => ["#", await embedTemplate(toDoc, print, path, opts)];
const embedShorthandClassName = async (toDoc, print, path, opts) => [".", await embedTemplate(toDoc, print, path, opts)];
const embedTag = (path, opts) => {
const tag = path.node;
const parser = getTagParser(tag, opts);
if (parser === void 0) return null;
return async (toDoc, print, path, opts) => printTag(path, opts, print, {
inline: true,
preserve: parser === false,
content: await getFormattedBody(path, parser, toDoc, print, opts)
});
};
const embedTagVar = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
let doc = await toDoc(`var ${code}=_`, stmtParse);
if (Array.isArray(doc) && doc.length === 1) doc = doc[0];
if (typeof doc === "object" && !Array.isArray(doc) && doc.type === "group") doc = doc.contents;
if (Array.isArray(doc) && doc.length > 1) {
const varPart = doc[1];
if (typeof varPart === "object" && "type" in varPart && varPart.type === "group" && Array.isArray(varPart.contents)) {
const varContents = varPart.contents;
for (let i = varContents.length; i--;) {
const item = varContents[i];
if (typeof item === "string") {
const match = /\s*=\s*$/.exec(item);
if (match) {
varContents[i] = item.slice(0, -match[0].length);
varContents.length = i + 1;
return ["/", varContents];
}
}
}
}
}
return unexpectedDoc(opts, node);
}
return [];
};
const embedTagTypeArgs = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`_<${code}>`, exprParse);
if (typeof doc === "string") return doc.replace(/^_/, "");
if (Array.isArray(doc) && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
return unexpectedDoc(opts, node);
}
return [];
};
const embedTagParams = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`function _(${code}){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) {
const paramsGroup = doc[1];
if (paramsGroup && typeof paramsGroup === "object" && "type" in paramsGroup && paramsGroup.type === "group" && Array.isArray(paramsGroup.contents)) {
const paramsContents = [...paramsGroup.contents];
const first = paramsContents[0];
const last = paramsContents[paramsContents.length - 1];
if (typeof first === "string" && typeof last === "string") {
paramsContents[0] = first.replace(/^\(/, "|");
paramsContents[paramsContents.length - 1] = last.replace(/\)$/, "|");
}
return b.group(paramsContents);
}
}
return unexpectedDoc(opts, node);
}
return [];
};
const embedTagTypeParams = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`function _<${code}>(){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) return doc[1];
return unexpectedDoc(opts, node);
}
return [];
};
const embedTemplate = async (toDoc, _print, path, opts) => {
}
function printExact(path, opts) {
return read(path.node, opts);
}
async function templateToDoc(toDoc, path, opts) {
const { expressions, quasis } = path.node;

@@ -1252,14 +1207,12 @@ const first = read(quasis[0], opts);

return shorthandDoc;
};
}
async function argsToDoc(node, opts, toDoc) {
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`_(${code})`, exprParse);
if (Array.isArray(doc) && doc.length && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
return unexpectedDoc(opts, node);
if (isEmpty(node.value, opts)) return "";
const doc = await toDoc(`_(${read(node.value, opts).trim()})`, exprParse);
if (Array.isArray(doc) && doc.length && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
return [];
/* c8 ignore next */
return unexpectedDoc(opts, node);
}

@@ -1361,5 +1314,12 @@ function wrapConciseText(doc) {

}
const nonWhitespaceReg = /\S/g;
function isEmpty(range, opts) {
if (!range || range.start === range.end) return true;
nonWhitespaceReg.lastIndex = range.start;
return !(nonWhitespaceReg.test(opts._markoParsed.code) && nonWhitespaceReg.lastIndex <= range.end);
}
function pathHas(path, key) {
return !!path.node[key];
}
/* c8 ignore start */
function unexpectedDoc(opts, node) {

@@ -1370,2 +1330,3 @@ const parsed = opts._markoParsed;

}
/* c8 ignore stop */
exports.languages = languages;

@@ -1372,0 +1333,0 @@ exports.options = options;

@@ -1,2 +0,1 @@

import "node:module";
import { doc } from "prettier";

@@ -774,56 +773,10 @@ import { TagType, TagType as TagType$1, Validity, createParser, isValidAttrValue, isValidStatement } from "htmljs-parser";

print(path, opts, print) {
const { node } = path;
switch (node.type) {
case NodeType.AttrArgs:
case NodeType.AttrMethod:
case NodeType.AttrNamed:
case NodeType.AttrSpread:
case NodeType.Class:
case NodeType.Export:
case NodeType.Import:
case NodeType.OpenTagName:
case NodeType.Placeholder:
case NodeType.Scriptlet:
case NodeType.ShorthandClassName:
case NodeType.ShorthandId:
case NodeType.Static:
case NodeType.Style:
case NodeType.TagArgs:
case NodeType.TagParams:
case NodeType.TagTypeArgs:
case NodeType.TagTypeParams:
case NodeType.TagVar: return printExact(path, opts, print);
case NodeType.CDATA: return printCDATA(path, opts, print);
case NodeType.Comment: return printComment(path, opts, print);
case NodeType.Doctype: return printDoctype(path, opts, print);
case NodeType.Declaration: return printDeclaration(path, opts, print);
case NodeType.Program: return printProgram(path, opts, print);
case NodeType.Tag:
case NodeType.AttrTag: return printTag(path, opts, print);
case NodeType.Text: return printText(path, opts, print);
default: throw new Error(`Unknown node type in Marko template: ${NodeType[node.type] || node.type}`);
}
const { type } = path.node;
const handler = printHandlers[type];
if (handler) return handler(path, opts, print);
/* c8 ignore next */
throw new Error(`Unknown node type in Marko template: ${NodeType[type] || type}`);
},
embed(path, opts) {
switch (path.node?.type) {
case NodeType.AttrNamed: return embedAttrNamed;
case NodeType.AttrSpread: return embedAttrSpread;
case NodeType.Class: return embedClass;
case NodeType.Export: return embedExport;
case NodeType.Import: return embedImport;
case NodeType.OpenTagName: return embedOpenTagName;
case NodeType.Placeholder: return embedPlaceholder;
case NodeType.Scriptlet: return embedScriptlet;
case NodeType.ShorthandClassName: return embedShorthandClassName;
case NodeType.ShorthandId: return embedShorthandId;
case NodeType.Static: return embedStatic;
case NodeType.Style: return embedStyle;
case NodeType.Tag: return embedTag(path, opts);
case NodeType.TagArgs: return embedTagArgs;
case NodeType.TagParams: return embedTagParams;
case NodeType.TagTypeArgs: return embedTagTypeArgs;
case NodeType.TagTypeParams: return embedTagTypeParams;
case NodeType.TagVar: return embedTagVar;
}
return null;
embed(path) {
return embedHandlers[path.node.type] ?? null;
},

@@ -834,47 +787,208 @@ getVisitorKeys(node) {

} };
const printProgram = (path, opts, print) => {
const body = printBody(path, opts, print);
const lastStatic = path.node.static.length - (body ? 0 : 1);
let programDoc = path.map((child, i) => i !== lastStatic && hasExplicitLine(child, opts) ? [child.call(print), b.hardline] : child.call(print), "static");
if (body) if (body.inline) programDoc.push(wrapConciseText(body.content));
else programDoc = [...programDoc, ...body.content];
return [b.join(b.hardline, programDoc), b.hardline];
const printHandlers = {
[NodeType.AttrArgs]: printExact,
[NodeType.AttrMethod]: printExact,
[NodeType.AttrNamed]: printExact,
[NodeType.AttrSpread]: printExact,
[NodeType.Class]: printExact,
[NodeType.Export]: printExact,
[NodeType.Import]: printExact,
[NodeType.OpenTagName]: printExact,
[NodeType.Placeholder]: printExact,
[NodeType.Scriptlet]: printExact,
[NodeType.ShorthandClassName]: printExact,
[NodeType.ShorthandId]: printExact,
[NodeType.Static]: printExact,
[NodeType.Style]: printExact,
[NodeType.TagArgs]: printExact,
[NodeType.TagParams]: printExact,
[NodeType.TagTypeArgs]: printExact,
[NodeType.TagTypeParams]: printExact,
[NodeType.TagVar]: printExact,
[NodeType.Tag]: printTag,
[NodeType.AttrTag]: printTag,
[NodeType.CDATA]: (path, opts) => `<![CDATA[${read(path.node.value, opts)}]]>`,
[NodeType.Comment]: (path, opts) => {
const { node } = path;
const code = read(node, opts);
if (node.block) {
if (code.includes("\n")) {
const lines = code.split("\n");
const len = lines.length;
let indent = Infinity;
for (let i = 1; i < len; i++) {
const match = lines[i].match(/^(\s+)/);
if (match) indent = Math.min(indent, match[1].length);
else {
indent = 0;
break;
}
}
const parts = [lines[0]];
for (let i = 1; i < len; i++) parts.push(b.hardline, indent ? lines[i].slice(indent) : lines[i]);
return parts;
}
return code;
}
return b.lineSuffix(code);
},
[NodeType.Doctype]: (path, opts) => `<!${read(path.node.value, opts).replace(/\s+/g, " ").trim()}>`,
[NodeType.Declaration]: (path, opts) => `<?${read(path.node.value, opts).trim()}?>`,
[NodeType.Program]: (path, opts, print) => {
const body = printBody(path, opts, print);
const lastStatic = path.node.static.length - (body ? 0 : 1);
let programDoc = path.map((child, i) => i !== lastStatic && hasExplicitLine(child, opts) ? [child.call(print), b.hardline] : child.call(print), "static");
if (body) if (body.inline) programDoc.push(wrapConciseText(body.content));
else programDoc = [...programDoc, ...body.content];
return [b.join(b.hardline, programDoc), b.hardline];
},
[NodeType.Text]: (path, opts) => {
const text = read(path.node, opts).replace(/\\/g, "\\\\");
return /^\$!?{/.test(text) ? "\\" + text : text;
}
};
const printDoctype = (path, opts) => {
return `<!${read(path.node.value, opts).replace(/\s+/g, " ").trim()}>`;
};
const printDeclaration = (path, opts) => {
return `<?${read(path.node.value, opts).trim()}?>`;
};
const printCDATA = (path, opts) => {
return `<![CDATA[${read(path.node.value, opts)}]]>`;
};
const printComment = (path, opts) => {
const { node } = path;
const code = read(node, opts);
if (node.block) {
if (code.includes("\n")) {
const lines = code.split("\n");
const len = lines.length;
let indent = Infinity;
for (let i = 1; i < len; i++) {
const match = lines[i].match(/^(\s+)/);
if (match) indent = Math.min(indent, match[1].length);
else {
indent = 0;
break;
const embedHandlers = {
[NodeType.Class]: (toDoc, _print, path, opts) => toDoc(read(path.node, opts), exprParse),
[NodeType.Import]: (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse),
[NodeType.Export]: (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse),
[NodeType.Style]: async (toDoc, _print, path, opts) => {
const { node } = path;
const code = read(node.value, opts).trim();
const parser = getParserFromExt(node.ext?.slice(node.ext.lastIndexOf(".")) || ".css");
if (parser) return b.group([
`style${node.ext || ""} {`,
b.indent([b.line, await toDoc(code, { parser })]),
b.line,
"}"
]);
},
[NodeType.Static]: async (toDoc, _print, path, opts) => {
const { node } = path;
const code = opts._markoParsed.code.slice(node.start + node.target.length + 1, node.end).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [`${node.target} `, withBlockIfNeeded(await toDoc(code, stmtParse))] : [];
},
[NodeType.Scriptlet]: async (toDoc, _print, path, opts) => {
const code = read(path.node.value, opts).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [
b.breakParent,
"$ ",
withBlockIfNeeded(await toDoc(code, stmtParse))
] : [];
},
[NodeType.OpenTagName]: (toDoc, _print, path, opts) => templateToDoc(toDoc, path, opts),
[NodeType.Placeholder]: async (toDoc, _print, path, opts) => {
const { node } = path;
const code = read(node.value, opts);
if (code === "\" \"" || code === "' '") return getVisibleSpace(opts);
return b.group([
node.escape ? "${" : "$!{",
b.indent([b.softline, await toDoc(code, exprParse)]),
b.softline,
"}"
]);
},
[NodeType.TagArgs]: (toDoc, _print, path, opts) => argsToDoc(path.node, opts, toDoc),
[NodeType.AttrNamed]: async (toDoc, _print, path, opts) => {
const { node } = path;
const name = read(node.name, opts);
if (!(node.args || node.value)) return name;
const attrDoc = [name];
if (node.args && !isEmpty(node.args.value, opts)) {
const argsDoc = await argsToDoc(node.args, opts, toDoc);
if (argsDoc) attrDoc.push(argsDoc);
else return unexpectedDoc(opts, node);
}
if (node.value) if (node.value.type === NodeType.AttrMethod) {
const attrMethodDoc = await toDoc(`function${read(node.value, opts)}`, exprParse);
if (Array.isArray(attrMethodDoc) && attrMethodDoc.length && typeof attrMethodDoc[0] === "string") {
attrMethodDoc[0] = attrMethodDoc[0].replace(/^function\s*/, "");
attrDoc.push(attrMethodDoc);
} else return unexpectedDoc(opts, node);
} else attrDoc.push(node.value.bound ? ":=" : "=", withParensIfNeeded(await toDoc(read(node.value.value, opts), exprParse), isConcise(opts)));
return b.group(attrDoc);
},
[NodeType.AttrSpread]: async (toDoc, _print, path, opts) => {
return b.group(["...", withParensIfNeeded(await toDoc(read(path.node.value, opts), exprParse), isConcise(opts))]);
},
[NodeType.ShorthandId]: async (toDoc, _print, path, opts) => ["#", await templateToDoc(toDoc, path, opts)],
[NodeType.ShorthandClassName]: async (toDoc, _print, path, opts) => [".", await templateToDoc(toDoc, path, opts)],
[NodeType.Tag]: async (toDoc, print, path, opts) => {
const parser = getTagParser(path.node, opts);
if (parser === void 0) return void 0;
return printTag(path, opts, print, {
inline: true,
preserve: parser === false,
content: await getFormattedBody(path, parser, toDoc, print, opts)
});
},
[NodeType.TagVar]: async (toDoc, _print, path, opts) => {
const { node } = path;
let doc = await toDoc(`var ${read(node.value, opts).trim()}=_`, stmtParse);
if (Array.isArray(doc) && doc.length === 1) doc = doc[0];
if (typeof doc === "object" && !Array.isArray(doc) && doc.type === "group") doc = doc.contents;
if (Array.isArray(doc) && doc.length > 1) {
const varPart = doc[1];
if (typeof varPart === "object" && "type" in varPart && varPart.type === "group" && Array.isArray(varPart.contents)) {
const varContents = varPart.contents;
for (let i = varContents.length; i--;) {
const item = varContents[i];
if (typeof item === "string") {
const match = /\s*=\s*$/.exec(item);
if (match) {
varContents[i] = item.slice(0, -match[0].length);
varContents.length = i + 1;
return ["/", varContents];
}
}
}
}
const parts = [lines[0]];
for (let i = 1; i < len; i++) parts.push(b.hardline, indent ? lines[i].slice(indent) : lines[i]);
return parts;
}
return code;
return unexpectedDoc(opts, node);
/* c8 ignore stop */
},
[NodeType.TagTypeArgs]: async (toDoc, _print, path, opts) => {
const { node } = path;
if (isEmpty(node.value, opts)) return "";
const doc = await toDoc(`_<${read(node.value, opts).trim()}>`, exprParse);
if (typeof doc === "string") return doc.replace(/^_/, "");
if (Array.isArray(doc) && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
/* c8 ignore next */
return unexpectedDoc(opts, node);
},
[NodeType.TagParams]: async (toDoc, _print, path, opts) => {
const { node } = path;
if (isEmpty(node.value, opts)) return "";
const doc = await toDoc(`function _(${read(node.value, opts).trim()}){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) {
const paramsGroup = doc[1];
if (paramsGroup && typeof paramsGroup === "object" && "type" in paramsGroup && paramsGroup.type === "group" && Array.isArray(paramsGroup.contents)) {
const paramsContents = [...paramsGroup.contents];
const first = paramsContents[0];
const last = paramsContents[paramsContents.length - 1];
if (typeof first === "string" && typeof last === "string") {
paramsContents[0] = first.replace(/^\(/, "|");
paramsContents[paramsContents.length - 1] = last.replace(/\)$/, "|");
}
return b.group(paramsContents);
}
}
/* c8 ignore next */
return unexpectedDoc(opts, node);
},
[NodeType.TagTypeParams]: async (toDoc, _print, path, opts) => {
const { node } = path;
if (isEmpty(node.parent.params?.value, opts) || isEmpty(node.value, opts)) return "";
const doc = await toDoc(`function _<${read(node.value, opts).trim()}>(){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) return doc[1];
/* c8 ignore next */
return unexpectedDoc(opts, node);
}
return b.lineSuffix(code);
};
const printTag = ((path, opts, print, body = printBody(path, opts, print)) => {
function printTag(path, opts, print, body = printBody(path, opts, print)) {
return (isConcise(opts) ? printConciseTag : printHTMLTag)(path, opts, print, body);
});
const printHTMLTag = ((path, opts, print, body) => {
}
function printHTMLTag(path, opts, print, body) {
const { node } = path;

@@ -909,4 +1023,4 @@ const openTagDoc = ["<", printTagBeforeAttrs(path, opts, print)];

return b.group(openTagDoc);
});
const printConciseTag = ((path, opts, print, body) => {
}
function printConciseTag(path, opts, print, body) {
const { node } = path;

@@ -930,14 +1044,14 @@ const tagDoc = [printTagBeforeAttrs(path, opts, print)];

return b.group(tagDoc);
});
const printTagBeforeAttrs = (path, _opts, print) => {
}
function printTagBeforeAttrs(path, opts, print) {
const { node } = path;
const name = path.call(print, "name");
const doc = [name];
if (pathHas(path, "typeArgs")) doc.push(path.call(print, "typeArgs"));
if (pathHas(path, "typeArgs") && !isEmpty(path.node.typeArgs.value, opts)) doc.push(path.call(print, "typeArgs"));
if (pathHas(path, "shorthandId")) doc.push(path.call(print, "shorthandId"));
if (pathHas(path, "shorthandClassNames")) doc.push(path.map(print, "shorthandClassNames"));
if (pathHas(path, "args")) doc.push(path.call(print, "args"));
if (pathHas(path, "args") && !isEmpty(path.node.args.value, opts)) doc.push(path.call(print, "args"));
if (pathHas(path, "var")) doc.push(path.call(print, "var"));
if (pathHas(path, "params")) {
if (pathHas(path, "typeParams")) {
if (pathHas(path, "params") && !isEmpty(path.node.params.value, opts)) {
if (pathHas(path, "typeParams") && !isEmpty(path.node.typeParams.value, opts)) {
if (!(node.typeArgs || node.args || node.var)) doc.push(" ");

@@ -949,4 +1063,4 @@ doc.push(path.call(print, "typeParams"));

return doc.length === 1 ? name : doc;
};
const printBody = (path, opts, print) => {
}
function printBody(path, opts, print) {
const { node } = path;

@@ -963,3 +1077,2 @@ if (!node.body) return;

const childDoc = child.call(print);
if (!childDoc) return;
content ||= [];

@@ -1031,7 +1144,3 @@ if (isInline(child.node)) {

if (typeof childDoc === "string" && isVisibleSpace(childDoc)) {
if (endsWithLine(inline)) {
const last = inline.length - 1;
if (inline[last] === b.softline) inline[last] = b.line;
return;
}
if (endsWithLine(inline)) return;
childDoc = b.line;

@@ -1074,162 +1183,7 @@ }

}
};
const printText = (path, opts) => {
const text = read(path.node, opts).replace(/\\/g, "\\\\");
if (/^\$!?{/.test(text)) return "\\" + text;
return text;
};
const printExact = (path, opts) => read(path.node, opts);
const embedClass = (toDoc, _print, path, opts) => toDoc(read(path.node, opts), exprParse);
const embedImport = (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse);
const embedExport = (toDoc, _print, path, opts) => toDoc(read(path.node, opts), stmtParse);
const embedStyle = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
const parser = getParserFromExt(node.ext?.slice(node.ext.lastIndexOf(".")) || ".css");
if (parser) return b.group([
`style${node.ext || ""} {`,
b.indent([b.line, await toDoc(code, { parser })]),
b.line,
"}"
]);
};
const embedStatic = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = opts._markoParsed.code.slice(node.start + node.target.length + 1, node.end).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [`${node.target} `, withBlockIfNeeded(await toDoc(code, stmtParse))] : [];
};
const embedScriptlet = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
return code ? [
b.breakParent,
"$ ",
withBlockIfNeeded(await toDoc(code, stmtParse))
] : [];
};
const embedOpenTagName = async (toDoc, _print, path, opts) => embedTemplate(toDoc, _print, path, opts);
const embedPlaceholder = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts);
if (code === "\" \"" || code === "' '") return getVisibleSpace(opts);
return b.group([
node.escape ? "${" : "$!{",
b.indent([b.softline, await toDoc(code, exprParse)]),
b.softline,
"}"
]);
};
const embedTagArgs = (toDoc, _print, path, opts) => {
return argsToDoc(path.node, opts, toDoc);
};
const embedAttrNamed = async (toDoc, _print, path, opts) => {
const node = path.node;
const name = read(node.name, opts);
if (!(node.args || node.value)) return name;
const attrDoc = [name];
if (node.args) {
const argsDoc = await argsToDoc(node.args, opts, toDoc);
if (argsDoc) attrDoc.push(argsDoc);
else return unexpectedDoc(opts, node);
}
if (node.value) if (node.value.type === NodeType.AttrMethod) {
const attrMethodDoc = await toDoc(`function${read(node.value, opts)}`, exprParse);
if (Array.isArray(attrMethodDoc) && attrMethodDoc.length && typeof attrMethodDoc[0] === "string") {
attrMethodDoc[0] = attrMethodDoc[0].replace(/^function\s*/, "");
attrDoc.push(attrMethodDoc);
} else return unexpectedDoc(opts, node);
} else attrDoc.push(node.value.bound ? ":=" : "=", withParensIfNeeded(await toDoc(read(node.value.value, opts), exprParse), isConcise(opts)));
return b.group(attrDoc);
};
const embedAttrSpread = async (toDoc, _print, path, opts) => {
const node = path.node;
return b.group(["...", withParensIfNeeded(await toDoc(read(node.value, opts), exprParse), isConcise(opts))]);
};
const embedShorthandId = async (toDoc, print, path, opts) => ["#", await embedTemplate(toDoc, print, path, opts)];
const embedShorthandClassName = async (toDoc, print, path, opts) => [".", await embedTemplate(toDoc, print, path, opts)];
const embedTag = (path, opts) => {
const tag = path.node;
const parser = getTagParser(tag, opts);
if (parser === void 0) return null;
return async (toDoc, print, path, opts) => printTag(path, opts, print, {
inline: true,
preserve: parser === false,
content: await getFormattedBody(path, parser, toDoc, print, opts)
});
};
const embedTagVar = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
let doc = await toDoc(`var ${code}=_`, stmtParse);
if (Array.isArray(doc) && doc.length === 1) doc = doc[0];
if (typeof doc === "object" && !Array.isArray(doc) && doc.type === "group") doc = doc.contents;
if (Array.isArray(doc) && doc.length > 1) {
const varPart = doc[1];
if (typeof varPart === "object" && "type" in varPart && varPart.type === "group" && Array.isArray(varPart.contents)) {
const varContents = varPart.contents;
for (let i = varContents.length; i--;) {
const item = varContents[i];
if (typeof item === "string") {
const match = /\s*=\s*$/.exec(item);
if (match) {
varContents[i] = item.slice(0, -match[0].length);
varContents.length = i + 1;
return ["/", varContents];
}
}
}
}
}
return unexpectedDoc(opts, node);
}
return [];
};
const embedTagTypeArgs = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`_<${code}>`, exprParse);
if (typeof doc === "string") return doc.replace(/^_/, "");
if (Array.isArray(doc) && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
return unexpectedDoc(opts, node);
}
return [];
};
const embedTagParams = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`function _(${code}){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) {
const paramsGroup = doc[1];
if (paramsGroup && typeof paramsGroup === "object" && "type" in paramsGroup && paramsGroup.type === "group" && Array.isArray(paramsGroup.contents)) {
const paramsContents = [...paramsGroup.contents];
const first = paramsContents[0];
const last = paramsContents[paramsContents.length - 1];
if (typeof first === "string" && typeof last === "string") {
paramsContents[0] = first.replace(/^\(/, "|");
paramsContents[paramsContents.length - 1] = last.replace(/\)$/, "|");
}
return b.group(paramsContents);
}
}
return unexpectedDoc(opts, node);
}
return [];
};
const embedTagTypeParams = async (toDoc, _print, path, opts) => {
const node = path.node;
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`function _<${code}>(){}`, stmtParse);
if (Array.isArray(doc) && doc.length > 1) return doc[1];
return unexpectedDoc(opts, node);
}
return [];
};
const embedTemplate = async (toDoc, _print, path, opts) => {
}
function printExact(path, opts) {
return read(path.node, opts);
}
async function templateToDoc(toDoc, path, opts) {
const { expressions, quasis } = path.node;

@@ -1252,14 +1206,12 @@ const first = read(quasis[0], opts);

return shorthandDoc;
};
}
async function argsToDoc(node, opts, toDoc) {
const code = read(node.value, opts).trim();
if (code) {
const doc = await toDoc(`_(${code})`, exprParse);
if (Array.isArray(doc) && doc.length && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
return unexpectedDoc(opts, node);
if (isEmpty(node.value, opts)) return "";
const doc = await toDoc(`_(${read(node.value, opts).trim()})`, exprParse);
if (Array.isArray(doc) && doc.length && typeof doc[0] === "string") {
doc[0] = doc[0].replace(/^_/, "");
return doc;
}
return [];
/* c8 ignore next */
return unexpectedDoc(opts, node);
}

@@ -1361,5 +1313,12 @@ function wrapConciseText(doc) {

}
const nonWhitespaceReg = /\S/g;
function isEmpty(range, opts) {
if (!range || range.start === range.end) return true;
nonWhitespaceReg.lastIndex = range.start;
return !(nonWhitespaceReg.test(opts._markoParsed.code) && nonWhitespaceReg.lastIndex <= range.end);
}
function pathHas(path, key) {
return !!path.node[key];
}
/* c8 ignore start */
function unexpectedDoc(opts, node) {

@@ -1370,2 +1329,3 @@ const parsed = opts._markoParsed;

}
/* c8 ignore stop */
export { languages, options, parsers, printers };
{
"name": "prettier-plugin-marko",
"version": "4.0.5",
"version": "4.0.6",
"description": "A prettier plugin for parsing and printing Marko files",

@@ -5,0 +5,0 @@ "keywords": [