Markdown Cheatsheet

HTML and Escaping

Use this Markdown reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Raw HTML in Markdown

Original Markdown allows raw HTML to pass through untouched, and CommonMark keeps that. Whether it reaches the reader depends on the renderer's sanitizer, not on Markdown.

<div align="center">
  <img src="./logo.png" width="200" alt="logo">
</div>

Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy.

Water is H<sub>2</sub>O and this is x<sup>2</sup>.

Two kinds of HTML, with different rules:

  • Inline HTML such as <br>, <kbd>, <sub>, <img> sits inside a paragraph and Markdown around it still works.
  • Block HTML starts at the beginning of a line. In CommonMark, Markdown inside a block-level HTML element is not processed unless a blank line separates it from the tags.
<div>
**this bold is NOT processed**
</div>

<div>

**this bold IS processed, because of the blank lines**

</div>

That blank-line rule is the reason a collapsible details block needs an empty line after the summary tag.

What Gets Stripped

GFM's "disallowed raw HTML" extension filters a fixed tag list, and hosts add stricter allowlists on top. Never assume a tag survives.

CategoryTypical outcome
script, style, iframe, object, embedRemoved entirely
form, input, button, select, textareaRemoved
link, meta, title, base, noscriptRemoved
on* event attributesStripped from every tag
style and class attributesStripped by most hosts
details, summary, kbd, sub, sup, pictureKept on GitHub
div, span, p, img, br, hr, a, tableKept, attributes filtered

Practical consequences: no CSS, no JavaScript, no embedded video, and align plus width are the only layout controls you get. Anything beyond that needs a real site rather than a Markdown file.

A renderer that disallows raw HTML entirely (many CommonMark configurations, and this site's renderer) shows the tags as literal text or drops them, so a doc that leans on HTML degrades badly. Reach for HTML only when Markdown genuinely cannot express the thing.

Backslash Escaping

A backslash before an ASCII punctuation character makes it literal. Before anything else, the backslash is just a backslash.

\*not italic\*
\_not italic\_
\# not a heading
\- not a list item
1984\. not an ordered list
\[not a link\]
\!\[not an image\]
\> not a blockquote
\| not a table cell divider
\\ a literal backslash

The full escapable set is the ASCII punctuation characters, all of them:

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

Escaping a character that has no special meaning is harmless, so \! is fine even though ! alone is not special. Escaping a letter is not: \n is a literal backslash followed by n.

Where Escapes Do Not Work

Backslash escapes are processed only in normal text. They are inert inside:

  • Code spans, so a backslash there is a literal backslash.
  • Fenced and indented code blocks.
  • Autolinks in angle brackets.
  • Raw HTML tags.
`\*this shows a literal backslash and asterisk\*`

This is why a code span is usually a better tool than escaping. To show **kwargs in prose, backticks are shorter and less error-prone than \*\*kwargs.

HTML Entities

Named and numeric character references work anywhere Markdown text is processed, and are the fallback when a backslash escape is not enough or when a character would break a table.

EntityCharacterUse
&amp;An ampersandRarely needed, a bare one usually works
&lt; &gt;Angle bracketsTo show a tag as text
&quot; &apos;QuotesRarely needed
&#124;A vertical barA pipe inside a table cell
&nbsp;Non-breaking spaceForced spacing, prevents a wrap
&#8212;An em dashWhen the literal glyph is awkward to type
&hellip;An ellipsisTypography
&#x2713;A check markHex numeric form
Show a tag as text: &lt;script&gt;

A pipe in a table cell: `ls &#124; wc -l`

Two&nbsp;words that will not wrap apart.

Entities do not work inside code spans or fenced blocks. Inside a fence, &lt; renders as the four characters &lt;, which is correct behavior and occasionally surprising.

Comments

Markdown has no comment syntax. The universal workaround is an HTML comment, which every renderer removes from the output.

<!-- This note is invisible in the rendered output. -->

<!--
A multi-line comment.
Useful for a TODO or for hiding a draft section.
-->

A second trick uses a link reference definition, which is not rendered and needs no HTML.

[//]: # (This is also invisible.)

[comment]: <> (Another form of the same trick.)

Both are only invisible in the rendered output. Anyone reading the raw file, including anyone browsing the repository, sees them, so never hide anything sensitive this way.

Escaping Checklist

The situations that actually come up:

  • A number starting a line. Escape the period: 1984\.
  • A dash or hash starting a line. Escape it, or reword.
  • An identifier with underscores. Use a code span, not escapes.
  • Bold or italic markers in prose. Use a code span.
  • A pipe in a table. Escape it as \|, or use &#124;.
  • A URL you do not want autolinked. Use a code span.
  • A dollar sign on GitHub, where math is enabled. Escape it as \$.
  • A tag you want shown, not rendered. Use a code span, or &lt; and &gt;.

The pattern behind all of them: a code span is the blunt instrument that solves most escaping problems, and it also signals to the reader that the text is meant literally.