Skip to content

fix: don't double backslash escapes in non-CSS embedded templates#801

Open
bartlomieju wants to merge 1 commit into
dprint:mainfrom
bartlomieju:fix/embedded-template-escape-doubling
Open

fix: don't double backslash escapes in non-CSS embedded templates#801
bartlomieju wants to merge 1 commit into
dprint:mainfrom
bartlomieju:fix/embedded-template-escape-doubling

Conversation

@bartlomieju

Copy link
Copy Markdown
Collaborator

Problem

When formatting embedded code in tagged templates, lone escape sequences get
their backslash doubled, which changes the meaning of the user's code:

html`\n`;                          // \n  ->  \\n
const s = html`<script>const d = fetch(\`\`);</script>`;  // \`  ->  \\`

Root cause

maybe_gen_tagged_tpl_with_external_formatter unescapes \\ -> \ before
calling the external formatter and then re-escapes every \ -> \\
afterwards. The blanket post-doubling also doubles lone escapes (\n, \`)
that were never part of a \\ pair.

The \\ -> \ collapse is genuinely needed for CSS: the CSS parser cannot
parse the double-backslash form of escapes (e.g. Tailwind
.bg-\\[\\#86efac\\] errors; it needs .bg-\[\#86efac\]). But it must not be
applied to other embedded languages.

Fix

Gate the \\ <-> \ round-trip to embedded_lang == "css". Other languages
(html / xml / svg / sql) pass the raw text through verbatim, preserving their
escapes. The existing CSS \\ (Tailwind) behavior is unchanged.

Test

Added a regression spec to tests/specs/external_formatter/html.txt asserting
html`\n` stays \n. Verified it fails before the fix and passes after; the
existing CSS \\ spec still passes.


This PR was authored and opened with AI assistance (Claude Code). The fix was
manually verified end-to-end against Deno's formatter (which embeds this plugin):
it resolves denoland/deno#30103 and denoland/deno#30948, with Deno's full fmt
spec suite passing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fmt: literal "\n" (backslash n) within html tagged template incorrectly formatted as "\\n"

1 participant