Skip to main content

Fast Markdown to HTML renderer - GFM tables, code highlighting, XSS-safe, extensible

Project description

markdown-fast-py

Fast Markdown to HTML renderer — GFM tables, syntax highlighting, XSS-safe, extensible.

Pure Python. Zero dependencies. Production-ready.

Install

pip install markdown-fast-py

Quick Start

import markdown_fast_py as md

html = md.convert("# Hello\n\nThis is **bold** and _italic_.")
print(html)
# <h1 id="hello">Hello</h1>
# <p>This is <strong>bold</strong> and <em>italic</em>.</p>

Features

  • CommonMark-compatible block and inline parsing
  • GFM tables with per-column alignment
  • Syntax highlighting for 15+ languages — pure Python, no external deps
  • XSS sanitization — allowlist-based, strips event handlers and javascript: URIs
  • Task lists (- [x] done / - [ ] todo)
  • Strikethrough (~~text~~)
  • Autolinks (bare URLs and <angle-bracket> style)
  • Setext and ATX headings with automatic slug id attributes
  • Blockquotes, fenced and indented code blocks
  • Ordered and unordered lists with nesting
  • Hard line breaks ( \n)
  • Reference-style links and images
  • Extension system: footnotes, math, anchors, TOC, definition lists
  • Command-line tool (markdown-fast)

Usage

One-shot conversion

from markdown_fast_py import convert

html = convert(source)

Reusable instance

from markdown_fast_py import Markdown

md = Markdown(
    highlight_code=True,   # syntax-highlight fenced code blocks
    sanitize=True,         # strip dangerous HTML (XSS-safe)
    heading_ids=True,      # add id="slug" to headings
    safe_links=True,       # block javascript: URLs
    breaks=False,          # treat single newline as <br>
    xhtml=False,           # emit XHTML-style void elements
    table_class="",        # optional CSS class on <table>
    extensions=[],         # see Extensions section
)

html = md.render(source)
# or equivalently:
html = md.convert(source)
html = md(source)          # callable

API reference

convert(text, **options) -> str

One-shot Markdown-to-HTML conversion.

Parameter Type Default Description
text str Markdown source
highlight_code bool True Syntax-highlight fenced code blocks
sanitize bool True XSS-sanitize the output
heading_ids bool True Add id attributes to headings
safe_links bool True Block javascript: / data: hrefs
breaks bool False Newlines become <br>
xhtml bool False Self-closing void elements
smart_quotes bool False Curly quotes
table_class str "" CSS class on <table>
extensions list [] Extensions to enable

sanitize(html) -> str

Standalone XSS sanitizer — works on HTML from any source.

from markdown_fast_py import sanitize

clean = sanitize('<a href="javascript:alert(1)">click</a>')
# <a href="#">click</a>

highlight(code, language) -> str

Standalone syntax highlighter returning HTML with hl-* CSS classes.

from markdown_fast_py import highlight

html = highlight("def foo(): pass", "python")

parse(text) -> Node

Low-level AST parser. Returns a Node tree you can traverse or transform.

from markdown_fast_py import parse, NodeType

doc = parse("# Hello\n\n- item")
for child in doc.children:
    print(child.type, child.level if child.type == NodeType.HEADING else "")

Syntax Highlighting

Fenced code blocks are highlighted when a language tag is provided:

```python
def hello(name: str) -> str:
    return f"Hello, {name}!"
```

Supported languages

Language Tags
Python python, py
JavaScript javascript, js, jsx
TypeScript typescript, ts, tsx
HTML/XML html, xml
CSS/SCSS css, scss, sass
JSON json
SQL sql
Bash/Shell bash, sh, shell, zsh
Go go, golang
Rust rust, rs
YAML yaml, yml
Diff diff, patch

The highlighter emits <span class="hl-*"> markup. Include the bundled theme or write your own CSS:

from markdown_fast_py import CSS_THEME_DARK, CSS_THEME_LIGHT

# Embed in a <style> tag:
print(f"<style>{CSS_THEME_DARK}</style>")

XSS Sanitization

The sanitizer uses a strict allowlist of safe tags and attributes. Event handlers (onclick, onload, …), <script>, <iframe>, and javascript: / data: URIs are stripped automatically.

dangerous = '<p onclick="steal()">Hi <script>alert(1)</script></p>'
safe = convert(dangerous)
# <p>Hi </p>

Extensions

Enable built-in extensions by name or instance:

md = Markdown(extensions=["footnotes", "anchors", "toc"])

Available extensions

Name Class Description
footnotes FootnotesExtension [^1] references and definitions
math MathExtension $inline$ and $$block$$ pass-through for MathJax/KaTeX
anchors AnchorExtension Self-link ¶ on every heading
toc TableOfContentsExtension Replace [TOC] with a nested <nav>
deflist DefinitionListExtension term\n: definition<dl>

Custom extensions

from markdown_fast_py import Extension, Markdown

class MyExtension(Extension):
    name = "mine"

    def preprocess(self, text: str) -> str:
        return text.replace(":rocket:", "🚀")

    def postprocess_html(self, html: str) -> str:
        return html.replace("TODO", '<mark>TODO</mark>')

md = Markdown(extensions=[MyExtension()])

GFM Tables

| Name    | Age | City      |
|---------|:---:|----------:|
| Alice   | 30  | New York  |
| Bob     | 25  | London    |

Column alignment: :--- left, ---: right, :---: centre.

Command Line

# Convert from stdin
echo "# Hello" | markdown-fast

# Convert a file
markdown-fast README.md

# Output a full HTML page with dark theme
markdown-fast --page --theme dark --title "Docs" README.md > docs.html

# Disable highlighting and sanitization
markdown-fast --no-highlight --no-sanitize input.md

# Enable extensions
markdown-fast --extensions anchors toc footnotes README.md
usage: markdown-fast [-h] [-o FILE] [--no-highlight] [--no-sanitize]
                     [--no-heading-ids] [--breaks] [--xhtml]
                     [--page] [--title TITLE] [--theme {dark,light,none}]
                     [--extensions [EXT ...]] [--version]
                     [FILE]

License

MIT © Vladyslav Zaiets

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

markdown_fast_py-1.0.0.tar.gz (25.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markdown_fast_py-1.0.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file markdown_fast_py-1.0.0.tar.gz.

File metadata

  • Download URL: markdown_fast_py-1.0.0.tar.gz
  • Upload date:
  • Size: 25.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for markdown_fast_py-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c1100823ffdd3afaeb3f629fd263e991c7afe2b1061a4ea53d82d0a6b8d6cc02
MD5 21f435f7b495c4d9f8fd95ed6369a9b7
BLAKE2b-256 a76bac6fac1e2c23f10ae914211a10c6dd62388e897bae8546a3faba5d41a6ce

See more details on using hashes here.

File details

Details for the file markdown_fast_py-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for markdown_fast_py-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e9e50dd0338b9ed4696432fbbe00264b9aa649dddd316ad3bf606a8e80f88d1
MD5 602932ce3ceaa3e98d381116ff8af66a
BLAKE2b-256 f51b366a8821ed66a31fbc0fbd46d6a4fa9c01fc96410b5096ad16d852b93178

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page