NanoFile

Markdown cheat sheet

Every piece of markdown syntax, with the rendered result next to it. Each topic has its own page with the mistakes that catch people and the platforms that disagree.

The basics

A heading is a line that starts with one to six hash signs and a space. The number of hashes is the level, so # is the title and ### is a sub-sub-section.

All six levels
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6
The underline style, for levels 1 and 2 only
Heading 1
=========

Heading 2
---------

Heading 1

Heading 2

Called setext headings. They only go two levels deep, which is why almost everyone uses hashes.

Pressing Enter once does nothing visible: markdown joins the two lines into one paragraph. This is the single most common markdown surprise, and there are three ways around it.

Two spaces at the end of the line
first line  
second line

first line
second line

The two trailing spaces are invisible in your editor, which is exactly why this trips people up.

A backslash at the end of the line
first line\
second line

first line
second line

Visible, so it survives editors that trim trailing whitespace. Supported by CommonMark and GitHub.

Escaping characters in markdown

Escaping in detail, with the pitfalls →

Put a backslash in front of a markdown character to show it rather than act on it. It is the way out when your text contains the same symbols markdown uses.

Escaping
\*not italic\*

\# not a heading

2 \* 3 \* 4

*not italic*

# not a heading

2 * 3 * 4

Or use code, which escapes everything at once
`*everything here is literal*`

*everything here is literal*

Markdown has no comment syntax. An HTML comment is the usual way to leave a note in the file that does not appear in the rendered page.

HTML comment
<!-- This note is not rendered. -->
Multi-line
<!--
A longer note.
Still hidden.
-->

Front matter is metadata at the very top of a markdown file, fenced by three dashes above and below. Static site generators, Obsidian and most note tools read it; a plain renderer ignores it or, worse, prints it.

Front matter
---
title: Opening .md files
date: 2026-08-27
tags:
  - markdown
  - tools
draft: false
---

# The document starts here

title: Opening .md files date: 2026-08-27 tags: - markdown - tools draft: false

The document starts here

Text formatting

Wrap text in two asterisks to make it bold. Two underscores do the same thing, and both are equally correct, though asterisks are the safer habit.

Bold
**bold text**

__also bold__

bold text

also bold

Bold and italic together
***bold and italic***

**bold with _italic_ inside**

bold and italic

bold with italic inside

One asterisk either side gives italic text. A single underscore does the same, with one exception worth knowing about inside words.

Italic
*italic text*

_also italic_

italic text

also italic

Nested with bold
**bold with *italic* inside**

bold with italic inside

Two tildes either side of the text draw a line through it. It is a GitHub-flavoured extension rather than original markdown, which is why a few older renderers ignore it.

Strikethrough
~~struck through~~

struck through

Combined with other emphasis
~~**struck and bold**~~

struck and bold

There is no markdown syntax for underlining, and that is deliberate. On the web an underline means a link, so markdown left it out. When you genuinely need one, HTML is the answer.

The HTML that works nearly everywhere
<u>underlined text</u>

underlined text

Markdown files may contain HTML, and almost every renderer passes this straight through.

What people usually want instead
**bold for emphasis**

*italic for a title or a term*

bold for emphasis

italic for a title or a term

Lists

A dash and a space makes a bullet. A number, a dot and a space makes a numbered list. Nesting works by indenting, and the amount of indentation is where it usually goes wrong.

Bulleted
- first
- second
- third
  • first
  • second
  • third

`*` and `+` do the same thing. Pick one and stay with it.

Numbered
1. first
2. second
3. third
  1. first
  2. second
  3. third

A task list is a bulleted list where each item starts with a pair of brackets. Empty brackets give an empty box, an x inside gives a ticked one.

Task list
- [ ] not done yet
- [x] done
- [X] also done
  • not done yet
  • done
  • also done

Capital or lowercase x, both work.

Nested tasks
- [ ] parent task
  - [x] a step that is finished
  - [ ] a step that is not
  • parent task
    • a step that is finished
    • a step that is not

Blocks

One backtick either side gives inline code. Three backticks on their own line open and close a block, and a language name after the opening fence turns on highlighting.

Inline
Run `npm install` first.

Run npm install first.

Fenced block with a language
```ts
export function render(source: string) {
  return marked.parse(source);
}
```
export function render(source: string) {
  return marked.parse(source);
}

Start a line with a greater-than sign and a space to quote it. Everything that follows on that line, and on the lines after it that also start with the sign, becomes one quote.

A quote
> Nothing here is uploaded.
> Check your network tab.

Nothing here is uploaded. Check your network tab.

Several paragraphs
> First paragraph.
>
> Second paragraph.

First paragraph.

Second paragraph.

The lone `>` on the middle line is what keeps the two paragraphs inside the same quote.

Mermaid turns a few lines of text into a flowchart, a sequence diagram or a Gantt chart. It is not markdown: it is a code block that some renderers have learned to draw. Which is the whole story, because the same file is a picture in one place and a wall of arrows in another.

A flowchart
```mermaid
flowchart LR
  A[Write the file] --> B{Renders?}
  B -- yes --> C[Ship it]
  B -- no --> D[Check the platform]
  D --> A
```

`flowchart LR` is left to right; `TD` is top down. The shape comes from the brackets: `[]` a box, `{}` a diamond, `()` a rounded box.

A sequence diagram
```mermaid
sequenceDiagram
  Browser->>Page: opens the file
  Page-->>Browser: renders it locally
  Note over Page: nothing is uploaded
```

A solid arrow is `->>`, a dashed reply is `-->>`. Nothing else about the syntax matters until the diagram gets big.

A footnote is a marker in the text and a definition somewhere else in the file. The renderer collects the definitions, numbers them and puts them at the bottom with links back.

A footnote
Markdown was designed in 2004.[^1]

[^1]: By John Gruber, with Aaron Swartz on the syntax.

Markdown was designed in 2004.1

Footnotes

  1. By John Gruber, with Aaron Swartz on the syntax.

Named, and with several paragraphs
Nothing is uploaded.[^privacy]

[^privacy]:
    The parser runs in the browser.

    Indent continuation lines by four spaces.

Nothing is uploaded.1

Footnotes

  1. The parser runs in the browser.

    Indent continuation lines by four spaces.

Links and images

An image is written like a link with an exclamation mark in front of it. The square brackets hold the alt text, not a caption.

Image
![A blue heron in flight](heron.jpg)

A blue heron in flight

With a title
![A blue heron](heron.jpg "Photographed at dawn")

A blue heron

Tables

A table is rows of cells separated by pipes, with a line of dashes under the header row. Tables are a GitHub-flavoured extension, not original markdown, but support is close to universal now.

A table
| Element | Support |
| --- | --- |
| Tables | GitHub-flavoured |
| Task lists | Yes |
Element Support
Tables GitHub-flavoured
Task lists Yes
Alignment, set with colons
| Left | Centre | Right |
| :--- | :----: | ----: |
| a | b | 1,00 |
Left Centre Right
a b 1,00

Platform differences

Discord uses its own dialect of markdown. Most of it matches what you already know, with a handful of additions and a longer list of omissions.

What works
**bold**
*italic*
__underline__
~~strikethrough~~
***bold italic***
`inline code`
> a quote
# Heading 1
## Heading 2
### Heading 3
- a bullet
1. a numbered item
[a link](https://example.com)

bold italic underline strikethrough bold italic inline code

a quote

Heading 1

Heading 2

Heading 3

  • a bullet
  1. a numbered item a link
Discord's own
||spoiler text||

-# small text

```ts
const highlighted = true;
```

||spoiler text||

-# small text

const highlighted = true;

Slack calls its formatting mrkdwn, and the name is a warning: bold is one asterisk, italic is one underscore, and several things you expect are missing.

What works
*bold*
_italic_
~strikethrough~
`inline code`
> a quote
- a bullet
1. a numbered item
```
a code block
```

bold italic strikethrough inline code

a quote

  • a bullet
  1. a numbered item
a code block

Try any of it

Every snippet above has a Try it button that loads it into the viewer, where you can edit it and watch the result change. Nothing you write there leaves your browser.

Open the viewer