Skip to main content
Turndown automatically escapes Markdown special characters in HTML content to ensure they are rendered as literal text rather than being interpreted as Markdown syntax.

Why Escaping Is Needed

Markdown uses special characters to define formatting. When converting HTML to Markdown, these characters in the original content need to be escaped to preserve their literal meaning. For example, without escaping:
Would convert to:
When rendered, this would be interpreted as a numbered list item instead of a heading. With proper escaping:
The period is escaped, ensuring it renders as a heading.

Escaped Characters

Turndown escapes the following Markdown special characters:
Backslash
Escaped to: \\Backslashes themselves need escaping since they’re the escape character.
Asterisk
Escaped to: \*Prevents interpretation as emphasis, strong text, or list markers.
Hyphen (at line start)
Escaped to: \-Prevents interpretation as list markers or setext heading underlines.Only escaped when it appears at the start of a line.
Plus (at line start with space)
Escaped to: \+Prevents interpretation as a list marker.Pattern: ^+ (plus at start of line followed by space)
Equals signs (at line start)
Escaped to: \=Prevents interpretation as setext heading underlines.Pattern: ^(=+) (one or more equals signs at line start)
Hash (at line start with space)
Escaped to: \#Prevents interpretation as ATX heading markers.Pattern: ^(#{1,6}) (1-6 hashes at start of line followed by space)
Backtick
Escaped to: \`Prevents interpretation as inline code or code block delimiters.
Tildes (at line start)
Escaped to: \~~~Prevents interpretation as fenced code block delimiters.Pattern: ^~~~ (three tildes at start of line)
Left bracket
Escaped to: \[Prevents interpretation as link or image syntax.
Right bracket
Escaped to: \]Prevents interpretation as link or image syntax.
Greater than (at line start)
Escaped to: \>Prevents interpretation as blockquote markers.Only escaped when it appears at the start of a line.
Underscore
Escaped to: \_Prevents interpretation as emphasis markers.
Numbered list (at line start)
Escaped to: 1\.Prevents interpretation as ordered list items.Pattern: ^(\d+). (digits followed by period and space at line start)

Escape Patterns

The escape patterns are defined in the source code at src/turndown.js:7-21:
These patterns are applied using JavaScript’s String.prototype.replace() method.

How Escaping Works

Turndown escapes text in two stages:

1. During Node Processing

When processing DOM nodes, text nodes are escaped unless they’re inside code elements (src/turndown.js:164):
Text inside <code> and <pre> elements is never escaped because code should be displayed literally.

2. The Escape Method

The escape() method applies all escape patterns sequentially (src/turndown.js:142-146):
Each pattern is applied to the accumulating result, ensuring all special characters are properly escaped.

Examples

Escaping List Markers

Escaping Heading Markers

Escaping Emphasis

Code Is Not Escaped

Customizing Escape Behavior

You can customize the escape behavior by overriding the escape method on the TurndownService prototype.
Only customize escaping if you fully understand the implications. Incorrect escaping can break Markdown rendering.

Custom Escape Method

Less Aggressive Escaping

The default escaping can be aggressive. If you’re confident your content won’t create ambiguous Markdown:

Context-Aware Escaping

For more sophisticated escaping based on context:

Escaping Performance

Turndown’s escaping approach is optimized for correctness rather than performance:
  1. Regular expression based - Uses regex patterns for pattern matching
  2. Sequential application - Applies each escape pattern in order
  3. Applied to all text nodes - Escapes every text node except code
From the README (line 222-223):
To avoid the complexity and the performance implications of parsing the content of every HTML element as Markdown, Turndown uses a group of regular expressions to escape potential Markdown syntax.
As a result:
The escaping rules can be quite aggressive. Some text may be escaped even when it wouldn’t actually be interpreted as Markdown in practice.
This trade-off ensures correctness at the cost of occasionally over-escaping content.