Markdown

markdownreferencediagrams

Markdown is plain text that renders as formatted documents. John Gruber and Aaron Swartz designed it in 2004 around one goal: write in a format that is easy to read and easy to write as plain text, then convert it to valid HTML. It now runs README files, documentation, note apps like Obsidian, chat in Slack and Discord, and a fair number of content management systems.

Why Markdown

A Word document needs Word. A Markdown file is just text, so anything can open it: your editor, your terminal, git, a search tool, a browser. Nothing to install, nothing to go obsolete. That alone is most of why it won.

It is also cheap. A heading is one #. Bold is two *. A table needs no closing tags. Compare that to HTML, where half of what you type is punctuation the reader never sees.

Those two things are why AI tools write Markdown. Every character an AI writes costs something, so the cheapest formatting wins. The models also learned to write by reading the internet, and the internet's documentation, READMEs and forum posts are mostly Markdown, so it comes out naturally. It holds up when half-written too, which matters when text appears word by word on your screen: a page that is only partly finished still reads fine. That is why instruction files like AGENTS.md or CLAUDE.md are Markdown as well.

Below is the syntax you actually use, each piece next to what it produces, split into what base Markdown gives you, what GitHub Flavored Markdown adds on top, and what diagram tools layer on after that.

Base Markdown

Everything in this section is part of Markdown proper and works in any renderer.

Text styles

*italic* or _italic_
**bold** or __bold__
***bold italic***
`inline code`

italic, bold, bold italic, inline code.

Headings

Prefix a line with one to six # characters.

# Heading level 1
## Heading level 2
### Heading level 3
#### Heading level 4
##### Heading level 5
###### Heading level 6

Lists

Unordered lists take -, * or +. Indent by two spaces to nest.

- Coffee
- Tea
  - Green
  - Black
- Milk
  • Coffee
  • Tea
    • Green
    • Black
  • Milk

Ordered lists take a number and a dot. The numbers you write don't have to be sequential, the renderer counts for you.

1. Boil water
2. Add tea
   1. Wait three minutes
   2. Remove the bag
3. Drink
  1. Boil water
  2. Add tea
    1. Wait three minutes
    2. Remove the bag
  3. Drink

Blockquotes

> A quote.
>
> > A nested quote.

A quote.

A nested quote.

[inline link](https://commonmark.org)
[link with title](https://commonmark.org "CommonMark")
<https://commonmark.org>
[reference link][spec]

[spec]: https://commonmark.org

inline link link with title https://commonmark.org reference link

Images

Same as a link, with a leading !. The bracketed text is the alt text, which is what screen readers announce and what shows when the image fails to load, so write something useful there.

![Alt text](/images/example.png)
![Alt text](/images/example.png "Optional title")

An image wrapped in a link:

[![Alt text](/images/example.png)](https://example.com)

Code

Indent by four spaces, or fence with three backticks and an optional language for syntax highlighting.

```typescript
export function greet(name: string) {
  return `Hello, ${name}`;
}
```
export function greet(name: string) {
  return `Hello, ${name}`;
}

To show backticks inside a fence, wrap it in a longer fence of four backticks.

Horizontal rule

Three or more -, * or _ on their own line.

---

Escaping

Put a backslash before a character to stop it being treated as syntax: \*not italic\* renders as *not italic*.

GitHub Flavored Markdown

GFM is the dialect GitHub uses, and by now the one most tools follow. These features are not in base Markdown.

Strikethrough

~~strikethrough~~

strikethrough

Task lists

Task lists use - [ ] and - [x].

- [x] Write the article
- [ ] Publish it
  • Write the article
  • Publish it

Tables

Pipes separate cells, the second row separates the header. Colons in that row set the alignment: left, center, right.

| Feature | Syntax     | Notes                |
| :------ | :--------: | -------------------: |
| Bold    | `**text**` | Two asterisks        |
| Italic  | `*text*`   | One asterisk         |
| Code    | `` `x` ``  | Backticks            |
FeatureSyntaxNotes
Bold**text**Two asterisks
Italic*text*One asterisk
Code`x`Backticks

The pipes don't need to line up in the source, only the header separator row is required.

Base Markdown needs angle brackets around a bare URL. GFM links it either way, so https://commonmark.org on its own becomes a link.

Footnotes

Markdown has many dialects.[^1]

[^1]: CommonMark is the one that tries to pin down the ambiguities.

Diagrams

Diagram rendering is a feature of the tool showing the page, not of Markdown or GFM. A fenced block with the right language tag is handed to a diagram renderer, which draws it.

Mermaid

Many renderers (GitHub, GitLab, Obsidian, this site) turn a fenced block tagged mermaid into a diagram. See the official Mermaid documentation for the full syntax and the live editor for experimenting.

```mermaid
flowchart TD
    %% Nodes & Structure
    Start([1. Client Sends Request]) --> RateLimit{2. Rate Limiter}

    RateLimit -- Limit Exceeded --> HTTP429[429 Too Many Requests]
    RateLimit -- Within Limit --> AuthCheck{3. Authentication &<br>Authorization}

    AuthCheck -- Invalid / Expired Token --> HTTP401[401 Unauthorized /<br>403 Forbidden]
    AuthCheck -- Authorized --> Router[4. API Router & Controller]

    Router --> Validation{5. Input Validation}

    Validation -- Bad Payload / Missing Fields --> HTTP400[400 Bad Request]
    Validation -- Data Valid --> CacheCheck{6. Cache Hit?}

    CacheCheck -- Yes --> ServeCache[Fetch from Cache]
    CacheCheck -- No --> BizLogic[7. Business Logic &<br>Database Query]

    BizLogic --> DB{8. Database Success?}

    DB -- Timeout / Crash --> HTTP500[500 Internal Server Error]
    DB -- Success --> Format[9. Format Data<br>to JSON / XML]

    ServeCache --> Format
    Format --> Response([10. Client Receives Response])

    %% Error Endpoints Styles
    HTTP429 --> Response
    HTTP401 --> Response
    HTTP400 --> Response
    HTTP500 --> Response

    %% Styling
    style Start fill:#4CAF50,stroke:#388E3C,stroke-width:2px,color:#fff
    style Response fill:#2196F3,stroke:#1976D2,stroke-width:2px,color:#fff
    style HTTP429 fill:#FF5722,stroke:#E64A19,stroke-width:2px,color:#fff
    style HTTP401 fill:#FF5722,stroke:#E64A19,stroke-width:2px,color:#fff
    style HTTP400 fill:#FF5722,stroke:#E64A19,stroke-width:2px,color:#fff
    style HTTP500 fill:#F44336,stroke:#D32F2F,stroke-width:2px,color:#fff
```

Sequence diagrams, state diagrams, class diagrams, Gantt charts, ER diagrams and pie charts all work the same way, only the first keyword changes.

```mermaid
sequenceDiagram
    participant Alice
    participant Eve
    participant Bob
    Alice->>Bob: Send secret message
    Note over Eve: Eve intercepts message
    Eve-->>Bob: Forward modified message
```

PlantUML

PlantUML covers the same ground with a longer history and more diagram types, but it has no browser renderer, so almost no Markdown renderer draws a plantuml block out of the box. Rendering it means sending the source to a PlantUML server, which returns the image. This page does that with the public server at plantuml.com, so the diagram below is a picture fetched from there rather than something drawn locally.

```plantuml
@startuml
participant Alice
participant Eve
participant Bob
Alice -> Bob: Send secret message
note over Eve: Eve intercepts message
Eve --> Bob: Forward modified message
@enduml
```
PlantUML diagram

The trick is that the whole diagram fits in the URL: the source is encoded into the path of an image request, so no upload or storage is involved. Elsewhere the usual routes are a plugin, such as markdown-preview-enhanced in VS Code or the Confluence integration. Anything private should go through a self-hosted server instead, since the public one sees every diagram it draws.

See also