The Grand Markdown Feature Test

A single document that pokes at every corner of your renderer: typography, structure, tables, code, math, alerts, and a few sneaky edge cases. If something looks off, you've found a bug worth fixing.[1]


Typography

Plain text, bold, italic, bold and italic, strikethrough, inline code, and a regular link. Autolinks work too: https://example.com. You can also use highlighted text, H2O, E = mc2, and keyboard keys like Ctrl + K.

Escaped characters: *not italic*, `not code`, # not a heading, 1. not a list.

A hard line break follows this line.
And this line comes right after it.

Emoji shortcodes and literals: 🚀 ✨ 🎉 :

Typographic niceties: "curly quotes", 'single quotes', an em dash --- like this, an en dash for ranges (2020--2026), and an ellipsis...

Heading level three

Heading level four

Heading level five
Heading level six

Setext Heading One

Setext Heading Two


Lists

Unordered

  • First item
  • Second item

    • Nested item

      • Deeply nested item
    • Another nested item
  • Third item

Ordered

  1. Gather ingredients
  2. Mix thoroughly

    1. Dry first
    2. Wet second
  3. Bake until golden

Task list

  • Write the test document
  • Include every feature
  • Ship the blog
  • Take a long nap

Mixed and loose

  1. A numbered item with a paragraph.

    A second paragraph inside the same item.

    echo "code inside a list item"
  2. A numbered item with a bullet list:

    • one
    • two

Definition-style list

Term One : The first definition, if your renderer supports it.

Term Two : The second definition.


Blockquotes

A simple quote.

A longer quote with formatting, code, and a link.

It even spans multiple paragraphs.

And contains a nested quote.

And one more level down.

"The best way to find out if your renderer works is to throw everything at it."

--- Somebody, probably


Alerts

Useful information that users should know, even when skimming content.
Helpful advice for doing things better or more easily.
Key information users need to know to achieve their goal.
Urgent info that needs immediate user attention to avoid problems.
Advises about risks or negative outcomes of certain actions.

Alerts can hold richer content too, like a list:

  • Item one
  • Item two
const nested = "code inside an alert";

Tables

FeatureSupportedNotes
TablesYesYou are looking at one
AlignmentYesLeft, centre, and right
Inline codeYesWorks inside cells
FormattingYesItalic, strike, links

Alignment test:

Left alignedCentre alignedRight aligned
applebananacherry
122333
a longer cell heremidx

Wide table, to test horizontal overflow on small screens:

Column AColumn BColumn CColumn DColumn EColumn FColumn GColumn H
Lorem ipsum dolorSit amet consecteturAdipiscing elit sedDo eiusmod temporIncididunt ut laboreEt dolore magnaAliqua ut enimAd minim veniam

Math

Math is written in Typst syntax. Inline math sits in the flow of a sentence, like 𝑥2+𝑦2=𝑟2 or ∑𝑛𝑘=1𝑘=𝑛(𝑛+1)2, and should align neatly with the surrounding text.

Euler's identity, the famous one:

𝑒𝑖𝜋+1=0

The quadratic formula:

𝑥=−𝑏±√𝑏2−4𝑎𝑐2𝑎

The Gaussian integral:

∫∞−∞𝑒−𝑥2d𝑥=√𝜋

The Basel problem:

∑∞𝑛=11𝑛2=𝜋26

A matrix and a determinant:

𝐴=(𝑎𝑑𝑔𝑏𝑒ℎ𝑐𝑓𝑖),det(𝐴)=𝑎(𝑒𝑖−𝑓ℎ)−𝑏(𝑑𝑖−𝑓𝑔)+𝑐(𝑑ℎ−𝑒𝑔)

A piecewise function:

𝑓(𝑥)={𝑥2if𝑥≥0−𝑥if𝑥<0

The Laplace transform, with a series expansion:

ℒ︀{𝑓(𝑡)}=∫∞0𝑒−𝑠𝑡𝑓(𝑡)d𝑡=∑∞𝑛=0(−1)𝑛𝑛!𝑑𝑛𝑓𝑑𝑠𝑛

Maxwell, in potential form:

∇×(1𝜇0∇×𝑨)+𝜀0𝜕2𝑨𝜕𝑡2=𝑱+𝜀0∇(∇⋅𝑨)

A beastly limit, to stress the layout engine:

lim𝑁→∞∑𝑁𝑘=1(−1)𝑘+1𝑘𝑠∏𝑘𝑗=1Γ(𝑗+𝛼)Γ(𝑗+𝛽)=1Γ(𝑠)∫∞0𝑥𝑠−1𝑒−𝑥1−𝑒−𝑥log(Γ(𝑥+𝛼)Γ(𝑥+𝛽))d𝑥

And some inline odds and ends: 𝛼+𝛽=𝛾, (123), 𝒗⋅𝒘, ∫𝑓d𝑥, and text in math.


Programming

TypeScript

export function render(
  content: string,
  block: boolean,
  mode: "svg" | "html",
): string {
  const math = block ? `$ ${content} $` : `$${content}$`;
  const doc =
    `#set page(width: auto, height: auto, margin: 0pt)\n` +
    `#set text(size: 18pt)\n${math}`;

  compiler ??= NodeCompiler.create();

  const output =
    mode == "svg"
      ? compiler.svg({ mainFileContent: doc })
      : (compiler.tryHtml({ mainFileContent: doc }).result?.body() ?? "");

  const tag = mode == "svg" ? "svg" : "math";
  return (
    output.match(new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`))?.[0] ?? ""
  );
}

Python

from dataclasses import dataclass
from functools import lru_cache


@dataclass(frozen=True)
class Point:
    x: float
    y: float

    def distance_to(self, other: "Point") -> float:
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5


@lru_cache(maxsize=None)
def fib(n: int) -> int:
    return n if n < 2 else fib(n - 1) + fib(n - 2)


print([fib(i) for i in range(10)])  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Rust

use std::collections::HashMap;

fn word_count(text: &str) -> HashMap<&str, usize> {
    let mut counts = HashMap::new();
    for word in text.split_whitespace() {
        *counts.entry(word).or_insert(0) += 1;
    }
    counts
}

fn main() {
    let counts = word_count("the quick brown fox jumps over the lazy dog the end");
    println!("{:?}", counts.get("the")); // Some(3)
}

Shell

#!/usr/bin/env bash
set -euo pipefail

for file in ./posts/*.md; do
  echo "Building ${file}..."
  typst compile "$file" || echo "failed: $file" >&2
done

JSON, YAML, and TOML

{
  "name": "my-blog",
  "version": "1.0.0",
  "features": ["math", "alerts", "footnotes"],
  "nested": { "enabled": true, "count": 42, "ratio": 0.75, "nothing": null }
}
site:
  title: My Blog
  serif: false
  tags:
    - markdown
    - typst
[site]
title = "My Blog"
serif = false
tags = ["markdown", "typst"]

Diff

- const old = "before";
+ const updated = "after";
  const unchanged = true;

Typst

#set text(font: "Inter", size: 11pt)

= A Typst heading

Some *strong* text and an equation: $ integral_0^1 x^2 dif x = 1/3 $

HTML and CSS

<article class="post">
  <h1>Hello, world</h1>
  <p>Nothing fancy here.</p>
</article>
.post {
  max-width: 65ch;
  margin-inline: auto;
  font-family: system-ui, sans-serif;
}

Plain block, no language

No syntax highlighting here.
    Whitespace   is   preserved.

Long line, to test horizontal scrolling

This is a very long line of code that should scroll horizontally rather than wrap or break the layout of the page, because that is what code blocks are supposed to do when they get wide.

Media

An image with alt text:

A placeholder landscape

A linked image:

Click me


Raw HTML

Click to expand this collapsible section

Hidden content, which can still contain Markdown, code, and lists:

  • One
  • Two
  • Three
A raw HTML block with inline styles, in case your renderer allows it.

Footnotes and References

Footnotes appear at the bottom of the page, like this one.[2] You can reference the same note twice.[2] Long notes can hold more structure.[3]

Reference-style links keep prose tidy: here is one and here is another.

Heading links work too: jump back to the math section or the code section.


The Finale

If you made it this far, everything rendered. Here's one last combo of everything at once:

Mix bold, italic, code, strike, a link, and math like 𝑒𝑖𝜋=−1 in one place, and make sure it all still looks good.
It has a second paragraph, indented by four spaces.

```ts
const footnoteCode = "even code blocks";
```

Footnotes

  1. This is the first footnote, referenced from the opening paragraph. ↩
  2. A short footnote, with _formatting_ and `code`. ↩
  3. A longer footnote. ↩