Supported Extensions & Macros
acs2md converts Atlassian Document Format (ADF) through the Climakers conversion engine. That engine recognises a broad catalogue of Confluence extensions, marketplace-app macros, embeds and media types, and decides element by element whether to render real content fetched from Confluence or to preserve the original element as a safe HTML comment.
How an extension is rendered
Every recognised extension goes through three possible outcomes, in order:
- Live API rendering. The
--ext-*or--embed-*flag is enabled and the required credentials and context (space key, page ID) are available. The macro is replaced with real content: a Markdown table, a list of resolved pages, a base64 image. - HTML-comment placeholder. The extension is disabled, credentials are missing, or the API call failed. The converter emits a comment such as
<!-- Page Tree -->. It is invisible in rendered Markdown but records that a macro existed at that position, so audit and migration workflows stay lossless. - Graceful fallback. For image-style extensions, a failed download falls back to a plain reference —
media://UUIDor the original Confluence URL — so the document is never broken.
This is why every API-backed extension is safe to leave enabled. When API access is not configured the worst case is an HTML comment, never a runtime error and never a silently missing macro.
What Confluence access each extension needs
Most extensions need API access to resolve content. Configure it once through the config file, environment variables, or persistent flags — see Configuration.
| Setting | Required by | Notes |
|---|---|---|
confluence.domain | All API-backed extensions | e.g. your-tenant.atlassian.net |
confluence.username | All API-backed extensions | The email address of the Atlassian account |
confluence.api_token | All API-backed extensions | Created at id.atlassian.com |
--space-key | Recently Updated, List Labels, Blog Posts, Content by Label, Task Report | Falls back to the macro’s own spaces / spaceKey parameter when present. space convert by-key already supplies it. |
| Page ID context | Page Tree, Children, Contributors, Page Signatures, QC Properties | Supplied automatically by every space convert and page convert command |
When credentials or context are missing for one extension, only that extension degrades to an HTML comment and a warning is logged. Every other extension on the page continues to render.
Support matrix
The canonical inventory. Flag names are the CLI form accepted by acs2md and acp2md.
| Confluence extension | What it produces | Flag | Default | Requires |
|---|---|---|---|---|
| Inline images (any URL) | Base64 data URIs | --embed-images | true | HTTP access |
| Confluence media files | Base64 data URIs | --embed-media-images | true | Credentials |
| Confluence media as sidecars | Sidecar files + Markdown image | --image-sidecars | false (on with --obsidian) | Credentials |
| Non-image attachments | Sidecar files + Markdown link | always on when credentials present | on | Credentials |
| Draw.io diagrams | Base64 PNG | --ext-embed-drawio, -D | true | Credentials |
| Roadmap Planner | Base64 PNG | --ext-embed-roadmap | true | Credentials |
| Table of Contents | Markdown anchor list | --ext-render-toc | true | — |
| Recently Updated | Markdown bullet list | --ext-render-recently-updated | true | Credentials + space key |
| List Labels | Linked label badges | --ext-render-listlabels | true | Credentials + space key |
| Page Tree | Nested Markdown list | --ext-render-pagetree | true | Credentials + page ID |
| Children | Flat or nested list | --ext-render-children | true | Credentials + page ID |
| Contributors | Markdown list of users | --ext-render-contributors | true | Credentials + page ID |
| Content by Label | Markdown list of pages | --ext-render-content-report | true | Credentials |
| Blog Posts | Markdown list of posts | resolved automatically | true | Credentials + space key |
| Page Signatures | Markdown table | --ext-render-page-signatures | true | Credentials + page ID |
| QC Property | Resolved value inline | --ext-render-qc-properties | true | Credentials + page ID |
| QC Revision | Resolved value inline | --ext-render-qc-properties | true | Credentials + page ID |
| Task Report | Markdown table | --ext-render-task-report | true | Credentials + space key |
| Content Report Table | Markdown table | --ext-render-content-report | true | Credentials |
| CQL Query | Markdown list, or a table when the macro requests columns | --ext-render-cql-query | true | Credentials |
| Excerpt | Inline body text | always on | true | — |
| Anchor | Markdown anchor target | always on | on | — |
| Inline cards | Resolved page-title link | --ext-resolve-inline-card-titles | true | Credentials |
| Embed / block cards | Resolved Jira, Confluence or YouTube link | resolved automatically | true | Credentials |
Bodied extensions (expand, …) | Body content + comment marker | always on | comment on | — |
Inline extensions (status, livesearch, …) | HTML comment placeholder | always on | comment on | — |
| Other Confluence macros | HTML comment placeholder | always on | comment on | — |
| Generic ADF extensions | HTML comment placeholder | always on | comment on | — |
| Create from Template | Plain-text label | always on | comment on | — |
Reading the defaults. Every --ext-*, --embed-* and --include-* flag
ships enabled. Pass --flag=false to opt out for one run, or set the
equivalent config key or environment variable to make it permanent.
Images and media
Inline images
--embed-images (default true) downloads every remote image the page references and embeds it as a base64 data URI. The resulting Markdown is self-contained: it does not depend on the Confluence host, a private CDN, or network access at reading time.
Embedded: files with image extensions (.png, .jpg, .jpeg, .gif, .webp, .svg, .bmp, .ico), known image hosts, and any URL whose Content-Type starts with image/.
Skipped on purpose: YouTube and other video URLs, HTML pages, PDFs and other non-image binaries.
Base64 adds roughly 33% to the byte size — the normal cost of a self-contained document.
Confluence-hosted media files
ADF represents uploaded images, avatars and icons as media nodes carrying a UUID and a collection reference like contentId-393325. Without API access those can only render as media://UUID placeholders.
With --embed-media-images on and credentials configured, acs2md extracts the page ID from the collection attribute, calls the attachments API once per page (cached), downloads each matched attachment, and embeds it. A failed download falls back to  rather than breaking the document.
Supported formats: PNG, JPEG, GIF, WebP, SVG, BMP, ICO.
Sidecar files instead of base64
--image-sidecars writes the bytes to attachments/<page-id>/<filename> and links them relatively:
The export stays self-contained either way — what changes is line length. See Obsidian Vaults for why a 100 KB single-line data URI stops rendering there but works on GitHub. Failures fall back to base64, then to the remote URL.
Non-image attachments
PDFs, .docx, .xlsx, .pptx, ZIP archives and similar resolve through the same attachments API but render as ordinary Markdown links. The bytes are downloaded once and saved beside the Markdown:
[MBR Conversion User Guide.pdf](attachments/5814878215/MBR%20Conversion%20User%20Guide.pdf)
[Quarterly KPI workbook.xlsx](attachments/5814878215/Quarterly%20KPI%20workbook.xlsx)- Files land at
attachments/<page-id>/<original-filename>, so attachments from many pages share one output directory without colliding. - Original filenames are preserved; characters unsafe on Linux, macOS or Windows are replaced with
_. Hrefs are percent-encoded, so spaces and parentheses still produce working links. - An existing destination file is not re-downloaded — the filesystem acts as the cache.
- A failed download falls back to the remote Confluence URL with a warning, so output is never broken.
File type is classified by Confluence’s reported media type first, then magic-byte sniffing (PDF, ZIP / Office Open XML, OLE, RTF, 7z, gzip, tar), then the filename extension.
This is the recommended way to package Confluence content for offline review, audit handover, or Git-based archiving: the Markdown and its attachments form one portable bundle.
Diagrams
| Macro | Flag | Output |
|---|---|---|
| Draw.io | --ext-embed-drawio, -D | Base64 PNG of the rendered diagram |
| Roadmap Planner | --ext-embed-roadmap | Base64 PNG of the rendered roadmap |
Both need Confluence credentials, because the rendered image is fetched from the tenant rather than reconstructed locally. Both fall back to an HTML comment when they cannot be resolved.
Page-listing macros
| Macro | Flag | Output | Needs |
|---|---|---|---|
| Page Tree | --ext-render-pagetree | Nested Markdown list of descendants | Page ID |
| Children | --ext-render-children | Flat or nested list of child pages | Page ID |
| Recently Updated | --ext-render-recently-updated | Bullet list of recently changed pages | Space key |
| Blog Posts | resolved automatically | Bullet list of posts | Space key |
| Content by Label | --ext-render-content-report | List of pages carrying the label | Credentials |
| List Labels | --ext-render-listlabels | Linked label badges | Space key |
A full-space conversion already supplies the space context these macros need. When converting by-id, pass --space-key so the ones that require it can resolve.
People, activity and reporting
| Macro | Flag | Output |
|---|---|---|
| Contributors | --ext-render-contributors | Markdown list of contributing users |
| Task Report | --ext-render-task-report | Markdown table of tasks |
| Content Report Table | --ext-render-content-report | Markdown table of matching content |
| CQL Query | --ext-render-cql-query | Markdown list of linked results, or a table when the macro requests columns |
Document control and quality
| Macro | Flag | Output |
|---|---|---|
| Page Signatures | --ext-render-page-signatures | Signatures table, or a reviewers fallback table |
| QC Property | --ext-render-qc-properties | The resolved value, inline |
| QC Revision | --ext-render-qc-properties | The resolved value, inline |
These resolve template placeholders into the page’s actual metadata, which is what makes a converted controlled document readable outside Confluence.
Cards and embeds
| Element | Flag | Output |
|---|---|---|
| Inline cards | --ext-resolve-inline-card-titles | A link carrying the real page title instead of a bare URL |
| Embed and block cards | resolved automatically | Human-readable Jira, Confluence or YouTube links |
Inline card resolution is also what --wikilinks builds on: it needs a real title before it can emit [[Page Title]].
Lossless fallback
Anchors, excerpts, bodied extensions (expand and friends), inline extensions (status, livesearch), and any macro the engine does not specifically support are preserved as HTML comments. Nothing is silently dropped — a migration audit can still find every position where a macro used to be.
Markdown standards compliance
Output is written to satisfy common Markdown linters:
| Rule | Handling |
|---|---|
| MD009 no trailing whitespace | Stripped; hard breaks preserved |
| MD012 no multiple blank lines | Collapsed |
| MD022 blank lines around headings | Inserted before every block element |
| MD028 no blank lines between blockquotes | Merged |
| MD031 blank lines around fenced code | Inserted before opening fences |
| MD032 blank lines around lists | Inserted before every top-level list |
| MD040 fenced code language | A default language is supplied |
| MD045 image alt text | Falls back to image when ADF provides none |
| MD047 single trailing newline | Enforced |
Extended syntax preserved by GitHub, Obsidian and Pandoc is also emitted: highlight, superscript and subscript, automatic URL linking, per-column GFM table alignment, panels as alerts or callouts (--panel-style), math ($…$ and $$…$$), heading IDs for anchor links, and footnotes.
Caching, size limits and credentials
Several extensions download bytes or issue REST calls. Two settings control how aggressively results are cached:
| Setting | Default | Used by |
|---|---|---|
--image-cache-dir | <output-dir>/<space-key>/.image_cache/ | --embed-images, --embed-media-images, --ext-embed-drawio, --ext-embed-roadmap |
--image-max-size-bytes | 2097152 (2 MB) | All embedding flags above — a larger download keeps its original URL instead |
Attachment sidecars use the output directory itself as a cache: a file already on disk is not fetched again.
--image-max-size-bytes defaults to 2 MB. Images above that keep their
Confluence URL rather than being embedded, which means those specific images
need credentials and network access to view. Raise the limit if a fully
offline export matters more than output size.
When --sync or --incremental is active, acs2md prints both the state file path and the image cache path before conversion starts, so you can confirm where artefacts will land.
When to disable an extension
| Situation | What to pass |
|---|---|
| Building a RAG or search index — you want text, not pictures | --embed-images=false --embed-media-images=false |
| Output must stay small and readers have Confluence access anyway | --embed-images=false |
| A macro resolves slowly across a large space and you do not need it | Disable that specific --ext-render-* |
| You need the export to be reproducible and API-independent | Disable every --ext-render-*; macros become comments |
| Conversion is rate-limited by macro resolution | Disable the page-listing macros first — they cost the most API calls |
Each --ext-render-* costs extra API calls, because the macro is resolved against Confluence rather than read from the page body. On a large space that is the dominant cost.
See also
- Convert Spaces — the full flag reference
- Obsidian Vaults — how these render in a vault
- Configuration — credentials, proxy and retry settings