MkDocs Extensions Guide#
This guide explains all the markdown extensions enabled in this documentation site and how to use them effectively.
Installation Required
Before using these extensions, install all required packages: MkDocs Installation Guide
Escaping Syntax in Documentation#
Core Concept
When writing documentation about markdown extensions, you often need to show the raw syntax without MkDocs processing it. This section explains how to display examples that would otherwise be transformed by extensions.
The Problem#
When documenting extensions, you want to show users the raw syntax they should type. But MkDocs processes that syntax before rendering!
Example problem with the Critic extension:
You want to show this syntax:
This is {--deleted text--}. But when used in markdown, it renders like this:
Result: Readers see the styled output, not the raw syntax they need to type - regardless of the type you wrap it in (e.g. bash, text, mardown, etc).
Understanding MkDocs Processing Order#
MkDocs processes your documentation in this order:
- Markdown extensions process first (
pymdownx.snippets,pymdownx.critic, etc.) - Plugins process second (
mkdocs-macros-pluginfor Jinja2 templates) - Rendering happens last
This means:
- ✅ Markdown extensions see and transform their syntax patterns
- ✅ Plugins see the result after extensions run
- ❌ Standard markdown code blocks don't prevent extension processing
Solution 1: HTML Entities in <pre><code> Blocks#
When to use: Preventing markdown extensions from processing syntax examples.
How it works: HTML entities bypass markdown processing because they're already HTML.
Common HTML entities:
| Character | Entity Code | Use Case |
|---|---|---|
{ | { | Critic markup, Jinja2 |
} | } | Critic markup, Jinja2 |
< | < | Snippets, HTML tags |
> | > | Snippets, HTML tags |
- | - or - | Double dashes (optional) |
+ | + or + | Double plus (optional) |
% | % | Jinja2 (optional) |
Example - Showing Critic Markup Syntax:
❌ WRONG - Gets processed by critic extension:
This is {--deleted text--}. ✅ CORRECT - Shows raw syntax:
Renders as: what you see above, since I had to use it to show you the example. 💛
Example - Showing Snippets Syntax:
❌ WRONG - Tries to include the file:
If you are seeing this, it is because it is a sample snippet
in the common folder called: `example-snippet.md`
✅ CORRECT - Shows raw syntax:
Renders as:
--8<-- "snippets/common/example-snippet.md" Solution 2: {% raw %} Tags#
When to use: Preventing Jinja2/macros plugin from processing template syntax (but NOT for markdown extensions).
How it works: Tells the macros plugin to skip processing the content between tags.
Example - Showing Jinja2 Template Syntax:
✅ CORRECT - Prevents macros plugin processing:
The following code:
{% raw %}
```markdown
{% if page.meta.priority %}
Priority: {{ page.meta.priority }}
{% endif %}
```
{% endraw %}
... will render this:
Does NOT Work for Markdown Extensions
The {% raw %} tags only prevent Jinja2/macros plugin processing (step 2).
They do NOT prevent markdown extensions (step 1) from processing.
Why: Extensions run before plugins see the {% raw %} tags.
Solution 3: Nested Code Blocks (Rare Cases)#
For some simple cases, triple backticks inside triple backticks work with pymdownx.superfences:
Limitation: Only works for basic markdown, not for special extension syntax.
Decision Guide: Which Method to Use?#
flowchart TD
A[What are you documenting?] --> B{Type of syntax?}
B -->|"Markdown extension<br>(snippets, critic)"| C["Use HTML entities in pre/code blocks"]
B -->|"Jinja2 templates<br>(macros plugin)"| D[Use raw tags]
B -->|"Basic markdown<br>(headings, lists)"| E["Use nested code blocks with superfences"]
C --> F["Example:<br>#123;--text--#125;"]
D --> G["Example:<br>#123;% raw %#125;<br>#123;#123; var #125;#125;<br>#123;% endraw #125;"]
E --> H["Example:<br>````markdown"] Quick Reference Table#
| Extension | Example Syntax | Escape Method | Entity/Code |
|---|---|---|---|
| Critic | | HTML entities | {--deleted--} |
| Critic | added | HTML entities | {++added++} |
| Critic | | HTML entities | {~~old~>new~~} |
| Snippets | --8<-- "file:section-name" | HTML entities | --8<-- "file:section-name" |
| Jinja2 | {{ variable }} | {% raw %}{% raw %} tags | N/A - use raw tags |
| Jinja2 | {% if condition %} | {% raw %} tags | N/A - use raw tags |
| HTML tags | <div> | HTML entities | <div> |
Real-World Examples from This Guide#
Throughout this guide, you'll see these techniques used:
- Critic syntax example (line ~695): Uses
{and}to showdeleted - Snippets syntax example (line ~77): Uses
<to show--8<-- - Jinja2 macro example (line ~358): Uses
{% raw %}tags to show{{ read_csv() }}
Table of Contents Extensions#
toc - Table of Contents#
Automatically generates table of contents from page headings.
Configuration:
- toc:
permalink: "#" # Adds clickable anchor links to headings
toc_depth: 3 # Include h1, h2, h3 in TOC (excludes h4, h5, h6)
Usage:
Each heading automatically gets an anchor link you can click to get a direct URL.
Code Highlighting Extensions#
pymdownx.highlight - Syntax Highlighting#
Provides beautiful syntax highlighting for code blocks.
Example:
def calculate_zone(temperature):
"""Calculate USDA hardiness zone from temperature."""
if temperature < -60:
return "1a"
elif temperature < -55:
return "1b"
# ... more logic
return "13b"
Features:
- Line numbers with
anchor_linenums: true - Line highlighting
- Language-specific syntax coloring
pymdownx.inlinehilite - Inline Code Highlighting#
Highlight code within text: print("Hello") renders as syntax-highlighted inline code.
Example:
The function def my_func(): does something important.
pymdownx.snippets - Code Snippet Inclusion#
Include code from external files directly into documentation.
Example:
--8<-- "path/to/code.py"
SOME EXAMPLE SHOULD BE ABOVE
From here you can also specify sections:
--8<-- "include.md:name"
--8<--
include.md:name
--8<--
Snippets + Jinja2 Templates DON'T WORK
Problem: You CANNOT use snippets to include Jinja2 template code!
Why: Execution order:
- ✅ Markdown extensions (including
pymdownx.snippets) run FIRST - ✅ Plugins (including
mkdocs-macros-plugin) run SECOND
What happens:
The snippet includes Jinja2 code as literal text BEFORE the macros plugin can process it. You'll see raw {% if page.meta.priority %} on the rendered page.
Solution - Put Jinja2 code directly in files:
<!-- ✅ CORRECT - Macros plugin processes this -->
{% if page.meta.priority %}
<div class="badge">{{ page.meta.priority }}</div>
{% endif %}
When to use snippets:
- ✅ Regular markdown content
- ✅ Code examples
- ✅ Static content that doesn't need processing
When NOT to use snippets:
- ❌ Jinja2 templates (use direct code instead)
- ❌ Dynamic content that needs plugin processing
pymdownx.superfences - Advanced Code Blocks#
Enables nested code blocks and custom fences like Mermaid diagrams.
Diagram Support#
Learn More: Mermaid Documentation
Mermaid Diagrams#
Create diagrams directly in markdown using Mermaid syntax.
Example - Flowchart:
graph LR
A[Gardener] --> B{Check Zone}
B -->|Zone 6a| C[Select Plants]
B -->|Zone 7b| D[Select Plants]
C --> E[Add to Garden]
D --> E Example - Sequence Diagram:
sequenceDiagram
User->>System: Search for tomato
System->>Database: Query plants
Database-->>System: Return results
System-->>User: Display plants Example - Class Diagram:
classDiagram
class Plant {
+String commonName
+String scientificName
+String hardinessZone
+Boolean isDroughtTolerant
+getPlantInfo()
}
class Profile {
+User user
+List plants
+addPlant()
+removePlant()
}
Profile --> Plant : contains Supported Diagram Types:
- Flowcharts (
graph) - Sequence diagrams (
sequenceDiagram) - Class diagrams (
classDiagram) - State diagrams (
stateDiagram) - Entity Relationship diagrams (
erDiagram) - Gantt charts (
gantt) - Pie charts (
pie) - Git graphs (
gitGraph)
Content Organization Extensions#
pymdownx.tabbed - Tabbed Content#
Create tabbed content blocks for organizing related information.
Example:
=== "Web Interface"
Access the plant search from the main navigation menu.
=== "Mobile App"
Tap the search icon in the bottom navigation bar.
=== "API"
```bash
curl https://api.example.com/plants?zone=6a
```
Renders as:
Admonitions & Callouts#
admonition - Callout Boxes#
Create attention-grabbing callout boxes as per here.
Available Types:
Note
This is a note - use for general information.
Tip
This is a tip - use for helpful suggestions.
Warning
This is a warning - use for important caveats.
Danger
This is a danger alert - use for critical warnings.
Example
This is an example - use for code examples or demonstrations.
Quote
This is a quote - use for citations or references.
Success
This is a success message - use for confirmations.
Information
This is an info box - use for supplementary information.
Question
This is a question - use for FAQs or clarifications.
Bug
This is a bug alert - use for known issues.
Syntax:
Custom Plant Tip (with custom CSS):
pymdownx.details - Collapsible Admonitions#
Make admonitions collapsible to save space.
Example:
??? question "How do I determine my USDA zone?"
Click here to expand and see the answer.
Your USDA hardiness zone is based on your location's average annual minimum temperature.
Renders as:
How do I determine my USDA zone?
Click here to expand and see the answer.
Your USDA hardiness zone is based on your location's average annual minimum temperature.
Start Expanded:
Renders as:
Pro Tip
This starts open but can be collapsed.
Table Extensions#
tables - Enhanced Tables#
Create beautiful, responsive tables.
Example:
| Plant | Zone | Sun | Water |
|-------|------|-----|-------|
| Tomato | 3-11 | Full | Medium |
| Lettuce | 2-11 | Partial | High |
| Basil | 10-11 | Full | Medium |
Renders as:
| Plant | Zone | Sun | Water |
|---|---|---|---|
| Tomato | 3-11 | Full | Medium |
| Lettuce | 2-11 | Partial | High |
| Basil | 10-11 | Full | Medium |
Alignment:
| Left-aligned | Center-aligned | Right-aligned |
|:-------------|:--------------:|--------------:|
| Content | Content | Content |
mkdocs-table-reader-plugin - Import Tables from External Files#
Note that even after installing mkdocs-table-reader-plugin you may still be asked to install:
openpyxlxlrd
View this extension's documentation here. Learn how to use it to create reproducible reports via here.
Include tables directly from CSV, Excel, or other data files into your documentation.
Installation:
Configuration in mkdocs.yml:
Basic Usage - CSV Files:
Basic Usage - Excel Files:
Read Specific Excel Sheet:
Advanced Options:
<!-- Include only specific columns -->
{{ read_csv('data.csv', usecols=['Name', 'Zone', 'Type']) }}
<!-- Skip rows -->
{{ read_csv('data.csv', skiprows=2) }}
<!-- Use specific encoding -->
{{ read_csv('data.csv', encoding='utf-8') }}
<!-- Read Excel with specific range -->
{{ read_excel('data.xlsx', sheet_name='Plants', usecols='A:D') }}
Example - Decision Matrix:
## Project Decisions
The following decision matrix was used to evaluate our options:
{{ read_excel('../../decisions/CESYS524_decision-matrix.xlsx') }}
Features:
- Automatically converts CSV/Excel to markdown tables
- Supports pandas DataFrame operations
- Updates automatically when source files change
- No need to manually maintain duplicate table data
- Supports filtering, column selection, and formatting
Use Cases:
- Decision matrices and trade-off analyses
- Quality Function Deployment (QFD) matrices
- FMEA (Failure Mode and Effects Analysis) tables
- N-squared charts and interface matrices
- Any tabular data stored in external files
Learn More: mkdocs-table-reader-plugin Documentation
Styling Extensions#
attr_list - Add CSS Classes#
Add custom CSS classes and attributes to elements.
Example:
md_in_html - Markdown Inside HTML#
Use markdown syntax inside HTML blocks.
CRITICAL: Must Add markdown Attribute
By default, markdown is NOT processed inside HTML block elements like <div>. You MUST add the markdown attribute to enable processing.
❌ WRONG - Markdown not processed:
✅ CORRECT - Add markdown attribute:
Requirements:
- Add
markdownattribute to the opening tag - Add blank line after opening tag
- Add blank line before closing tag
- Markdown content must be properly formatted
Example with Classes:
<div markdown class="feature-card custom-style">
## Feature Title
- Markdown list item
- Another item
</div>
Inline vs Block Markdown:
<!-- Block-level markdown (headings, lists, paragraphs) -->
<div markdown style="padding: 20px;">
## Heading
Paragraph with **bold** and *italic*.
</div>
<!-- Inline markdown only -->
<div markdown="span">This is **inline** markdown only.</div>
Real-world example:
<div markdown style="border: 2px solid #e5e7eb; border-radius: 8px; padding: 20px;">
# Plant Database
**Purpose:** Plant data model and storage
**Status:** Approved
</div>
pymdownx.emoji - Emoji Support#
Use emojis via shortcodes.
Examples: - :seedling: → 🌱 - :sunflower: → 🌻 - :cactus: → 🌵 - :herb: → 🌿 - :bouquet: → 💐 - :cherry_blossom: → 🌸
Search emojis: Emoji Cheat Sheet
Task List Extensions#
pymdownx.tasklist - Interactive Checkboxes#
Create task lists with checkboxes.
Example:
- [x] Choose planting location
- [x] Test soil pH
- [ ] Purchase seeds
- [ ] Plant seeds
- [ ] Water regularly
Renders as:
- Choose planting location
- Test soil pH
- Purchase seeds
- Plant seeds
- Water regularly
List Extensions#
def_list - Definition Lists#
Create glossary-style definition lists.
Example:
USDA Hardiness Zone
: A geographic area defined by average annual minimum temperature, used to determine which plants can survive in a location.
Full Sun
: 6 or more hours of direct sunlight per day.
Partial Shade
: 3-6 hours of direct sunlight per day.
Renders as:
- USDA Hardiness Zone
- A geographic area defined by average annual minimum temperature, used to determine which plants can survive in a location. (See abbreviations to see why USDA is special here.)
- Full Sun
- 6 or more hours of direct sunlight per day.
- Partial Shade
- 3-6 hours of direct sunlight per day.
Reference Extensions#
abbr - Abbreviations#
Define abbreviations with tooltips.
Example:
When you hover over "USDA", you'll see the full definition like in this line.
Should you decide to do this, remember it might be best to put them at the bottom. It is untested about if the last definition updates all or only the most recent. (If you have them all at the end, you can alphabetize to know what ones you do have.)
footnotes - Footnotes#
Add footnotes to content. (They will appear at the bottom of your document - just like gootnotes.)
Example:
Plants in zone 6a can survive temperatures down to -10°F[^1].
[^1]: USDA Plant Hardiness Zone Map, 2012 revision
Renders as:
Plants in zone 6a can survive temperatures down to -10°F1.
Typography Extensions#
pymdownx.smartsymbols - Smart Symbols#
Automatically converts text to proper symbols.
Conversions:
(c)→ ©(r)→ ®(tm)→ ™c/o→ ℅+/-→ ±-->→ →<--→ ←<-->→ ↔=/=→ ≠
pymdownx.keys - Keyboard Keys#
Display keyboard shortcuts beautifully.
Example:
Renders as:
Press Ctrl+Alt+Del to restart.
Review Extensions#
pymdownx.critic - Track Changes#
Mark up content for review with track-changes style markup.
Syntax:
This is {--deleted text--}.
This is {++added text++}.
This is {~~old~>new~~} text.
This is {==highlighted==} text.
{>>This is a comment<<}
Renders as:
This is deleted text.
This is added text.
This is oldnew text.
This is highlighted text.
This is a comment
Math Extensions#
pymdownx.arithmatex - Mathematical Expressions#
Write mathematical formulas using LaTeX syntax.
Inline Math:
Block Math:
Example - Growing Calculations:
Best Practices#
When to Use Each Extension#
Admonitions:
- Use
notefor general information - Use
warningfor important caveats - Use
tipfor helpful suggestions - Use
examplefor code demonstrations
Diagrams:
- Use flowcharts for process flows
- Use sequence diagrams for API interactions
- Use class diagrams for data models
- Use entity-relationship diagrams for database schemas
Tabs:
- Use for multiple implementations (web vs mobile)
- Use for different user roles (admin vs user)
- Use for multiple code examples (Python vs JavaScript)
Tables:
- Use for structured data (plant characteristics)
- Use for comparison (feature matrices)
- Keep tables simple - complex tables are hard to read on mobile
Accessibility Considerations#
- Always provide alt text for images:
-
Use semantic heading structure:
- Don't skip heading levels (h1 → h3)
- Use h1 only once per page
-
Make link text descriptive:
- ❌
[Click here](link)for more information - ✅
[Learn about USDA zones](link)for detailed information
- ❌
-
Use proper table headers:
Image Processing (Quick Reference)#
This documentation uses two plugins for optimal image handling.
Automatic Image Optimization#
All images are automatically compressed during build - no special syntax needed.
Just add images normally:
The optimize plugin automatically:
- Compresses PNG/JPG files (30-70% size reduction)
- Strips metadata
- Generates WebP versions
- Caches results for faster rebuilds
Click-to-Zoom Lightbox#
All images automatically get click-to-zoom functionality.
Basic usage (auto-enabled):
Click image to open lightbox. Use arrow keys or swipe to navigate.
Disable lightbox for specific images:
Keyboard shortcuts in lightbox:
←/→- Navigate galleryEsc- Close+/-- Zoom in/out
Installation & Configuration
For setup instructions, system dependencies, and troubleshooting, see: Image Processing Setup Guide
Custom Extensions (Project-Specific)#
Zone Badges#
Use custom CSS class for zone badges:
Status Badges#
Use for requirement/specification status:
<div class="status-badge draft">Draft</div>
<div class="status-badge review">In Review</div>
<div class="status-badge approved">Approved</div>
<div class="status-badge implemented">Implemented</div>
Feature Cards#
Use for highlighting features:
<div class="feature-card">
## Plant Search
Search thousands of plants by name, zone, characteristics, and more.
</div>
See more with the requirements index example.
Additional Resources#
- Material for MkDocs Reference
- PyMdown Extensions Documentation
- Python Markdown Documentation
- Mermaid Live Editor - Test diagrams
Need Help?#
If you're unsure which extension to use, refer to this decision tree:
flowchart TD
A["What do you need?"] --> B{"Content Type"}
B -->|"Diagram"| C["Use Mermaid"]
B -->|"Code"| D["Use highlight or superfences"]
B -->|"Important Info"| E["Use admonition"]
B -->|"Organize Options"| F["Use tabs"]
B -->|"Structured Data"| G["Use table"]
B -->|"Definition"| H["Use def_list"]
B -->|"Track Changes"| I["Use critic"] Maintained By: Gardening App Documentation Team
-
USDA Plant Hardiness Zone Map, 2012 revision ↩