#637·markdoc

Heading escape regex matches # anywhere in text, not just at line start

Author: joelzwarringtonCreated Sep 8, 2026Updated Sep 18, 2026
Labelsbug

What happened?

Since #583, # within block content is incorrectly getting escaped when formatting, e.g. C# is a languageC\# is a language.

To reproduce

  1. Format a text node whose content contains a # followed by whitespace anywhere other than the start of a line:
    javascript
    const { format, Ast } = require('@markdoc/markdoc');
    const node = new Ast.Node('text', { content: 'Text # not a heading' });
    console.log(format(node));
  2. Observe the output is Text \# not a heading — the # is escaped even though it can't start a heading there.
  3. Same happens with C# is a languageC\# is a language.

As a broken test case: the escape markdown content fixture in src/formatter.test.ts (~line 148, next to the existing Text > not a blockquote line) should include a new line:

Text # not a heading

This fails against the current regex and passes once #+\s is anchored with ^.

Version

No response

Additional context

Fix is a one-character change in src/formatter.ts:227:

diff
- yield* escapeMarkdownCharacters(content, /^\*|#+\s|^>/);
+ yield* escapeMarkdownCharacters(content, /^\*|^#+\s|^>/);