FormatArc's Markdown to HTML converter showing the difference between escaped and unescaped symbolsFormatArc's Markdown to HTML converter showing the difference between escaped and unescaped symbols
Published: 2026-07-15

Markdown Escape Characters: Complete List + 22 Tested Examples

A line that starts with * turns into a bullet. # price list becomes a page heading. The <version> placeholder you typed has vanished from the preview. All of these happen because Markdown read your symbol as a formatting instruction — and none of them produce an error message. This guide covers how to escape characters so they display as typed, backed by 22 test cases run against 4 renderers.

The short answer — put one backslash before the symbol

Type a backslash \ directly before the character you want to display. That's it.

\*this will not be italic\*

The backslash itself disappears from the output. The example above renders as the plain string *this will not be italic*, asterisks included.

To display a literal backslash, double it: \\.

Quick reference — from symptom to fix

Work backwards from what went wrong. Every symptom below comes from the measured cases later in this article.

What happenedCauseFix
Text turned italic or boldWords wrapped in * or _Escape as \* \_
A whole line became a headingLine starts with # plus a spaceWrite \#
A numbered list appearedLine starts with a number and a periodEscape the period: 1986\.
A bullet list appearedLine starts with - or *Write \- \*
Text disappeared from the pageA word wrapped in < and >Write \< and \>
A table cell split, or lost its second halfA pipe inside the cellBackslash before the pipe (details below)

Which characters can be escaped

The CommonMark spec on backslash escapesOpens in a new tab states that "Any ASCII punctuation character may be backslash-escaped". That covers these 32 characters:

! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~

Two flip sides of this rule cause most of the confusion:

  • Only ASCII punctuation qualifies. Before anything else, the backslash is just a character: the spec says "Backslashes before other characters are treated as literal backslashes". So \n does not become a line break — it renders as a backslash followed by an n
  • Escaping is about position, not just the character. # only makes a heading at the start of a line with a space after it; a # in the middle of a sentence is already safe

The next section pins down those boundaries with measurements.

Tested — what breaks without escaping, and whether the backslash works

Plenty of guides list escapable characters. Very few show what actually happens when you don't escape, or verify that the backslash works across implementations. So we ran 22 cases through 4 renderers: GitHub's production renderer (via the Markdown API), marked 18.0.5, remark-gfm 4.0.1, and strict CommonMark (remark-parse with no extensions). Measured on 2026-07-15; the reproduction script and raw data live in this site's repository under scripts/benchmarks/markdown-escape-characters/.

Here are the headline cases.

Input (measured string)Without escapingWith escaping
Buy the *limited edition* today.Renders italic (4/4 renderers)\*limited edition\* displays as typed (4/4)
# price list at line startBecomes an h1 heading (4/4)\# price list displays as typed (4/4)
1986. What a year. at line startBecomes an ordered list starting at 1986 (4/4)1986\. What a year. displays as typed (4/4)
Replace <version> with 2.0<version> vanishes from the page (4/4)\<version\> stays visible (4/4)
grep a | b inside a table cellThe pipe splits the cell and the overflow is dropped (all 3 GFM renderers)A backslash keeps it in one cell (all 3 GFM renderers)

The number-plus-period case is the easiest to miss. Whether it's 1. or 1986., a number followed by a period at the start of a line becomes an ordered list and the rest of the sentence gets indented. If you open a sentence with a year or a model number, escape the period.

To see how your Markdown is interpreted, paste it into Markdown to HTML — the conversion runs entirely in your browser and nothing you paste is uploaded anywhere.

FormatArc's Markdown to HTML converter showing the difference between escaped and unescaped symbolsFormatArc's Markdown to HTML converter showing the difference between escaped and unescaped symbols

All four implementations here are CommonMark-based, and their escape behavior matched cleanly. Where dialects do diverge is a separate topic — see CommonMark vs GFM for those measurements.

Cases where you don't need to escape

Over-escaping makes your source harder to read and adds noise to diffs. Three common patterns tested as safe without any escaping:

  • Intraword underscores. max_retry_count_limit rendered as typed in all 4 renderers — an _ inside a word is not treated as emphasis
  • #hashtag with no space. A # only creates a heading when a space follows it; #hashtag stayed plain text in all 4 renderers
  • Brackets with no URL attached. [TODO] fix later rendered as typed in all 4 renderers. One caveat: if your document contains a reference definition like [TODO]: https://... somewhere, the brackets become a link — escape as \[TODO\] only in that case

The asymmetry to remember: asterisks do not behave like underscores. foo*bar*baz turned italic in all 4 renderers, even though the asterisks sit inside a word. Don't extend your snake_case instincts to *.

Where backslash escapes don't work

The CommonMark spec is explicit: "Backslash escapes do not work in code blocks, code spans, autolinks, or raw HTML". Our tests confirm it — a \* written inside a code span or a fenced code block displayed the backslash itself, in all 4 renderers.

Two practical consequences:

  • Inside code blocks, escape nothing. * and # display exactly as typed
  • Trying to escape inside code backfires. Write `\*` and your readers see \*, not *

One more trap sits at the end of the line. Per the spec, "A backslash at the end of the line is a hard line break" — and all 4 renderers converted a trailing \ into <br>. If you meant to escape a symbol at the end of a line and left the backslash last, you get an extra line break instead of a symbol.

The disappearing characters — watch out for < and >

Most symbols fail towards unwanted formatting. < and > fail towards invisible text, which is worse. If you write placeholders like <version>, this one is for you.

In our tests, the <version> in Replace <version> with 2.0 disappeared from the rendered page in all 4 renderers. The mechanism differs: GitHub's sanitizer strips the unknown tag, while marked and remark pass it through as raw HTML that the browser then swallows. Either way, your readers see nothing.

Two fixes:

Replace \<version\> with 2.0
Replace `<version>` with 2.0

\<version\> stayed visible in all 4 renderers. If the placeholder is part of a command or code, a code span communicates that intent better.

The one contextual exception — pipes inside table cells

Everything above applies anywhere in a document. Pipes inside table cells are the one place with extra rules. Tables are not core CommonMark — they're a GFM extensionOpens in a new tab — and a raw pipe inside a cell starts a new column. Worse, the GFM spec says that cells beyond the header column count are ignored ("the excess is ignored"): in our tests, a cell containing grep a | b was split at the pipe and the trailing b was silently dropped (all 3 GFM renderers). This is the only escape failure that loses data instead of just changing formatting.

Escape pipes with a backslash, or use the HTML character reference &#124;. Both kept the pipe inside a single cell in all 3 GFM renderers.

| command |
| --- |
| grep a \| b |
| grep a &#124; b |

If your table comes from CSV or spreadsheet data, CSV to Markdown escapes in-cell pipes automatically when it generates the table — no manual cell-by-cell checking, and the conversion never leaves your browser.

Prefer a code span when the symbol is code

Wrapping text in backticks also displays symbols literally, but the two techniques serve different purposes:

  • Use a backslash when the symbol belongs to the prose. Prices may change \*without notice\* keeps the sentence looking like a sentence, symbols included
  • Use a code span when the text is a command, a path, or a regex. C:\Users\name and \d+ read better in monospace, and the styling tells readers it's code

Since escape processing is disabled inside code spans, a regex like \d+ can be written as-is. For how escaping is handled when converting existing HTML or rich text into Markdown, see the HTML to Markdown guide.

Frequently asked questions

Which characters can be escaped in Markdown?

All 32 ASCII punctuation characters (CommonMark specOpens in a new tab). A backslash before a letter, digit, or non-ASCII character is not an escape — it renders as a literal backslash.

I typed \n but there's no line break

\n is a programming-language notation, not a Markdown escape. A backslash before a letter renders literally (confirmed in all 4 renderers). To break a line in Markdown, leave a blank line for a new paragraph, or end the line with a backslash for a hard break.

Do underscores in snake_case need escaping?

No. Intraword _ was not treated as emphasis in any of the 4 renderers. Asterisks are the exception: foo*bar*baz turns italic even inside a word.

How do I escape a pipe inside a table cell?

Put a backslash before the pipe, or use the character reference &#124;. Both worked in all 3 GFM renderers we tested. If you generate tables from CSV, CSV to Markdown escapes them for you.

How do I show a backslash or asterisk inside a code block?

Do nothing. Escape processing doesn't apply inside code blocks and code spans, so * and \ display exactly as typed. Writing \* there would show the backslash too.

Summary

  • The core rule: one backslash directly before the symbol. It covers the 32 ASCII punctuation characters and nothing else
  • snake_case, #hashtag, and unlinked brackets need no escaping — over-escaping just clutters your source
  • Escapes don't work inside code blocks or code spans, and a backslash at the end of a line becomes a hard line break
  • < > fail by making text invisible, and in-cell pipes fail by dropping data — fix those two first

To check how your Markdown renders, paste it into Markdown to HTML — free, no signup, and nothing you paste leaves your browser.