Markdown basics

How to Escape Special Characters in Markdown

To escape a special character in Markdown, put a backslash in front of it. \* shows a plain asterisk instead of starting italics, \# at the start of a line shows a hash instead of making a heading, and \| keeps a pipe inside a table cell. That works for every ASCII punctuation mark, and only for those: a backslash before a letter or a digit is shown as typed.

QuickMark on iPad in split view. Left: pairs of Markdown lines, one plain and one with backslashes, such as 1986. A great year and 1986\. A great year. Right: the plain lines render as a numbered list, italics, a math formula, subscript and a keyboard key, while the escaped lines show the characters exactly as typed
Each pair is the same line with and without backslashes. Captured in QuickMark on an iPad (A16) simulator while writing this post.

The rule fits in one sentence. The hard part is knowing when a character needs it, and the few places where one backslash isn't enough. So I ran 129 small cases through QuickMark's own renderer (markdown-it, the same code the app, Quick Look and published pages use) and sent the tricky ones through GitHub's Markdown API as well. Everything below is what came out, not what the spec suggests should.

The basic move

You write
*sold out*

\*sold out\*

\# Not a heading

C:\Users\mai
You get

sold out

*sold out*

# Not a heading

C:\Users\mai

The last line is the reassuring one. \U and \m aren't escapes (U and m are letters), so the backslashes stay. You don't have to double every backslash in a Windows path. You only need \\ when the backslash sits right before punctuation and you want both to show.

Which characters can be escaped

The CommonMark spec allows a backslash before any ASCII punctuation character. In practice these are the ones that do something in Markdown, and so the ones you'll actually escape:

CharacterWhy it gets eatenEscape
* _Italic and bold\* \_
#Heading, at the start of a line\#
- +Bullet, at the start of a line\- \+
. after a numberNumbered list1986\.
>Blockquote, at the start of a line\>
[ ] !Links and images\[ \] \!
`Inline code\`
|Table cell border\|
<HTML tag\<
&HTML entity like &copy;\&
$Math, in apps that render it\$
\The escape character itself\\

Escaping something harmless is fine. \., \!, \%, \@ and \{\} all rendered as the bare character with the backslash removed, so when in doubt, escaping costs nothing.

Most characters only matter in one position

You rarely need an escape in the middle of a sentence. 2 * 3 * 4 rendered as plain arithmetic, snake_case_word kept its underscores, #hashtag and #1 fan stayed text (a heading needs a space after the hash), and a < b came out fine. Markdown is pickier about the start of a line, and that's where most surprises come from:

Line starts withWhat rendersFix
1986. A great yearA numbered list that starts at 19861986\. A great year
# not a headingAn H1\# not a heading
* note or - noteA bullet\* note
> replyA blockquote\> reply
*** or ---A horizontal rule\*\*\*
Text, then --- on the next lineThe text becomes an H2Escape every dash (see below)
Four spaces of indentA code blockRemove the indent

The year one catches people writing timelines and changelogs. Nothing looks wrong in the editor. In the preview, "1986." is gone and the line has a list number in front of it.

When one backslash isn't enough

A backslash protects exactly one character. If the syntax is made of a run of characters, escaping only the first can leave a shorter run behind that still means something:

You writeWhat rendersWhat works
\~~gone~~A stray tilde, then "gone~" as subscript\~\~gone\~\~
\---A hyphen followed by an en dash\-\-\-
a..\.An ellipsis character plus a perioda\.\.\.

The tilde case is QuickMark specific: the app also supports ~subscript~, so a single leftover tilde pair is still syntax. On GitHub, which has no subscript, \~~gone~~ simply shows the tildes. The safe habit is the same everywhere: escape every character of the run.

Pipes inside a table

A pipe is a cell border, even inside backticks. This surprised me more than anything else in the test run, so I checked GitHub too. Both split the cell:

You write
| Code | Cells |
|---|---|
| `a | b` | one |

| Code | Cells |
|---|---|
| `a \| b` | one |
You get
CodeCells
`ab`
CodeCells
a | bone

In the first table the row lost its last cell, and the backticks show up as literal characters. With \| the code span stays whole and the backslash disappears, even though backslashes are normally kept inside code. Outside backticks, &#124; works too. More table rules are in How to Make a Table in Markdown.

HTML tags you meant as text

Writing about HTML in Markdown is a classic trap. Use the <kbd> tag doesn't show the word "<kbd>": the renderer treats it as a real tag, the word disappears, and everything after it is drawn as a keyboard key (you can see "tag" in a key box in the iPad screenshot above). GitHub swallows it the same way. Three ways out:

  • Use the \<kbd> tag
  • Use the &lt;kbd&gt; tag
  • Backticks, which is what you usually want anyway: Use the `<kbd>` tag

One QuickMark detail: tags that could run code (<script>, <iframe>, event handlers) are never executed. The app shows them as plain text, so a pasted snippet can't do anything to you. Safe tags like <b>, <kbd> and <details> do render.

Dollar signs

Apps that render math (QuickMark, GitHub, Obsidian) use $…$ for formulas, which makes prices a worry. The measured behavior is friendlier than you'd expect: price $5 or $6.50 today stayed plain text, because a dollar sign followed by a digit can't close a formula. It goes wrong when a later dollar sign does close a pair:

  • from $5 to $10$ rendered "10" as a formula.
  • between $a$ and $b rendered "a" as a formula.

\$ fixes both. If a note mixes money and math, escape the money. The full math rules are in How to Write Math Equations in Markdown.

Smart punctuation, and how to keep it straight

This part varies by app. QuickMark's renderer has smart punctuation turned on, so straight quotes become curly quotes, -- becomes an en dash, --- an em dash, ... a single ellipsis character, and (c), (tm) and (r) become the ©, ™ and ® symbols. GitHub's API left all of these exactly as typed when I sent the same text.

Usually that's what you want in prose. When it isn't (a command-line flag like --force, a quote that must stay straight), escape it: \-\-, \", it\'s and \(c) all came out exactly as typed. Inside backticks nothing is converted, so `--force` is the cleaner fix for flags.

The extras: highlight, subscript, emoji, wiki links

QuickMark supports a few things beyond basic Markdown, and each has an escape that only needs a backslash before the first character:

SyntaxRenders asKeep it as text
==text==Highlight\==text==
H~2~OSubscriptH\~2~O
x^2^Superscriptx\^2^
:smile:An emoji\:smile:
[[Page]]A wiki link\[[Page]]
[^1]A footnote marker\[^1]
> [!NOTE]A callout> \[!NOTE]
- [ ] taskA checkbox- \[ ] task
QuickMark on iPhone showing a note where every line starts with an escaped character: # Not a heading, - Not a bullet, > Not a quote, **Not bold**, [Not a link], a Windows path, prices with dollar signs, ==text== and H~2~O, (c) and -- left as typed, and :smile: as a word
Every line here would be formatting without its backslash. iPhone 17 Pro simulator.

Two more things a backslash does

A backslash at the end of a line is a line break. word\ followed by a new line rendered a <br>, the same as ending the line with two spaces, and much easier to see. A backslash at the very end of a paragraph has nothing to break, so it just shows.

A backslash inside code does nothing. In `\*` or a fenced block, the backslash shows up as typed, because code is never parsed for Markdown. That's why the cleanest "escape" for anything technical is often backticks. The one exception is the table pipe above. More on code spans and fences in How to Write Code Blocks.

One link inside escaped brackets still works

\[not a link\](http://x.com) does stop the link syntax: the brackets show as text. But the URL in the parentheses is still a full web address, and QuickMark turns bare http:// and https:// addresses into links, so it becomes clickable on its own. If you want the whole thing inert, put it in backticks.

Quick reference

  • Backslash before the punctuation: \*, \#, \|, \$.
  • Runs of syntax: escape every character, \~\~, \-\-\-.
  • Start of line is where escapes matter most: headings, bullets, quotes, and numbers like 1986.
  • Tags as text: \<tag> or backticks.
  • Backslash before a letter stays visible, so paths need no extra work.
  • Anything technical: backticks beat backslashes.

The Markdown cheat sheet has every syntax these escapes protect, and What Is GitHub Flavored Markdown covers the parts that differ between apps.

QuickMark app icon

Get rendered Markdown previews everywhere

QuickMark is a free, native Markdown app for Mac, iPhone and iPad. Live preview, export and publish built in.