Reference
Markdown cheat sheet
The whole language on one page, with what each piece renders as beside it. Markdown is about twenty marks in total — you can read the lot in ten minutes and then never look it up again.
Last updated 1 September 2026 · covers CommonMark and GitHub Flavored Markdown
Headings and emphasis
A heading is one to six # marks, a space, then the
text. Use one # once, for the title of the document;
a reader builds its table of contents from these, so the levels
want to descend in order rather than jump from # to
####.
| Type this | You get |
|---|---|
# Title |
Title |
## Section |
Section |
### Subsection |
Subsection |
#### Smaller still |
Smaller still |
**bold** |
bold |
*italic* |
italic |
***both*** |
both |
~~struck out~~ |
|
`inline code` |
inline code |
_italic_ and __bold__ with underscores
mean the same thing as the asterisk forms. Asterisks are the safer
habit: underscores inside a word are left alone by most parsers,
so snake_case_name survives, but
*a*b*c* and _a_b_c_ do not agree
anywhere.
Paragraphs and line breaks
This is the one rule that catches everybody. A single newline is
not a line break — Markdown joins those lines into
one paragraph, which is why a hand-wrapped email pasted into a
.md file comes out as a wall of text. A blank line
starts a new paragraph. To break a line inside one paragraph, end
it with two spaces, or with a backslash.
Roses are red,
violets are blue.
Two spaces at the end of this line,··
and this line begins right under it.
Renders as two paragraphs, the second of which has a break in the middle:
Roses are red, violets are blue.
Two spaces at the end of this line,
and this line begins right under it.
The middle dots above stand in for the two spaces, which are
invisible and therefore easy to delete by accident. A trailing
backslash does the same job and can be seen:
line one\. Many editors strip trailing whitespace on
save, so if your breaks keep vanishing, that is why — use
the backslash.
Lists
A bullet is -, * or +
followed by a space. Pick one and keep to it: changing the marker
mid-list starts a second list. A numbered list is any number, a
full stop and a space.
- Milk
- Eggs
- Bread
1. Open the file
2. Read the file
3. Close the file
The numbers you type are ignored past the first — a list
written 1., 1., 1. still
renders 1, 2, 3, which is handy when you insert a step in the
middle. Start at something other than 1 and it is honoured, so
7. begins at seven.
Nest by indenting two spaces under the parent item's text, or four if you want a rule that works in every parser ever written:
- Fruit
- Apple
- Pear
- Vegetables
1. Carrot
2. Leek
Which gives:
-
Fruit
- Apple
- Pear
-
Vegetables
- Carrot
- Leek
Task lists
A GitHub extension, and the most-used one after tables. Square
brackets with a space are unchecked, with an x
checked:
| Type this | You get |
|---|---|
- [ ] Not done yet |
Not done yet |
- [x] Done |
Done |
See it happen as you type
Every example on this page is Markdown, and Markdown Eye renders it live in a split window — the source on the left, the result on the right, no sign-in and nothing uploaded. Paste an example in and change it.
Open the web appLinks and images
Square brackets hold the words the reader sees, round brackets hold where they go. An image is the same thing with an exclamation mark in front, and the brackets hold the alt text instead.
| Type this | What it does |
|---|---|
[Markdown Eye](https://markdowneye.com/) |
A link with its own text |
[the app](./app "Read Markdown online") |
A link with a tooltip, to a relative path |
<https://markdowneye.com/> |
The URL itself, made clickable |
 |
An image, with alt text for screen readers |
[](https://example.com) |
An image that is also a link |
[jump](#lists) |
A link to a heading on the same page — lower case, spaces become hyphens, punctuation is dropped |
If the same long URL appears several times, or a paragraph is becoming unreadable, define the link once at the bottom and refer to it by name. The definition is invisible in the output and can sit anywhere in the file:
Built by [Techely][t], and it reads [PDFs][p] too.
[t]: https://www.techely.com
[p]: https://markdowneye.com/app
Code
One backtick either side for code inside a sentence. Three backticks on their own line, above and below, for a block — and put the language after the opening three, which is what turns the highlighting on.
```js
const eye = "open";
console.log(eye.toUpperCase());
```
Common names: js, ts,
python, bash, json,
yaml, sql, html,
css, diff, c,
cpp, java, go,
rust, php. Markdown Eye highlights over
190 of them; a name it does not know just renders as plain
monospace rather than failing.
To show a backtick inside inline code, wrap it in two:
``a ` b``. To show a whole fence, wrap it in four.
And if you would rather not use fences at all, indenting a block
by four spaces also makes it code — the older syntax, still
valid, but it cannot carry a language name.
Tables
Pipes between the cells, and a row of dashes under the header. That dash row is not decoration — it is what tells the parser this is a table at all, so a table without it renders as a line of text full of pipes.
| Language | Extension | Highlighted |
| ---------- | --------- | ----------- |
| JavaScript | .js | yes |
| Rust | .rs | yes |
| Whitespace | .ws | no |
Which renders as:
| Language | Extension | Highlighted |
|---|---|---|
| JavaScript | .js | yes |
| Rust | .rs | yes |
| Whitespace | .ws | no |
Line the pipes up if you like — it makes the source readable and changes nothing in the output. The number of dashes does not matter either; three is the minimum.
Aligning a column
Colons in the dash row set the alignment of the whole column, and they are the only place alignment can be set:
| Dash row | Column is |
|---|---|
| --- | |
Left, the default |
| :--- | |
Left, said out loud |
| :---: | |
Centred |
| ---: | |
Right — what numbers want |
Three limits are worth knowing before you fight them. A cell
cannot contain a paragraph break, so a long cell needs a literal
<br> where the line should turn. A pipe inside a
cell has to be escaped as \|, or it ends the cell. And
there is no way to merge cells — no colspan, no rowspan. If
you need one, the table has to be written as HTML.
Quotes and rules
A > at the start of a line quotes it, and quotes
nest. Three or more dashes, asterisks or underscores on a line of
their own draw a horizontal rule.
> Any fool can write code that a computer can understand.
>
> > The hard part is writing code a human can understand.
---
Which gives a quote inside a quote, then a rule:
Any fool can write code that a computer can understand.
The hard part is writing code a human can understand.
Keep a blank line before a rule made of dashes. Put
--- directly under a line of text and the older
syntax takes over: that line becomes a heading instead, which is
the usual explanation for a stray heading nobody typed.
Three dashes at the very top of a file are something else again
— a block of ---, then
key: value lines, then --- is front
matter, the metadata that static site generators read. Markdown
itself has no such concept, so a plain renderer shows it: the first
--- becomes a rule, and the closing one turns the
key: value lines above it into a heading. That is not
a fault in the file — it is the site generator's convention
showing through, and it disappears once the generator has had it.
Math
Not part of Markdown itself, but supported almost everywhere it matters, in LaTeX notation. Markdown Eye reads all four of the usual delimiters, so a document written for GitHub, for Jupyter or for a LaTeX habit all render the same:
| Type this | What it does |
|---|---|
$E = mc^2$ |
Inline, in the flow of the sentence |
\(E = mc^2\) |
Inline, the LaTeX form |
$$ … $$ |
Its own centred block |
\[ … \] |
Its own centred block, the LaTeX form |
```math |
A fenced block, the way GitHub writes it |
The area under the curve is $\int_0^1 x^2\,dx$, or:
$$
\int_0^1 x^2\,dx = \frac{1}{3}
$$
Rendering is by KaTeX, which covers the mathematics and most of the
symbols but not the whole of LaTeX — no packages, no
\newcommand across blocks, no TikZ. A dollar sign that
is meant to be money needs escaping as \$, or the
paragraph after it turns into an equation.
Diagrams
A fenced block labelled mermaid is drawn as a diagram
rather than printed as code. The point of it is that the diagram
lives in the document as text: it goes through code review, it
diffs, and nobody has to find the original file to change an arrow.
```mermaid
flowchart LR
A[Open a .md file] --> B{Which mode?}
B -->|Read| C[Rendered, with contents]
B -->|Split| D[Source and preview]
B -->|Edit| E[Just the source]
```
Change the first word and you get a different kind of diagram:
sequenceDiagram, classDiagram,
stateDiagram-v2, erDiagram,
gantt, pie, mindmap,
timeline, gitGraph. The syntax for each
is Mermaid's own, and its documentation is the place to look it up
— this page is about Markdown, and Mermaid is a language of
its own that Markdown merely carries.
Diagrams need a renderer
GitHub draws Mermaid blocks; most editors show them as code and leave you to imagine it. Markdown Eye draws them, in the same window as the rest of the document, and redraws as you type.
Try a Mermaid blockHTML inside Markdown
Markdown allows raw HTML, which is the escape hatch for everything
it cannot do: a merged table cell, an image at a particular width,
a collapsible block. Two rules make it behave. Leave a blank line
before and after a block-level tag, and do not expect Markdown
inside it — text between <div> tags is
passed through untouched, so **bold** in there stays
as asterisks.
<details>
<summary>Show the long version</summary>
Blank lines around this, and *this* is Markdown again.
</details>
<img src="cat.png" alt="A cat" width="320">
Whether the HTML survives depends on where the file is read.
GitHub strips most tags and all attributes it does not trust.
Markdown Eye runs everything through DOMPurify, which keeps the
formatting tags and removes anything that could execute —
because a .md file from the internet is untrusted
input, and a reader that runs its scripts is a security hole
rather than a feature.
Escaping a character
A backslash before a Markdown character makes it literal:
\*not italic\*, \# not a heading,
\| not a cell. The characters that need it are
\ ` * _ { } [ ] ( ) # + - . ! | and, where math is
on, $. Inline code is the other way to be literal and
is usually clearer for one-off symbols.
Syntax that is not universal
These appear on plenty of cheat sheets without the warning they need: each one is an extension that a particular site or plugin added, and it renders as literal characters everywhere else. If something below is not working for you, it is almost certainly not your typing.
| Syntax | Where it works |
|---|---|
[^1] and [^1]: the note |
Footnotes. GitHub, GitLab and Pandoc. Not in plain CommonMark, and not in Markdown Eye — they show as the bracketed text. |
==highlighted== |
Obsidian, and a few others. Nowhere in the standard. |
> [!NOTE] |
GitHub's coloured callouts. Elsewhere, an ordinary quote
with [!NOTE] as its first line.
|
## Heading {#my-id} |
Custom anchors. Pandoc and most static site generators.
Markdown Eye makes its own ids from the heading text, so
[jump](#my-heading) works without this.
|
:tada: |
Emoji shortcodes. GitHub and chat apps. Paste the emoji itself and it works everywhere. |
H<sub>2</sub>O |
Subscript and superscript have no Markdown of their own; the HTML tags are the portable way, and they survive. |
Which Markdown is this?
There is no single Markdown. John Gruber wrote the original in 2004 and left a good deal of it undefined, so everyone who implemented it made different guesses. Two names are worth knowing:
- CommonMark — the specification that settled the ambiguities. Headings, emphasis, lists, links, images, code, quotes, rules. No tables.
- GitHub Flavored Markdown (GFM) — CommonMark plus the four extensions everybody now assumes are Markdown: tables, strikethrough, task lists, and URLs that become links without brackets.
Everything on this page above the previous section is CommonMark or
GFM, which is what Markdown Eye renders and what a
README.md is read as. Write to that and your document
looks the same on GitHub, in a static site, in this app and in the
next editor you try.
The whole thing at once
One block with every mark on this page in it. Copy it, save it as
demo.md, and open it in whatever you are using
— whatever renders and whatever does not tells you more
about your setup than any list of features.
# Title
A paragraph with **bold**, *italic*, ~~struck~~ and `code` in it.
A second line, joined to the first. Two spaces end this one,··
so this begins on a new line.
## Lists
- Bullet
- Nested bullet
- [x] Done
- [ ] Not done
1. First
2. Second
## A link, an image, a quote
[Markdown Eye](https://markdowneye.com/) — and <https://markdowneye.com/app>

> Quoted, and it can
> run over two lines.
## A table
| Thing | Works |
| ----- | :---: |
| Table | yes |
| Math | yes |
## Code
```js
const eye = "open";
```
## Math and a diagram
Inline $E = mc^2$, and a block:
$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$
```mermaid
flowchart LR
A[Write] --> B[Read]
```
---
Escaped: \*not italic\* and \# not a heading.
The middle dots on line four are the two spaces again; type real ones. Everything else can be pasted as it stands.
Then what
A cheat sheet is only useful next to something that renders it.
Markdown Eye reads a .md file with its contents down
the side, highlighted code, real math and drawn diagrams —
in the browser with no sign-in, or as a Windows app. Nothing is
uploaded either way.
- Open the web app and paste any example above into it.
-
Not sure what a
.mdfile even is? How to open a .md file starts further back. -
Download for Windows to make it the
program that opens
.mdfiles on double-click.
Open a Markdown file and see
One click, no account, nothing to install and nothing uploaded. If it is not for you there is nothing to cancel.