From 5a526601af575a313f48a618d076b47231e465aa Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Tue, 14 Mar 2023 11:50:29 -0700 Subject: [PATCH] fix: printing marko placeholders in embedded script/styles --- .../auto.marko | 6 + .../concise.marko | 7 + .../html.marko | 6 + .../with-parens.marko | 6 + .../auto.marko | 1 + .../concise.marko | 1 + .../html.marko | 1 + .../with-parens.marko | 1 + .../embedded-text-with-placeholders.marko | 8 + src/index.ts | 169 +++++++++++++----- 10 files changed, 158 insertions(+), 48 deletions(-) create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/auto.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/concise.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/html.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/with-parens.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders/auto.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders/concise.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders/html.marko create mode 100644 src/__tests__/__snapshots__/embedded-text-with-placeholders/with-parens.marko create mode 100644 src/__tests__/fixtures/embedded-text-with-placeholders.marko diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/auto.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/auto.marko new file mode 100644 index 0000000..5500ff0 --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/auto.marko @@ -0,0 +1,6 @@ + + + diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/concise.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/concise.marko new file mode 100644 index 0000000..909e17c --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/concise.marko @@ -0,0 +1,7 @@ +script -- window.bla = ${JSON.stringify(input.bla)}; + +script + -- + window.a = ${JSON.stringify(input.a)}; + window.b = ${JSON.stringify(input.b)}; + -- diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/html.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/html.marko new file mode 100644 index 0000000..5500ff0 --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/html.marko @@ -0,0 +1,6 @@ + + + diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/with-parens.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/with-parens.marko new file mode 100644 index 0000000..5500ff0 --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders.expected/with-parens.marko @@ -0,0 +1,6 @@ + + + diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders/auto.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders/auto.marko new file mode 100644 index 0000000..d58ab80 --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders/auto.marko @@ -0,0 +1 @@ + diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders/concise.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders/concise.marko new file mode 100644 index 0000000..964daeb --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders/concise.marko @@ -0,0 +1 @@ +script -- window.bla = ${JSON.stringify(input.bla)}; diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders/html.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders/html.marko new file mode 100644 index 0000000..d58ab80 --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders/html.marko @@ -0,0 +1 @@ + diff --git a/src/__tests__/__snapshots__/embedded-text-with-placeholders/with-parens.marko b/src/__tests__/__snapshots__/embedded-text-with-placeholders/with-parens.marko new file mode 100644 index 0000000..d58ab80 --- /dev/null +++ b/src/__tests__/__snapshots__/embedded-text-with-placeholders/with-parens.marko @@ -0,0 +1 @@ + diff --git a/src/__tests__/fixtures/embedded-text-with-placeholders.marko b/src/__tests__/fixtures/embedded-text-with-placeholders.marko new file mode 100644 index 0000000..351b169 --- /dev/null +++ b/src/__tests__/fixtures/embedded-text-with-placeholders.marko @@ -0,0 +1,8 @@ + + + diff --git a/src/index.ts b/src/index.ts index 769ac9f..0b60007 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,8 +33,9 @@ import { } from "./utils/get-original-code"; const defaultFilePath = resolve("index.marko"); -const { builders: b } = doc; +const { builders: b, utils } = doc; const identity = (val: T) => val; +const embeddedPlaceholderReg = /__EMBEDDED_PLACEHOLDER_(\d+)__/g; export const languages: SupportLanguage[] = [ { @@ -395,59 +396,93 @@ export const printers: Record> = { } else if (node.body.body.length) { const lastIndex = node.body.body.length - 1; const bodyDocs = [] as Doc[]; - let textDocs = [] as Doc[]; let textOnly = true; - tagPath.each( - (child, i) => { - const childNode = child.getValue(); - const isText = isTextLike(childNode, node); - - if (isText) { - textDocs.push( - embedMode && childNode.type === "MarkoText" - ? callEmbed(print, child, embedMode, childNode.value) - : print(child) - ); - if (i !== lastIndex) return; - } else { - textOnly = false; - } + if (embedMode) { + let placeholderId = 0; + const placeholders = [] as Doc[]; + let embeddedCode = ""; + + tagPath.each( + (child) => { + const node = child.getValue(); + if (node.type === "MarkoText") { + embeddedCode += node.value; + } else { + embeddedCode += `__EMBEDDED_PLACEHOLDER_${placeholderId++}__`; + placeholders.push(print(child)); + } + }, + "body", + "body" + ); + + const embeddedDoc = replaceEmbeddedPlaceholders( + callEmbed(print, tagPath, embedMode, embeddedCode), + placeholders + ); + + bodyDocs.push( + b.group([ + opts.markoSyntax === "html" + ? "" + : b.ifBreak("--", " --", { groupId }), + opts.markoSyntax === "html" ? "" : b.line, + embeddedDoc, + opts.markoSyntax === "html" + ? "" + : b.ifBreak([b.softline, "--"]), + ]) + ); + } else { + let textDocs = [] as Doc[]; + tagPath.each( + (child, i) => { + const childNode = child.getValue(); + const isText = isTextLike(childNode, node); + + if (isText) { + textDocs.push(print(child)); + if (i !== lastIndex) return; + } else { + textOnly = false; + } - if (textDocs.length) { - const isFirst = !bodyDocs.length; - bodyDocs.push( - b.group([ - opts.markoSyntax === "html" - ? "" - : isFirst - ? b.ifBreak("--", " --", { groupId }) - : "--", - opts.markoSyntax === "html" - ? preserveSpace || isFirst + if (textDocs.length) { + const isFirst = !bodyDocs.length; + bodyDocs.push( + b.group([ + opts.markoSyntax === "html" + ? "" + : isFirst + ? b.ifBreak("--", " --", { groupId }) + : "--", + opts.markoSyntax === "html" + ? preserveSpace || isFirst + ? "" + : b.softline + : preserveSpace + ? b.hardline + : b.line, + preserveSpace ? textDocs : b.fill(textDocs), + opts.markoSyntax === "html" ? "" - : b.softline - : preserveSpace - ? b.hardline - : b.line, - preserveSpace ? textDocs : b.fill(textDocs), - opts.markoSyntax === "html" - ? "" - : b.ifBreak([b.softline, "--"]), - ]) - ); - - if (!isText) { - textDocs = []; + : b.ifBreak([b.softline, "--"]), + ]) + ); + + if (!isText) { + textDocs = []; + bodyDocs.push(print(child)); + } + } else { bodyDocs.push(print(child)); } - } else { - bodyDocs.push(print(child)); - } - }, - "body", - "body" - ); + }, + "body", + "body" + ); + } const sep = (preserveSpace || !textOnly) && @@ -708,3 +743,41 @@ export const printers: Record> = { }, }, }; + +function replaceEmbeddedPlaceholders(doc: Doc, placeholders: Doc[]) { + if (!placeholders.length) return doc; + + return utils.mapDoc(doc, (cur) => { + if (typeof cur === "string") { + let match = embeddedPlaceholderReg.exec(cur); + + if (match) { + const replacementDocs = [] as Doc[]; + let index = 0; + + do { + const placeholderIndex = +match[1]; + + if (index !== match.index) { + replacementDocs.push(cur.slice(index, match.index)); + } + + replacementDocs.push(placeholders[placeholderIndex]); + index = match.index + match[0].length; + } while ((match = embeddedPlaceholderReg.exec(cur))); + + if (index !== cur.length) { + replacementDocs.push(cur.slice(index)); + } + + if (replacementDocs.length === 1) { + return replacementDocs[0]; + } + + return replacementDocs; + } + } + + return cur; + }); +}