The callout preprocessor ran AFTER the fenced-code extraction pass, so
a code block nested inside a callout blockquote (each line prefixed
with `> `) was captured whole \u2014 including the leading `> ` on the
closing fence. When the placeholder was later restored inside the raw
`<div class="callout-body">`, the closing line `> \`\`\`` no longer sat
at 0-3 leading spaces, so CommonMark did not recognize it as a fence
closer. marked.js ran the block unclosed, swallowed the callout's
`</div></div>` and every downstream node, and the render leaked as raw
blockquote text.
Reorder the pipeline so callouts are converted BEFORE code-block
extraction. The scan is fence-aware (backticks and tildes) so a
literal `> [!TYPE]\' inside a top-level code block is not misread as a
callout. Mirrored in backend/export.py so the standalone export matches
the in-app preview.
Verified end-to-end against a 12-case matrix covering GFM (github.com)
and GLFM (gitlab.com) alert syntax: nested backtick fence (bug),
nested tilde fence, all 5 types in UPPERCASE, GitLab lowercase with
custom title, empty callout, plain blockquote passthrough, literal
`[!TIP]` inside top-level backtick and tilde fences (regression),
rich body markdown, paragraph separators, adjacent callouts, and
nested-alert attempts (GFM disallows nesting).
Signed-off-by: pablon <73798198+pablon@users.noreply.github.com>
The MCP client posted template/path, but /api/templates/create-note reads
templateName/notePath, so every call failed with
"HTTP 400: Template name and note path required" before the template was
ever loaded. Send the keys the endpoint expects.