A fast and complete Python implementation of Markdown with extensive extras support
—
Extensions for specialized content types including mathematical expressions, diagrams, interactive elements, alerts, and advanced formatting that extend markdown beyond standard text processing.
Support for LaTeX mathematical notation and expressions.
# latex extra - LaTeX math expression support
extras = ["latex"]Usage Examples:
import markdown2
# Requires latex2mathml package: pip install latex2mathml
math_text = '''
The quadratic formula is: $x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$
Block math equation:
$$
\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi}
$$
Matrix notation:
$$
\\begin{pmatrix}
a & b \\\\
c & d
\\end{pmatrix}
$$
'''
html = markdown2.markdown(math_text, extras=["latex"])
# Converts LaTeX to MathML for web displaySupport for various diagram types including Mermaid and WaveDrom.
# mermaid extra - Mermaid diagram support
extras = ["mermaid"]
# wavedrom extra - WaveDrom digital timing diagrams
extras = ["wavedrom"]
# With configuration
extras = {
"wavedrom": {
"config": {"theme": "default"}
}
}Usage Examples:
import markdown2
# Mermaid diagrams
mermaid_text = '''
```mermaid
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Action 1]
B -->|No| D[Action 2]
C --> E[End]
D --> EsequenceDiagram
participant A as Alice
participant B as Bob
A->>B: Hello Bob!
B->>A: Hello Alice!'''
html = markdown2.markdown(mermaid_text, extras=["mermaid", "fenced-code-blocks"])
wavedrom_text = '''
{
"signal": [
{"name": "clk", "wave": "p.....|..."},
{"name": "dat", "wave": "..2.3.|=.4", "data": ["head", "body", "tail"]},
{"name": "req", "wave": "0.1..0|1.0"}
]
}'''
html = markdown2.markdown(wavedrom_text, extras=["wavedrom", "fenced-code-blocks"])
### Alert and Admonition Systems
GitHub-style alerts and reStructuredText-style admonitions for highlighting important content.
```python { .api }
# alerts extra - GitHub-style alerts
extras = ["alerts"]
# admonitions extra - RST-style admonitions
extras = ["admonitions"]Usage Examples:
import markdown2
# GitHub-style alerts
alerts_text = '''
> [!NOTE]
> This is a note alert with important information.
> [!WARNING]
> This is a warning alert about potential issues.
> [!TIP]
> This is a tip alert with helpful suggestions.
> [!IMPORTANT]
> This is an important alert for critical information.
> [!CAUTION]
> This is a caution alert about dangerous operations.
'''
html = markdown2.markdown(alerts_text, extras=["alerts"])
# RST-style admonitions
admonitions_text = '''
!!! note "Optional Title"
This is a note admonition with an optional title.
It can contain multiple paragraphs and formatting.
!!! warning
This is a warning without a custom title.
!!! tip "Pro Tip"
Advanced users can configure this feature
for better performance.
'''
html = markdown2.markdown(admonitions_text, extras=["admonitions"])Support for spoilers, collapsible content, and special formatting.
# spoiler extra - Stack Overflow style spoiler blocks
extras = ["spoiler"]
# telegram-spoiler extra - Telegram-style spoiler text
extras = ["telegram-spoiler"]Usage Examples:
import markdown2
# Stack Overflow style spoilers
spoiler_text = '''
Here's a puzzle for you:
>! The answer is 42.
>!
>! This is the spoiler content that will be hidden
>! until the user clicks to reveal it.
Click to reveal the solution above.
'''
html = markdown2.markdown(spoiler_text, extras=["spoiler"])
# Telegram-style spoilers
telegram_text = '''
The movie ending is ||completely unexpected||.
The main character ||dies in the final scene||.
'''
html = markdown2.markdown(telegram_text, extras=["telegram-spoiler"])Sequential numbering system for figures, tables, equations, and other elements.
# numbering extra - generic counter support for sequential numbering
extras = ["numbering"]Usage Examples:
import markdown2
numbering_text = '''
See %Figure 1% for the architecture overview.
%Figure 1%: System Architecture

The equation %Equation 1% shows the relationship:
%Equation 1%: $E = mc^2$
Refer to %Table 1% for performance metrics:
%Table 1%: Performance Results
| Test | Result |
|------|--------|
| A | 95% |
| B | 87% |
'''
html = markdown2.markdown(numbering_text, extras=["numbering", "tables"])Combine mathematical and diagram extras for scientific documentation:
import markdown2
# Scientific paper processor
scientific_processor = markdown2.Markdown(
extras=[
"latex", # Mathematical expressions
"mermaid", # Flow charts and diagrams
"wavedrom", # Timing diagrams
"tables", # Data tables
"footnotes", # Citations
"numbering", # Figure/equation numbering
"header-ids", # Section references
"toc", # Table of contents
"admonitions" # Warnings and notes
]
)
scientific_document = '''
---
title: "Analysis of Quantum Computing Algorithms"
author: "Dr. Jane Smith"
---
# Introduction
This paper analyzes quantum algorithms with focus on Grover's algorithm.
!!! note "Prerequisites"
Readers should be familiar with linear algebra and quantum mechanics.
## Grover's Algorithm
The algorithm provides quadratic speedup: $O(\\sqrt{N})$ vs classical $O(N)$.
%Figure 1%: Algorithm Flow
```mermaid
graph TD
A[Initialize] --> B[Apply H gates]
B --> C[Oracle]
C --> D[Diffusion]
D --> E{Converged?}
E -->|No| C
E -->|Yes| F[Measure]The probability amplitude is given by: $$P = \sin^2\left((2k+1)\frac{\theta}{2}\right)$$
[!WARNING] Quantum decoherence can affect algorithm performance. '''
html = scientific_processor.convert(scientific_document)
### Documentation with Interactive Elements
Create rich documentation with alerts, spoilers, and diagrams:
```python
import markdown2
# Documentation processor with interactive elements
docs_processor = markdown2.Markdown(
extras=[
"alerts", # GitHub-style alerts
"admonitions", # RST-style admonitions
"spoiler", # Collapsible spoilers
"mermaid", # Diagrams
"fenced-code-blocks", # Code examples
"tables", # Reference tables
"header-ids", # Navigation
"toc" # Table of contents
]
)
interactive_docs = '''
# API Documentation
> [!IMPORTANT]
> This API requires authentication for all endpoints.
## Authentication Flow
```mermaid
sequenceDiagram
participant C as Client
participant A as Auth Server
participant R as Resource Server
C->>A: Request token
A->>C: Return token
C->>R: API call with token
R->>C: Return data!!! tip "Best Practice" Always store tokens securely and refresh them before expiration.
! The API key should never be exposed in client-side code. ! Use environment variables or secure key management systems.
[!WARNING] Rate limiting applies to all endpoints (100 requests/minute).
| Status Code | Meaning | Action |
|---|---|---|
| 200 | Success | Continue |
| 401 | Unauthorized | Check token |
| 429 | Rate Limited | Wait and retry |
| ''' |
html = docs_processor.convert(interactive_docs)
## Configuration Options
### LaTeX Configuration
Requires `latex2mathml` package and Python 3.8.1+:
```bash
pip install latex2mathmlRequires wavedrom package:
pip install wavedromwavedrom_config = {
"config": {
"theme": "default", # or "dark"
"width": 800,
"height": 400
}
}Works with fenced code blocks and can be rendered client-side:
<!-- Include Mermaid.js in your HTML -->
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>import markdown2
# Full-featured content processor
rich_processor = markdown2.Markdown(
extras={
# Math and diagrams
"latex": None,
"mermaid": None,
"wavedrom": None,
# Alerts and admonitions
"alerts": None,
"admonitions": None,
"spoiler": None,
# Structure and layout
"tables": None,
"footnotes": None,
"header-ids": None,
"toc": {"depth": 3},
"metadata": None,
# Code and syntax
"fenced-code-blocks": None,
"code-color": None,
# Text processing
"smarty-pants": None,
"break-on-newline": None
}
)
# Process rich content document
html = rich_processor.convert(rich_content_markdown)
# Access all features
if html.metadata:
print("Document metadata available")
if html.toc_html:
print("Table of contents generated")import markdown2
def process_user_content(content, allow_math=False, allow_diagrams=False):
"""Process user-generated content with configurable features."""
base_extras = [
"fenced-code-blocks",
"tables",
"header-ids",
"alerts",
"break-on-newline"
]
if allow_math:
base_extras.append("latex")
if allow_diagrams:
base_extras.extend(["mermaid", "wavedrom"])
processor = markdown2.Markdown(
extras=base_extras,
safe_mode="escape" # Security for user content
)
return processor.convert(content)
# Usage
user_post = process_user_content(user_markdown, allow_math=True)
admin_doc = process_user_content(admin_markdown, allow_math=True, allow_diagrams=True)Install with Tessl CLI
npx tessl i tessl/pypi-markdown2