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~~ 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
    1. Carrot
    2. 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 app

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
![A cat asleep on a keyboard](cat.png) An image, with alt text for screen readers
[![alt](cat.png)](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 block

HTML 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>

![Alt text for the picture](cat.png)

> 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 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.