mkdocs2confluence 0.6.9__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mkdocs2confluence-0.6.9/src/mkdocs2confluence.egg-info → mkdocs2confluence-0.7.0}/PKG-INFO +142 -105
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/README.md +139 -104
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/pyproject.toml +8 -1
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0/src/mkdocs2confluence.egg-info}/PKG-INFO +142 -105
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs2confluence.egg-info/SOURCES.txt +5 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs2confluence.egg-info/requires.txt +3 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/cli.py +138 -0
- mkdocs2confluence-0.7.0/src/mkdocs_to_confluence/pdf/__init__.py +1 -0
- mkdocs2confluence-0.7.0/src/mkdocs_to_confluence/pdf/generator.py +33 -0
- mkdocs2confluence-0.7.0/src/mkdocs_to_confluence/pdf/render.py +276 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preview/server.py +1 -1
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_cli.py +20 -0
- mkdocs2confluence-0.7.0/tests/test_pdf.py +201 -0
- mkdocs2confluence-0.7.0/tests/test_server.py +247 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/LICENSE +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/setup.cfg +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs2confluence.egg-info/dependency_links.txt +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs2confluence.egg-info/entry_points.txt +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs2confluence.egg-info/top_level.txt +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/emitter/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/emitter/xhtml.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/ir/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/ir/document.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/ir/nodes.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/ir/treeutil.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/loader/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/loader/config.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/loader/extra_css.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/loader/nav.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/loader/page.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/parser/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/parser/markdown.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/abbrevs.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/fence.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/frontmatter.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/icons.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/includes.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preprocess/linkdefs.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preview/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/preview/render.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/publisher/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/publisher/client.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/publisher/pipeline.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/__init__.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/abbrevs.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/assets.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/editlink.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/images.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/internallinks.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/src/mkdocs_to_confluence/transforms/mermaid.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_abbrevs.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_editlink.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_emitter.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_extra_css.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_frontmatter.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_icons.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_images.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_internallinks.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_ir.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_linkdefs.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_loader.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_mermaid.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_page_loader.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_parser.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_preprocess.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_preview.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_publish_client.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_publish_config.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_publish_pipeline.py +0 -0
- {mkdocs2confluence-0.6.9 → mkdocs2confluence-0.7.0}/tests/test_treeutil.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs2confluence
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Publish MkDocs Material pages to Confluence Cloud — admonitions, Mermaid diagrams, tabs, page properties and more
|
|
5
5
|
Author: Anders Hybertz
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -26,6 +26,8 @@ License-File: LICENSE
|
|
|
26
26
|
Requires-Dist: PyYAML>=6.0.3
|
|
27
27
|
Requires-Dist: httpx>=0.27
|
|
28
28
|
Requires-Dist: tinycss2>=1.5.1
|
|
29
|
+
Provides-Extra: pdf
|
|
30
|
+
Requires-Dist: weasyprint>=60.0; extra == "pdf"
|
|
29
31
|
Provides-Extra: dev
|
|
30
32
|
Requires-Dist: pytest; extra == "dev"
|
|
31
33
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -50,160 +52,171 @@ Dynamic: license-file
|
|
|
50
52
|
[](https://mypy-lang.org/)
|
|
51
53
|
[](https://github.com/PyCQA/bandit)
|
|
52
54
|
|
|
53
|
-
A Python CLI tool that compiles MkDocs-flavoured Markdown into native Confluence storage XHTML and publishes it to Confluence.
|
|
55
|
+
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.
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
> **Zensical compatible** — [Zensical](https://zensical.org/) is the modern successor to MkDocs + Material for MkDocs, built by the same team. Since Zensical uses the same `mkdocs.yml` format and Python Markdown extensions, your Zensical project works with this tool today — no changes required.
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Architecture
|
|
62
|
-
|
|
63
|
-

|
|
64
|
-
|
|
65
|
-
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 parents always exist before children.
|
|
57
|
+
> **Zensical compatible** — [Zensical](https://zensical.org/) is the modern successor to MkDocs + Material for MkDocs. Since it uses the same `mkdocs.yml` format and Python Markdown extensions, your Zensical project works with mk2conf today with no changes required.
|
|
66
58
|
|
|
67
59
|
---
|
|
68
60
|
|
|
69
61
|
## Installation
|
|
70
62
|
|
|
71
|
-
Requires Python 3.12+.
|
|
72
|
-
|
|
73
|
-
**From PyPI:**
|
|
63
|
+
Requires Python 3.12+. The PyPI package is `mkdocs2confluence`; the CLI command is `mk2conf`.
|
|
74
64
|
|
|
75
65
|
```bash
|
|
76
66
|
pip install mkdocs2confluence
|
|
67
|
+
# or, for an isolated install:
|
|
68
|
+
pipx install mkdocs2confluence
|
|
77
69
|
```
|
|
78
70
|
|
|
79
|
-
|
|
71
|
+
To use the `mk2conf pdf` subcommand, install the optional PDF extra:
|
|
80
72
|
|
|
81
73
|
```bash
|
|
82
|
-
|
|
74
|
+
pip install "mkdocs2confluence[pdf]"
|
|
83
75
|
```
|
|
84
76
|
|
|
77
|
+
> **macOS only**: WeasyPrint requires Pango for font rendering:
|
|
78
|
+
> ```bash
|
|
79
|
+
> brew install pango
|
|
80
|
+
> ```
|
|
81
|
+
|
|
85
82
|
**From source** (see [Setup.md](Setup.md)):
|
|
86
83
|
|
|
87
84
|
```bash
|
|
88
85
|
git clone https://github.com/jeckyl2010/mkdocs2confluence.git
|
|
89
|
-
cd mkdocs2confluence
|
|
90
|
-
pip install -e ".[dev]"
|
|
86
|
+
cd mkdocs2confluence && uv sync
|
|
91
87
|
```
|
|
92
88
|
|
|
93
|
-
> **Package name vs. command name** — This follows the same convention used by many popular CLI tools (e.g. `pip install httpie` → `http` command). The PyPI package is `mkdocs2confluence` (descriptive, easy to find), and the CLI command is `mk2conf` (short, fast to type). Install once, run everywhere as `mk2conf`.
|
|
94
|
-
|
|
95
89
|
---
|
|
96
90
|
|
|
97
91
|
## Quick start
|
|
98
92
|
|
|
99
93
|
```bash
|
|
100
|
-
#
|
|
101
|
-
mk2conf preview --
|
|
94
|
+
# Inspect the Confluence storage XHTML for a page
|
|
95
|
+
mk2conf preview --page index.md
|
|
102
96
|
|
|
103
|
-
# Open a browser
|
|
104
|
-
mk2conf preview --
|
|
97
|
+
# Open a live browser preview — rebuilds on every file save
|
|
98
|
+
mk2conf preview --page index.md --watch
|
|
99
|
+
mk2conf preview --section Guide --watch
|
|
105
100
|
|
|
106
101
|
# Dry-run: see what would be published without touching Confluence
|
|
107
|
-
mk2conf publish --
|
|
102
|
+
mk2conf publish --dry-run
|
|
108
103
|
|
|
109
104
|
# Publish all nav pages to Confluence
|
|
110
|
-
|
|
105
|
+
mk2conf publish
|
|
106
|
+
|
|
107
|
+
# Export a nav section to a stand-alone PDF document
|
|
108
|
+
mk2conf pdf --section Guide --out guide.pdf
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Configuration
|
|
114
|
+
|
|
115
|
+
Add a `confluence:` block to your `mkdocs.yml`:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
confluence:
|
|
119
|
+
base_url: https://yourorg.atlassian.net
|
|
120
|
+
space_key: TECH
|
|
121
|
+
email: user@example.com
|
|
122
|
+
token: !ENV CONFLUENCE_API_TOKEN # never hardcode the token
|
|
123
|
+
parent_page_id: "123456" # optional root page
|
|
124
|
+
mermaid_render: kroki # "kroki" (default) | "kroki:https://your-kroki" | "none"
|
|
125
|
+
full_width: true # default: true
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The API token is read from (in priority order):
|
|
129
|
+
|
|
130
|
+
1. `token:` in `mkdocs.yml` — typically via `!ENV CONFLUENCE_API_TOKEN`
|
|
131
|
+
2. `CONFLUENCE_API_TOKEN` environment variable
|
|
132
|
+
3. `MK2CONF_TOKEN` environment variable
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Your first publish
|
|
137
|
+
|
|
138
|
+
Once you have added the `confluence:` block (see above), this is all you need to get from zero to a live Confluence page:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# 1. Set your API token (add this to your shell profile or CI secrets)
|
|
142
|
+
export CONFLUENCE_API_TOKEN=your_api_token_here
|
|
143
|
+
|
|
144
|
+
# 2. Preview one page locally to verify the output before touching Confluence
|
|
145
|
+
mk2conf preview --page docs/index.md --watch
|
|
146
|
+
|
|
147
|
+
# 3. Dry-run to see exactly what would be created or updated
|
|
148
|
+
mk2conf publish --dry-run
|
|
149
|
+
|
|
150
|
+
# 4. Publish
|
|
151
|
+
mk2conf publish
|
|
111
152
|
```
|
|
112
153
|
|
|
154
|
+
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.
|
|
155
|
+
|
|
113
156
|
---
|
|
114
157
|
|
|
115
158
|
## Commands
|
|
116
159
|
|
|
117
160
|
### `mk2conf preview`
|
|
118
161
|
|
|
119
|
-
Compile
|
|
162
|
+
Compile and inspect output locally — no Confluence API calls. Mermaid diagrams are rendered via Kroki unless `mermaid_render: none` is set.
|
|
120
163
|
|
|
121
164
|
```
|
|
122
|
-
mk2conf preview [--config PATH] --page PATH [--out FILE] [--html]
|
|
165
|
+
mk2conf preview [--config PATH] --page PATH [--out FILE] [--html] [--watch]
|
|
166
|
+
mk2conf preview [--config PATH] --section SECTION [--out FILE] [--watch]
|
|
123
167
|
```
|
|
124
168
|
|
|
125
169
|
| Flag | Default | Description |
|
|
126
170
|
|---|---|---|
|
|
127
|
-
| `--config PATH` | `./mkdocs.yml` | Path to
|
|
128
|
-
| `--page PATH` | *(required)* | Relative path to the Markdown file |
|
|
129
|
-
| `--
|
|
130
|
-
| `--
|
|
171
|
+
| `--config PATH` | `./mkdocs.yml` | Path to `mkdocs.yml` |
|
|
172
|
+
| `--page PATH` | *(required unless --section)* | Relative path to the Markdown file |
|
|
173
|
+
| `--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. |
|
|
174
|
+
| `--out FILE` | stdout | Write output to a file or directory |
|
|
175
|
+
| `--html` | off | Render macros as styled browser-viewable HTML |
|
|
176
|
+
| `--watch` | off | Serve on `http://localhost:8765` and auto-rebuild on file changes. Implies `--html`. `Ctrl+C` to stop. |
|
|
131
177
|
|
|
132
|
-
|
|
178
|
+
`--html` is for local review only — the actual Confluence storage XHTML is the `--html`-free output.
|
|
133
179
|
|
|
134
180
|
---
|
|
135
181
|
|
|
136
182
|
### `mk2conf publish`
|
|
137
183
|
|
|
138
|
-
Compile all pages
|
|
184
|
+
Compile all pages in `nav:` and publish to Confluence Cloud.
|
|
139
185
|
|
|
140
186
|
```
|
|
141
|
-
mk2conf publish [--config PATH] [--page PATH] [--section
|
|
187
|
+
mk2conf publish [--config PATH] [--page PATH] [--section SECTION] [--dry-run] [--report FILE] [--prune]
|
|
142
188
|
```
|
|
143
189
|
|
|
144
190
|
| Flag | Default | Description |
|
|
145
191
|
|---|---|---|
|
|
146
|
-
| `--config PATH` | `./mkdocs.yml` | Path to
|
|
192
|
+
| `--config PATH` | `./mkdocs.yml` | Path to `mkdocs.yml` |
|
|
147
193
|
| `--page PATH` | *(all nav pages)* | Publish a single page only |
|
|
148
|
-
| `--section
|
|
149
|
-
| `--dry-run` | off | Print the publish plan
|
|
150
|
-
| `--report FILE` | *(none)* | Write a JSON publish report
|
|
151
|
-
| `--prune` | off | Delete managed
|
|
194
|
+
| `--section SECTION` | *(whole nav)* | Publish only a nav subtree, slash-separated for nested sections (e.g. `Guide` or `Guide/Setup`) |
|
|
195
|
+
| `--dry-run` | off | Print the publish plan; no Confluence API writes |
|
|
196
|
+
| `--report FILE` | *(none)* | Write a JSON publish report |
|
|
197
|
+
| `--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. |
|
|
152
198
|
|
|
153
|
-
####
|
|
199
|
+
#### Publish behaviour
|
|
154
200
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
space_key: TECH
|
|
161
|
-
email: user@example.com
|
|
162
|
-
token: !ENV CONFLUENCE_API_TOKEN # never hardcode the token
|
|
163
|
-
parent_page_id: "123456" # optional root page
|
|
164
|
-
mermaid_render: kroki # optional: "kroki" (default), "kroki:https://your-kroki" or "none"
|
|
165
|
-
full_width: true # optional: publish pages in full-width layout (default: true)
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
The API token is read from (in priority order):
|
|
169
|
-
1. The `token:` field in `mkdocs.yml` (typically via `!ENV CONFLUENCE_API_TOKEN`)
|
|
170
|
-
2. `CONFLUENCE_API_TOKEN` environment variable
|
|
171
|
-
3. `MK2CONF_TOKEN` environment variable
|
|
172
|
-
|
|
173
|
-
#### Publish rules
|
|
174
|
-
|
|
175
|
-
- **Only pages in `nav:` are published** — the nav is the publish gate. Pages not listed in the nav are never touched, keeping drafts and WIP content private.
|
|
176
|
-
- Pages with `ready: false` in their YAML front matter are **skipped**, even if listed in the nav.
|
|
177
|
-
- Section nodes (nav groups without a page) become empty parent pages in Confluence, mirroring the nav hierarchy.
|
|
178
|
-
- All locally linked assets are uploaded as Confluence page attachments automatically.
|
|
179
|
-
- **Smart update detection** — before calling the Confluence update API, mk2conf compares a `sha256` hash of the compiled output against the hash stored from the previous run (kept as a hidden Confluence page property `mk2conf-content-hash`). Pages whose content has not changed are skipped entirely — no version bump, no watcher notification. As a side effect, Confluence's built-in version history becomes a meaningful audit trail: every version represents a real content change, each stamped *"Updated by mk2conf"* so automated publishes are clearly distinguishable from manual edits. You can diff any two versions directly inside Confluence, with inline highlighting showing exactly which paragraphs, headings, or code blocks changed.
|
|
180
|
-
- **Orphan pruning** — every page created by mk2conf is stamped with a hidden `mk2conf-managed` property. Pass `--prune` to automatically delete managed pages that have been removed from `nav:`. Manually-created Confluence pages are never deleted.
|
|
181
|
-
|
|
182
|
-
#### Orphan pruning
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
mk2conf publish --prune
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
After each publish run, `--prune` fetches all descendants of the configured `parent_page_id`, diffs them against the pages just published, and deletes any managed orphans — i.e. pages that carry the `mk2conf-managed` stamp but are no longer in the MkDocs nav.
|
|
189
|
-
|
|
190
|
-
> **Safety:** Only pages stamped by mk2conf are eligible for deletion. Any page created directly in Confluence will never be touched, even if it sits inside the managed hierarchy.
|
|
191
|
-
>
|
|
192
|
-
> **Partial runs:** `--prune` is silently ignored when `--page` or `--section` is used, because a partial publish would only cover a subset of the nav and would incorrectly identify out-of-scope pages as orphans.
|
|
201
|
+
- **Only `nav:` pages are published** — pages absent from the nav are never touched (natural draft gate).
|
|
202
|
+
- Pages with `ready: false` in front matter are skipped, even if listed in `nav:`.
|
|
203
|
+
- Section nodes (nav groups without a page) become empty parent pages, mirroring the nav hierarchy.
|
|
204
|
+
- Local assets are uploaded as Confluence page attachments automatically.
|
|
205
|
+
- **Unchanged pages are skipped** — a `sha256` hash 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.
|
|
193
206
|
|
|
194
207
|
#### Mermaid rendering
|
|
195
208
|
|
|
196
|
-
| `mermaid_render`
|
|
209
|
+
| `mermaid_render` | Behaviour |
|
|
197
210
|
|---|---|
|
|
198
|
-
| `kroki` *(default)* | Render via `https://kroki.io`. PNGs
|
|
211
|
+
| `kroki` *(default)* | Render via `https://kroki.io`. PNGs cached in `~/.cache/mk2conf/mermaid/`. |
|
|
199
212
|
| `kroki:https://your-kroki` | Render via a self-hosted Kroki instance. |
|
|
200
|
-
| `none` |
|
|
213
|
+
| `none` | Fall back to a `code` macro labelled `mermaid`. |
|
|
201
214
|
|
|
202
215
|
If Kroki is unreachable the run continues, falling back to the `code` macro for affected diagrams.
|
|
203
216
|
|
|
204
217
|
#### Styling from extra.css
|
|
205
218
|
|
|
206
|
-
If
|
|
219
|
+
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.
|
|
207
220
|
|
|
208
221
|
| Selector | Applied to |
|
|
209
222
|
|---|---|
|
|
@@ -212,11 +225,9 @@ If your `mkdocs.yml` has an `extra_css:` list, mk2conf reads those files and app
|
|
|
212
225
|
| `h1` – `h6` | Headings |
|
|
213
226
|
| `code` (not `pre code`) | Inline code spans |
|
|
214
227
|
|
|
215
|
-
Supported properties: `background-color`, `color`, `font-weight`, `font-style`, `font-size`, `text-align`, `border`.
|
|
228
|
+
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.
|
|
216
229
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
**Works best with simple, flat CSS.** Complex Material for MkDocs theme overrides — compound selectors (`.md-typeset table:not([class]) thead th`), `color-mix()`, `@media` blocks, `:has()` etc. — are silently skipped. For these, maintain a small separate file:
|
|
230
|
+
Complex Material theme overrides (compound selectors, `color-mix()`, `@media`, `:has()`) are silently skipped. For best results, maintain a small dedicated overrides file:
|
|
220
231
|
|
|
221
232
|
```css
|
|
222
233
|
/* confluence-overrides.css */
|
|
@@ -228,12 +239,34 @@ code { background-color: #f5f5f5; }
|
|
|
228
239
|
|
|
229
240
|
```yaml
|
|
230
241
|
extra_css:
|
|
231
|
-
- stylesheets/extra.css
|
|
232
|
-
- stylesheets/confluence-overrides.css
|
|
242
|
+
- stylesheets/extra.css # full Material theme
|
|
243
|
+
- stylesheets/confluence-overrides.css # simple Confluence-targeted styles
|
|
233
244
|
```
|
|
234
245
|
|
|
235
246
|
---
|
|
236
247
|
|
|
248
|
+
### `mk2conf pdf`
|
|
249
|
+
|
|
250
|
+
Export a nav section or single page to a stand-alone, printer-ready PDF document. Requires `pip install "mkdocs2confluence[pdf]"`.
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
mk2conf pdf [--config PATH] (--section SECTION | --page PATH) [--out FILE] [--author TEXT] [--doc-version TEXT] [--quiet]
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
| Flag | Default | Description |
|
|
257
|
+
|---|---|---|
|
|
258
|
+
| `--config PATH` | `./mkdocs.yml` | Path to `mkdocs.yml` |
|
|
259
|
+
| `--section SECTION` | *(required unless --page)* | Export a nav subtree by section title |
|
|
260
|
+
| `--page PATH` | *(required unless --section)* | Export a single page |
|
|
261
|
+
| `--out FILE` | `<section-or-page>.pdf` | Output PDF path |
|
|
262
|
+
| `--author TEXT` | *(none)* | Author name printed on the cover page |
|
|
263
|
+
| `--doc-version TEXT` | *(none)* | Document version printed on the cover page |
|
|
264
|
+
| `--quiet` | off | Suppress progress output |
|
|
265
|
+
|
|
266
|
+
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).
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
237
270
|
## Supported Markdown features
|
|
238
271
|
|
|
239
272
|
### Block elements
|
|
@@ -288,7 +321,7 @@ extra_css:
|
|
|
288
321
|
| Internal links `[text](page.md)` | Native Confluence page link; `#fragment` anchors preserved |
|
|
289
322
|
| `awesome-pages` nav (`.pages` files) | Fully supported |
|
|
290
323
|
| Edit link banner | `info` macro linking back to source in GitHub/GitLab |
|
|
291
|
-
| Grid cards `<div class="grid cards" markdown>` | Native `ac:layout` multi-column sections (auto-detects 1/2/3 columns from card count)
|
|
324
|
+
| Grid cards `<div class="grid cards" markdown>` | Native `ac:layout` multi-column sections (auto-detects 1/2/3 columns from card count) |
|
|
292
325
|
|
|
293
326
|
### YAML front matter → Page Properties
|
|
294
327
|
|
|
@@ -313,7 +346,6 @@ ready: true
|
|
|
313
346
|
| `subtitle` | Rendered as italic lead paragraph above the properties table |
|
|
314
347
|
| `tags` | Also applied as Confluence page labels |
|
|
315
348
|
| `ready` | `true` → ✅ Ready · `false` → 📝 Draft (skips publish) |
|
|
316
|
-
| `source` | Stripped (internal tooling field) |
|
|
317
349
|
| *other fields* | Title-cased key, value stringified |
|
|
318
350
|
|
|
319
351
|
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.
|
|
@@ -322,21 +354,25 @@ If `repo_url` + `edit_uri` are set in `mkdocs.yml`, an **Edit Source** row links
|
|
|
322
354
|
|
|
323
355
|
MkDocs abbreviation definitions (`*[ABBR]: Full term`) are expanded inline — Confluence has no native `<abbr>` tooltip. The **first occurrence** in body text is expanded as `IAM (Identity and Access Management)`; subsequent occurrences are left as-is. Abbreviations that only appear in headings or code are collected into an auto-appended **Glossary** section.
|
|
324
356
|
|
|
325
|
-
### Graceful degradation
|
|
326
|
-
|
|
327
|
-
Any unrecognised block is preserved as a visible `warning` macro — no content is silently lost.
|
|
328
|
-
|
|
329
357
|
---
|
|
330
358
|
|
|
331
359
|
## Known limitations
|
|
332
360
|
|
|
333
361
|
| Feature | Behaviour |
|
|
334
362
|
|---|---|
|
|
335
|
-
| **Admonition styling** | `tip`, `info`, `warning`, `note` use Confluence's fixed native macro
|
|
363
|
+
| **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. |
|
|
336
364
|
| **Abbreviation tooltips** | No native tooltip support. First occurrence expanded inline; remainder left as-is. |
|
|
337
|
-
| **
|
|
338
|
-
| **
|
|
339
|
-
| **
|
|
365
|
+
| **Page ordering** | Confluence sorts child pages alphabetically; the v2 REST API has no write endpoint for ordering. |
|
|
366
|
+
| **Code language aliases** | Short aliases (`py`, `js`, `yml`, `ts`, `sh`) are passed through as-is; Confluence requires full language names for syntax highlighting. |
|
|
367
|
+
| **Unrecognised blocks** | Preserved as a visible `warning` macro — no content is silently lost. |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Architecture
|
|
372
|
+
|
|
373
|
+

|
|
374
|
+
|
|
375
|
+
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.
|
|
340
376
|
|
|
341
377
|
---
|
|
342
378
|
|
|
@@ -345,8 +381,9 @@ Any unrecognised block is preserved as a visible `warning` macro — no content
|
|
|
345
381
|
See [Setup.md](Setup.md) for environment setup.
|
|
346
382
|
|
|
347
383
|
```bash
|
|
348
|
-
pytest
|
|
349
|
-
ruff check src tests
|
|
350
|
-
|
|
351
|
-
|
|
384
|
+
uv run pytest -q # run tests
|
|
385
|
+
uv run ruff check src tests # lint
|
|
386
|
+
uv run vulture src --min-confidence 80 # dead code check
|
|
387
|
+
uv run mypy src # type-check
|
|
388
|
+
uv run bandit -r src -ll # security scan
|
|
352
389
|
```
|