Observed since 20 Oct, 19:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Pure-Python Markdown ↔ Atlassian Document Format (ADF) converter with lossless round-tripping
A pure-Python converter between Markdown (CommonMark + GFM) and Atlassian Document Format (ADF) — the JSON document model used by Confluence and Jira. Round-trips losslessly, including ADF-only constructs like panels, status badges, mentions, task lists, expand sections, and macros.
flowchart LR
MD[Markdown] -->|markdown-it-py| IR((Internal IR + adf-* envelopes))
ADF[ADF JSON] -->|mapping.yaml| IR
PF[Panflute JSON] -->|pf.load| IR
IR -->|options filter| W{writer}
W -->|CommonMark serializer| MD2[Markdown]
W -->|mapping.yaml| ADF2[ADF JSON]
W -->|pf.dump| PF2[Panflute JSON]
ADF is JSON, but no mature pure-Python tool converts it to and from
Markdown without losing information. adflux fills that gap:
pip install adflux — no Pandoc binary,
no Node, no Ruby.mapping.yaml plus a small
envelope convention round-trips every ADF construct, including ones
the library has never seen.<details>, smart cards become autolinks. The
output looks correct in GitHub, VS Code, and any standard viewer.pip install adflux
Requires Python ≥ 3.11. Linux, macOS, and Windows are CI-tested.
from adflux import convert
# Markdown → ADF JSON
adf = convert(open("README.md").read(), src="md", dst="adf")
# ADF JSON → Markdown, dropping ADF-only constructs to plain content
md = convert(adf, src="adf", dst="md", options={"envelopes": "drop"})
adflux convert --from md --to adf README.md > readme.adf.json
adflux convert --from adf --to md page.json
adflux convert --from adf --to md --option envelopes=drop page.json
adflux validate page.adf.json
adflux list-options
Full API and CLI reference: docs/usage.md.
| Option | Choices | Default | Description |
|---|---|---|---|
envelopes | keep, drop, keep-strict | keep | How ADF envelope nodes are handled on lossy targets. |
jira-strict | true, false | false | Reject non-Jira ADF nodes during serialization. |
Worked examples: docs/options.md.
| ADF construct | Rendered as |
|---|---|
panel (info/note/warning/…) | GitHub alert blockquote (> [!NOTE], > [!TIP], …) |
expand | <details><summary>title</summary>…</details> |
inlineCard / blockCard / embedCard | Autolink (<https://…>) |
taskList / taskItem | GFM task list (- [ ], - [x]) |
emoji, mention | Plain text (🚀, @alice) |
| Everything else | HTML-comment marker (<!--adf:status …-->) |
The reader recognises every form on its way back, so MD → ADF → MD is
stable.
| Format | Aliases | Description |
|---|---|---|
| Markdown | md, markdown | CommonMark + GFM via markdown-it-py |
| ADF | adf | Atlassian Document Format JSON |
| Panflute | panflute, pf | Pandoc JSON AST for integration with panflute tools |
Div / Span envelopes for ADF-only constructs.adf-<nodeType> plus a base64-JSON blob
for complex attributes. A universal adf-raw fallback guarantees zero
data loss.src/adflux/formats/adf/mapping.yaml.
Adding a new node type is a YAML edit.Deeper dives:
docs/design.md ·
docs/architecture.md ·
docs/options.md ·
docs/fidelity-matrix.md ·
docs/extending.md ·
docs/e2e-testing.md.
Runnable scripts in examples/:
python examples/md_to_adf.py README.md
python examples/adf_to_markdown.py
python examples/confluence_roundtrip.py
git clone https://github.com/mikejhill/adflux
cd adflux
uv sync --all-groups
uv run poe check
Common tasks via poethepoet:
poe test # unit + integration + round-trip + property tests
poe test-e2e # live Confluence + Jira round-trip suite (requires .env)
poe lint # ruff format --check + ruff check
poe typecheck # ty check src
poe cov # pytest with coverage report
poe check # lint + typecheck + test (run before opening a PR)
poe build # sdist + wheel into ./dist
CI runs the full matrix on Linux, macOS, and Windows for Python 3.11–3.13.
Releases are automated. Land changes on main using
Conventional Commits, then run
the Release workflow from the GitHub Actions tab. go-semantic-release
computes the next version, builds the sdist + wheel, creates a tagged
GitHub Release, and publishes to PyPI via OIDC trusted publishing.
Issues and pull requests are welcome. Before opening a PR:
poe check must pass (lint + typecheck + tests).feat:, fix:, docs:, …).tests/roundtrip/test_node_coverage.py.MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.3.1 | 18 Apr 2026 | 7 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Public sponsor counts have not been collected. These signals belong to the repository owner.
github · 1 observations shown. Missing days are unknown.
| Date / source period | Value | Observed at |
|---|---|---|
| 2026-10-22 | 0 | 2026-10-22T16:35:45.8681459Z |
Observed since 20 Oct, 19:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:178b3e20a0ef91679fe39591e9f170d5dbe3c6b5de096ee0ca24cc4e78572cbd