Publish MkDocs Material pages to Confluence Cloud — admonitions, Mermaid diagrams, tabs, page properties and more
Project description
mk2conf — MkDocs / Zensical to Confluence
A Python CLI tool that compiles MkDocs-flavoured Markdown into native Confluence storage XHTML and publishes it directly to Confluence Cloud. It is a compiler/transpiler, not an HTML converter — every construct maps to its native Confluence equivalent, so pages look and behave like hand-authored Confluence content.
Zensical compatible — Zensical is the modern successor to MkDocs + Material for MkDocs. Since it uses the same
mkdocs.ymlformat and Python Markdown extensions, your Zensical project works with mk2conf today with no changes required.
Installation
Requires Python 3.12+. The PyPI package is mkdocs2confluence; the CLI command is mk2conf.
pip install mkdocs2confluence
# or, for an isolated install:
pipx install mkdocs2confluence
To use the mk2conf pdf subcommand, install the optional PDF extra:
pip install "mkdocs2confluence[pdf]"
WeasyPrint requires system libraries (Pango, Cairo) — install them for your platform:
| Platform | Command |
|---|---|
| macOS | brew install pango |
| Ubuntu / Debian | apt install libpango-1.0-0 libpangoft2-1.0-0 |
| Windows 11 | choco install gtk-runtime — or download the GTK3 runtime installer and add its bin\ folder to your PATH |
From source (see Setup.md):
git clone https://github.com/jeckyl2010/mkdocs2confluence.git
cd mkdocs2confluence && uv sync
Quick start
# Inspect the Confluence storage XHTML for a page
mk2conf preview --page index.md
# Open a live browser preview — rebuilds on every file save
mk2conf preview --page index.md --watch
mk2conf preview --section Guide --watch
# Dry-run: see what would be published without touching Confluence
mk2conf publish --dry-run
# Publish all nav pages to Confluence
mk2conf publish
# Export a nav section to a stand-alone PDF document
mk2conf pdf --section Guide --out guide.pdf
Configuration
Add a confluence: block to your mkdocs.yml:
confluence:
base_url: https://yourorg.atlassian.net
space_key: TECH
email: user@example.com
token: !ENV CONFLUENCE_API_TOKEN # never hardcode the token
parent_page_id: "123456" # optional root page
mermaid_render: kroki # "kroki" (default) | "kroki:https://your-kroki" | "none"
full_width: true # default: true
The API token is read from (in priority order):
token:inmkdocs.yml— typically via!ENV CONFLUENCE_API_TOKENCONFLUENCE_API_TOKENenvironment variableMK2CONF_TOKENenvironment variable
Your first publish
Once you have added the confluence: block (see above), this is all you need to get from zero to a live Confluence page:
# 1. Set your API token (add this to your shell profile or CI secrets)
export CONFLUENCE_API_TOKEN=your_api_token_here
# 2. Preview one page locally to verify the output before touching Confluence
mk2conf preview --page docs/index.md --watch
# 3. Dry-run to see exactly what would be created or updated
mk2conf publish --dry-run
# 4. Publish
mk2conf publish
That is it. mk2conf reads mkdocs.yml in the current directory, compiles every page listed in nav:, mirrors the hierarchy under parent_page_id, and skips any page that has not changed since the last run.
Commands
mk2conf preview
Compile and inspect output locally — no Confluence API calls. Mermaid diagrams are rendered via Kroki unless mermaid_render: none is set.
mk2conf preview [--config PATH] --page PATH [--out FILE] [--html] [--watch]
mk2conf preview [--config PATH] --section SECTION [--out FILE] [--watch]
| Flag | Default | Description |
|---|---|---|
--config PATH |
./mkdocs.yml |
Path to mkdocs.yml |
--page PATH |
(required unless --section) | Relative path to the Markdown file |
--section SECTION |
(none) | Nav section title to render, slash-separated for nested sections (e.g. Guide or Guide/Setup). Renders all pages in that subtree as a browseable HTML index. |
--out FILE |
stdout | Write output to a file or directory |
--html |
off | Render macros as styled browser-viewable HTML |
--watch |
off | Serve on http://localhost:8765 and auto-rebuild on file changes. Implies --html. Ctrl+C to stop. |
--html is for local review only — the actual Confluence storage XHTML is the --html-free output.
mk2conf publish
Compile all pages in nav: and publish to Confluence Cloud.
mk2conf publish [--config PATH] [--page PATH] [--section SECTION] [--dry-run] [--report FILE] [--prune]
| Flag | Default | Description |
|---|---|---|
--config PATH |
./mkdocs.yml |
Path to mkdocs.yml |
--page PATH |
(all nav pages) | Publish a single page only |
--section SECTION |
(whole nav) | Publish only a nav subtree, slash-separated for nested sections (e.g. Guide or Guide/Setup) |
--dry-run |
off | Print the publish plan; no Confluence API writes |
--report FILE |
(none) | Write a JSON publish report |
--prune |
off | Delete managed pages no longer in nav:. Only pages stamped by mk2conf are eligible — manually-created Confluence pages are never touched. Ignored on partial (--page / --section) runs. |
Publish behaviour
- Only
nav:pages are published — pages absent from the nav are never touched (natural draft gate). - Pages with
ready: falsein front matter are skipped, even if listed innav:. - Section nodes (nav groups without a page) become empty parent pages, mirroring the nav hierarchy.
- Local assets are uploaded as Confluence page attachments automatically.
- Unchanged pages are skipped — a
sha256hash of the compiled output is stored as a hidden page property; pages with identical content since the last run produce no version bump and no notification.
Mermaid rendering
mermaid_render |
Behaviour |
|---|---|
kroki (default) |
Render via https://kroki.io. PNGs cached in ~/.cache/mk2conf/mermaid/. |
kroki:https://your-kroki |
Render via a self-hosted Kroki instance. |
none |
Fall back to a code macro labelled mermaid. |
If Kroki is unreachable the run continues, falling back to the code macro for affected diagrams.
Styling from extra.css
If mkdocs.yml lists extra_css: files, mk2conf reads them and applies a whitelisted set of CSS properties as inline style="..." attributes on Confluence output.
| Selector | Applied to |
|---|---|
th, thead th |
Table header cells |
td |
Table body cells |
h1 – h6 |
Headings |
code (not pre code) |
Inline code spans |
Supported properties: background-color, color, font-weight, font-style, font-size, text-align, border. CSS custom properties (var(--name)) are resolved automatically, including chained variables and var(--name, fallback) syntax.
Complex Material theme overrides (compound selectors, color-mix(), @media, :has()) are silently skipped. For best results, maintain a small dedicated overrides file:
/* confluence-overrides.css */
:root { --primary: #d20014; }
th { background-color: var(--primary); color: white; font-weight: 600; }
h1, h2, h3 { color: var(--primary); }
code { background-color: #f5f5f5; }
extra_css:
- stylesheets/extra.css # full Material theme
- stylesheets/confluence-overrides.css # simple Confluence-targeted styles
mk2conf pdf
Export a nav section or single page to a stand-alone, printer-ready PDF document. Requires pip install "mkdocs2confluence[pdf]".
mk2conf pdf [--config PATH] (--section SECTION | --page PATH) [--out FILE] [--author TEXT] [--doc-version TEXT] [--quiet]
| Flag | Default | Description |
|---|---|---|
--config PATH |
./mkdocs.yml |
Path to mkdocs.yml |
--section SECTION |
(required unless --page) | Export a nav subtree by section title |
--page PATH |
(required unless --section) | Export a single page |
--out FILE |
<section-or-page>.pdf |
Output PDF path |
--author TEXT |
(none) | Author name printed on the cover page |
--doc-version TEXT |
(none) | Document version printed on the cover page |
--quiet |
off | Suppress progress output |
The PDF includes a cover page, table of contents with page numbers, and one chapter per nav page with automatic page breaks. Code blocks avoid mid-block splits; Mermaid diagrams appear as embedded PNGs (same Kroki-rendered images used for Confluence).
Supported Markdown features
Block elements
| Feature | Confluence output |
|---|---|
ATX headings # – ###### |
<h1> – <h6> |
| Paragraphs | <p> |
| Fenced code blocks | code macro with language, title, and line numbers |
| Bullet lists | <ul>/<li> |
| Ordered lists | <ol>/<li> |
Task lists - [x] / - [ ] |
Native <ac:task-list> / <ac:task> macros |
| Tables (GFM pipe syntax) | <table> with header and column alignment |
| Blockquotes | <blockquote> |
Horizontal rules --- |
<hr/> |
Inline elements
| Feature | Confluence output |
|---|---|
**bold** / __bold__ |
<strong> |
*italic* |
<em> |
~~strikethrough~~ |
<s> |
~subscript~ |
<sub> (pymdownx.tilde) |
^superscript^ |
<sup> (pymdownx.caret) |
^^inserted^^ |
<u> (pymdownx.caret insert) |
`inline code` |
<code> |
[text](url) |
<a href="..."> |
https://bare-url |
<a href="..."> (autolink) |
[text](file.pdf) |
<ac:link><ri:attachment .../> (uploaded as attachment) |
 |
<ac:image> with <ri:attachment> (local) or <ri:url> (remote) |
{ width="400" } |
<ac:image ac:width="400"> — also supports height and align |
<br> / <br/> / trailing \ |
<br /> |
<sub> / <sup> / <u> / <small> |
Direct XHTML passthrough |
<mark>text</mark> |
<span style="background-color: yellow;"> |
<kbd>text</kbd> |
<code> |
++ctrl+alt+del++ |
<code>Ctrl</code>+<code>Alt</code>+<code>Del</code> (pymdownx.keys) |
<s>text</s> / <del>text</del> |
<span style="text-decoration: line-through;"> |
MkDocs / Material extensions
| Feature | Confluence output |
|---|---|
--8<-- file includes |
Resolved before parsing |
Admonitions !!! type "title" |
info / tip / warning / note macro |
Danger admonitions (danger, error, bug) |
Red panel macro with 🚨 prefix |
Collapsible admonitions ??? type |
expand macro |
Content tabs === "Label" |
expand macros (one per tab) |
Details blocks ??? "title" |
expand macro |
Footnotes [^1] |
Superscript anchor links + Footnotes section at page bottom |
| Mermaid diagrams | PNG via Kroki, uploaded as attachment (<ac:image ac:align="center">) |
Internal links [text](page.md) |
Native Confluence page link; #fragment anchors preserved |
awesome-pages nav (.pages files) |
Fully supported |
| Edit link banner | info macro linking back to source in GitHub/GitLab |
Grid cards <div class="grid cards" markdown> |
Native ac:layout multi-column sections (auto-detects 1/2/3 columns from card count) |
YAML front matter → Page Properties
A YAML front matter block is converted to a Confluence Page Properties macro, making it queryable via the Page Properties Report macro.
---
title: "Architecture Proposal – IAM"
subtitle: "Hybrid Identity Hub"
documentId: AP-IAM-2026
version: "0.1"
lastUpdated: 2026-01-12
author: "Anders Hybertz"
tags: [architecture, iam]
ready: true
status: in-progress
---
| Field | Notes |
|---|---|
title |
Used as the Confluence page title on publish |
subtitle |
Rendered as italic lead paragraph above the properties table |
tags |
Also applied as Confluence page labels |
ready |
true → ✅ Ready · false → 📝 Draft (skips publish) |
status |
Sets the Confluence page status badge — common values: rough-draft, in-progress, ready-for-review (space-specific values are also supported). Not shown in the properties table. |
| other fields | Title-cased key, value stringified |
If repo_url + edit_uri are set in mkdocs.yml, an Edit Source row links to the source file. If site_url is set, a Published Page row links to the rendered MkDocs site.
Abbreviation expansion
MkDocs abbreviation definitions (*[ABBR]: Full term) are rendered as inline superscript anchor links. The first occurrence of each abbreviation in body text gets a superscript number (API¹) that links to a numbered glossary appended at the bottom of the page. Subsequent occurrences are left as plain text. Abbreviations that only appear in headings or other non-expandable contexts are included in the glossary as plain numbered entries (no inline back-link). Uses only native Confluence storage format — no plugins required.
Known limitations
| Feature | Behaviour |
|---|---|
| Admonition styling | tip, info, warning, note use Confluence's fixed native macro colours. danger, error, bug use a custom red panel macro with 🚨 prefix. All other types are mapped to the nearest native macro. |
| Abbreviation tooltips | No native tooltip support. First occurrence gets a superscript anchor link (API¹); all definitions collected in a numbered glossary at the bottom of the page. No plugins required. |
| Page ordering | Confluence sorts child pages alphabetically; the v2 REST API has no write endpoint for ordering. |
| Code language aliases | Short aliases (py, js, yml, ts, sh) are passed through as-is; Confluence requires full language names for syntax highlighting. |
| Unrecognised blocks | Preserved as a visible warning macro — no content is silently lost. |
Architecture
Each stage is a separate Python module under src/mkdocs_to_confluence/. The plan phase makes all API read calls (find existing pages); the execute phase makes all write calls, ensuring parent pages always exist before their children.
Development
See Setup.md for environment setup.
uv run pytest -q # run tests
uv run ruff check src tests # lint
uv run vulture src --min-confidence 80 # dead code check
uv run mypy src # type-check
uv run bandit -r src -ll # security scan
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mkdocs2confluence-0.7.31.tar.gz.
File metadata
- Download URL: mkdocs2confluence-0.7.31.tar.gz
- Upload date:
- Size: 171.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ce11cc8104de228d3d3caf3caaf41cacbe97a6ca8e80975fe73e84fb5a0ba8e
|
|
| MD5 |
ab624b4469914ec6a8a61c67903d6bd4
|
|
| BLAKE2b-256 |
098c49429369437aaa75d5a1d070f28521d29ed616c135f9c31bfc6f3b5272b2
|
File details
Details for the file mkdocs2confluence-0.7.31-py3-none-any.whl.
File metadata
- Download URL: mkdocs2confluence-0.7.31-py3-none-any.whl
- Upload date:
- Size: 117.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a57f9876bdc9d29c29dfed5675cd2a7be59cdd94bc8eae80e109335137626f0e
|
|
| MD5 |
108aaf060cedbe3347c4c0f0da285c03
|
|
| BLAKE2b-256 |
39ffe4a75eb590710c6b8d45359c65dcc5a21b0bf8af09febd9911da89ae968b
|