Markdown Cheatsheet

Every rule below shows the markdown you write next to what it actually renders to. The output is produced by the same renderer that displays pastes on this site, so what you see here is what you get.

Headings

Six levels, one to six hashes. The space after the hashes is required — `#Heading` renders as literal text, not a heading.

You write
# Release notes
## Version 2.1
### Bug fixes
#### Storage layer
You get

Release notes

Version 2.1

Bug fixes

Storage layer

Skipping levels (H1 straight to H3) renders fine but reads poorly to screen readers and search engines. Go in order where you can.

Bold, italic and strikethrough

One marker for italic, two for bold, three for both. Tildes give you strikethrough.

You write
*italic* and _also italic_

**bold** and __also bold__

***bold italic***

~~struck through~~
You get

italic and also italic

bold and also bold

bold italic

struck through

Underscores do not work mid-word — `snake_case_name` stays intact, which is exactly what you want when writing about code. Asterisks do split words.

Lists

Dashes, asterisks or plus signs for bullets; numbers for ordered lists. Indent by two spaces to nest.

You write
- Parser
- Renderer
  - Syntax highlighting
  - Math
- Storage

1. Compress
2. Encrypt
3. Store
You get
  • Parser
  • Renderer
    • Syntax highlighting
    • Math
  • Storage
  1. Compress
  2. Encrypt
  3. Store

Ordered lists renumber themselves. Writing 1. three times still renders 1, 2, 3 — handy when reordering steps.

Task lists

A GitHub Flavored Markdown extension. Square brackets with a space are unchecked, with an x are checked.

You write
- [x] Write the parser
- [x] Add syntax highlighting
- [ ] Ship expiry options
- [ ] View counter
You get
  • Write the parser
  • Add syntax highlighting
  • Ship expiry options
  • View counter

Images

Same as a link with a leading exclamation mark. The bracketed text is alt text, not a caption — it is what shows if the image fails to load.

You write
![A markdown logo](https://mdbin.sivaramp.com/mdbin.png)

[![Clickable image](https://mdbin.sivaramp.com/mdbin.png)](https://mdbin.sivaramp.com)
You get
A markdown logo

Wrapping an image in a link is how you make it clickable — that nested form is why link and image syntax look so similar.

Code and syntax highlighting

Backticks for inline code, three backticks for a block. Name the language after the opening fence to get highlighting.

You write
Call `decrypt()` before rendering.

```typescript
export async function decrypt(blob: string, password: string) {
  const key = await deriveKey(password, salt)
  return crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, data)
}
```
You get

Call decrypt() before rendering.

typescript
export async function decrypt(blob: string, password: string) {  const key = await deriveKey(password, salt)  return crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, data)}

To show literal backticks inside inline code, wrap with more backticks than you need to display.

Tables

Pipes separate columns, and the second row sets alignment. Colons control it: left, right, or both for centred.

You write
| Algorithm | Key size | Authenticated |
|:----------|---------:|:-------------:|
| AES-GCM   |      256 | Yes           |
| AES-CBC   |      256 | No            |
| ChaCha20  |      256 | Yes           |
You get
AlgorithmKey sizeAuthenticated
AES-GCM256Yes
AES-CBC256No
ChaCha20256Yes

The dashes do not need to line up. Ugly source renders into a clean table, so do not waste time aligning by hand.

Blockquotes

A leading angle bracket. Stack them to nest, and keep using markdown inside.

You write
> Encryption happens in the browser.
>
> > The server only ever sees ciphertext.
You get

Encryption happens in the browser.

The server only ever sees ciphertext.

Math

LaTeX via KaTeX. Single dollar signs for inline math, double for a centred block.

You write
Key derivation runs $n = 310{,}000$ iterations.

$$
\text{DK} = \text{PBKDF2}(\text{PRF}, P, S, c, \text{dkLen})
$$
You get

Key derivation runs $n = 310{,}000$ iterations.

DK=PBKDF2(PRF,P,S,c,dkLen)\text{DK} = \text{PBKDF2}(\text{PRF}, P, S, c, \text{dkLen})

Not part of standard markdown — most renderers show this as literal text. It works here, on GitHub, and in most documentation tooling.

Mermaid diagrams

A fenced code block tagged `mermaid` becomes a rendered diagram. Flowcharts, sequence diagrams, state machines and more.

You write
```mermaid
flowchart LR
  A[Write markdown] --> B{Encrypt?}
  B -- Yes --> C[Derive key in browser]
  B -- No --> D[Compress]
  C --> E[Store ciphertext]
  D --> E
```
You get

Also outside standard markdown. Diagrams live as text, so they stay diffable in version control.

Horizontal rules

Three or more dashes, asterisks or underscores on their own line.

You write
Above the line

---

Below the line
You get

Above the line


Below the line

Put a blank line before the dashes. Directly under a line of text, they turn that text into a heading instead.

Line breaks and paragraphs

A blank line starts a new paragraph. A single newline is usually collapsed — end a line with two spaces to force a break inside one paragraph.

You write
This line ends with two spaces
so this sits directly underneath it.

This is a separate paragraph.
You get

This line ends with two spaces so this sits directly underneath it.

This is a separate paragraph.

Trailing whitespace being meaningful is markdown at its worst. Most editors strip it on save, so prefer a blank line where you can.

Footnotes

Reference a note inline, define it anywhere. Rendered output collects them at the bottom with a link back.

You write
Content is compressed before storage.[^brotli]

[^brotli]: Brotli, which typically beats gzip on text.
You get

Content is compressed before storage.

Footnotes

  1. Brotli, which typically beats gzip on text.

Inline HTML

Markdown passes most HTML straight through, which covers whatever the syntax cannot express.

You write
<details>
<summary>Click to expand</summary>

Hidden until opened. Markdown still works **in here**.

</details>
You get
Click to expand

Hidden until opened. Markdown still works in here.

Keep a blank line between an HTML tag and markdown inside it, or the markdown will not be parsed. Anywhere rendering untrusted input, HTML should be sanitised.

Escaping

Put a backslash before a character to render it literally instead of as syntax.

You write
\*not italic\*

\# not a heading

A literal backslash: \\
You get

*not italic*

# not a heading

A literal backslash: \

Try it yourself

Paste markdown, get a shareable link with real rendering — syntax highlighting, tables, math and diagrams included. No signup, and optional end-to-end encryption if the contents are sensitive.