Files
paseo/packages/app/src/utils/markdown-parser.ts
T
Christoph LeiterandClaude Opus 5 3d69b0f458 fix(app): render markdown verbatim instead of substituting characters (#3253)
markdown-it's typographer option rewrites characters after parsing, so
a literal (c) came out as ©. Agents label steps and options (a), (b),
(c) all the time, and an ordinary list rendering as (a), (b), © stops
your eye every time.

The same option turns ... into an ellipsis, --- into an em dash, and
straight quotes into curly ones. Agent output is text people paste
back into a shell or a file, so a curly quote in --name="my repo"
looks correct on screen and fails when pasted. The markdown file
preview had the same problem, showing characters that are not in the
file on disk.

Every in-app markdown surface now goes through one factory in
utils/markdown-parser.ts, which leaves typographer off: agent chat,
plan cards, pull request comment bodies and the file preview. The plan
card was rendering through its library's built-in parser because it
never passed a markdownit prop, and that default has typographer on.

Link behaviour is unchanged. The assistant parser keeps its file://
permission and no other surface gains it, and linkify stays on for
chat and the default renderer and off for plan cards, matching what
each did before.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 08:58:27 +00:00

20 lines
879 B
TypeScript

import MarkdownIt from "markdown-it";
/**
* The one place that decides how the app parses markdown.
*
* `typographer` stays off. It switches on two markdown-it core rules that
* rewrite characters the user may copy back into a shell or a file:
* `replacements` turns `(c)` into ©, `a -- b` into an en dash and `...` into
* an ellipsis, and `smartquotes` curls straight quotes so `--name="x"` stops
* being pasteable. Agent output, plans and file previews all have to render
* the text they were handed.
*
* `linkify` is a parameter rather than a shared default because the surfaces
* disagree today: chat and the default renderer linkify bare URLs, plan cards
* never have. Unifying that is a product decision on its own.
*/
export function createMarkdownParser({ linkify }: { linkify: boolean }): MarkdownIt {
return new MarkdownIt({ html: false, linkify });
}