Skip to content

Header IDs

Brett Terpstra edited this page Jan 4, 2026 · 4 revisions

Header IDs

Apex automatically generates unique IDs for all headers, making it easy to link to specific sections. Different processor modes use different ID generation rules.

Automatic Generation

By default, Apex generates header IDs automatically. You can disable this with --no-ids:

apex document.md --no-ids

ID Formats

Apex supports three ID formats, each matching the behavior of different Markdown processors:

GFM Format (Default)

Used by default in unified and GFM modes. Matches GitHub's header ID generation:

Rules:

  • Spaces become single dashes
  • Em dashes (—) and en dashes (–) are removed
  • Punctuation is removed
  • Other whitespace is removed
  • Diacritics are normalized to ASCII equivalents (é → e, ñ → n, etc.)
  • Emojis are converted to their textual names (e.g., 😄 → "smile", 🚀 → "rocket")
  • Leading and trailing dashes are trimmed
  • Result is lowercased

Examples:

# Emoji Support
→ id="emoji-support"

# 😄 Emoji Support
→ id="smile-emoji-support"

# 🚀
→ id="rocket"

# 👍 👎
→ id="thumbsup-thumbsdown"

# Hello—World
→ id="helloworld"

# C++ Programming
→ id="c-programming"

# Déjà Vu
→ id="deja-vu"

Note: Emoji-to-name conversion matches Pandoc's GFM behavior, ensuring emojis in headers are represented as readable text in IDs. This only applies to GFM format; MMD and Kramdown formats preserve emojis as-is or remove them according to their respective rules.

MultiMarkdown Format

Used in MultiMarkdown mode. Preserves dashes and diacritics:

Rules:

  • Spaces are removed (not converted to dashes)
  • All dash types (regular, em, en) are preserved
  • Diacritics are preserved (UTF-8)
  • Punctuation is removed
  • Leading and trailing dashes are preserved
  • Result is lowercased

Examples:

# Header—One
→ id="header—one"

# Hello World
→ id="helloworld"

# Déjà Vu
→ id="déjà-vu"

Kramdown Format

Used in Kramdown mode. More aggressive punctuation handling:

Rules:

  • Spaces become single dashes (one dash per space)
  • Em dashes (—) and en dashes (–) are removed
  • Diacritics are removed (not normalized)
  • Punctuation becomes dashes (except trailing punctuation is removed)
  • If punctuation is followed by a space, the space is skipped
  • Leading dashes are trimmed
  • Trailing dashes are preserved
  • Result is lowercased

Examples:

# Hello, World!
→ id="hello-world"

# C++ Programming
→ id="c-programming"

# Test (Example)
→ id="test-example"

Setting ID Format

By Mode

Each mode automatically sets the appropriate ID format:

  • --mode gfm → GFM format
  • --mode mmd → MultiMarkdown format
  • --mode kramdown → Kramdown format
  • --mode unified → GFM format (default)

Override in Unified Mode

In unified mode, you can override the default GFM format:

# Use MMD format in unified mode
apex document.md --mode unified --id-format mmd

# Use Kramdown format in unified mode
apex document.md --mode unified --id-format kramdown

Manual Header IDs

You can manually specify header IDs using several syntaxes:

MultiMarkdown Syntax

### Heading 1 [heading1]

Kramdown Syntax

### Heading 1 {#heading1}

Inline Attribute List (IAL)

### Heading 1 {: #heading1}

Manual IDs take precedence over auto-generated IDs.

Anchor Tags vs. IDs

By default, Apex adds id attributes directly to header elements:

<h1 id="my-header">My Header</h1>

You can generate <a> anchor tags instead:

apex document.md --header-anchors

This produces:

<h1><a id="my-header" href="#my-header">My Header</a></h1>

This format is compatible with some Markdown processors that use anchor tags.

Examples

GFM Format

# Getting Started with Apex
# Advanced Features
# C++ Integration

Becomes:

<h1 id="getting-started-with-apex">Getting Started with Apex</h1>
<h1 id="advanced-features">Advanced Features</h1>
<h1 id="c-integration">C Integration</h1>

MultiMarkdown Format

# Getting Started with Apex
# Advanced Features
# C++ Integration

With --id-format mmd:

<h1 id="gettingstartedwithapex">Getting Started with Apex</h1>
<h1 id="advancedfeatures">Advanced Features</h1>
<h1 id="cintegration">C Integration</h1>

Kramdown Format

# Getting Started with Apex
# Advanced Features
# C++ Integration

With --id-format kramdown:

<h1 id="getting-started-with-apex">Getting Started with Apex</h1>
<h1 id="advanced-features">Advanced Features</h1>
<h1 id="c-integration">C Integration</h1>

Linking to Headers

Once headers have IDs, you can link to them:

[Link to section](#getting-started-with-apex)

Or with wiki links (requires --wikilinks flag):

[[Document#getting-started-with-apex]]

Table of Contents

Apex's TOC generation automatically uses the same ID format as your headers. See Syntax for TOC details.

Related

Quick Links

Clone this wiki locally