acdc is the command-line entry point for the acdc AsciiDoc toolchain.
It converts documents, runs project lints and command blocks, displays a structural parser outline, and provides the AsciiDoc TCK adapter.
Use acdc <command> --help for the exhaustive option reference.
This guide focuses on common workflows and build-time features.
The default build includes HTML conversion, linting, pre-spec subs= compatibility, and the runtime convert --setext compatibility flag.
cargo build -p acdc-cli
cargo run -p acdc-cli -- convert document.adocOptional backends and tools are Cargo features:
cargo build -p acdc-cli --features pdf
cargo build -p acdc-cli --features terminal,highlighting
cargo build -p acdc-cli --all-featuresConvert one or more AsciiDoc files. HTML is the default backend in a default build; other backends must be selected explicitly.
acdc convert document.adoc
acdc convert --backend markdown --variant commonmark document.adoc
acdc convert --backend terminal --no-pager document.adocSupported backends depend on the features used to build the binary:
| Backend | Feature | Notes |
|---|---|---|
|
|
Standard HTML by default; |
|
|
Native roff/troff manual pages. |
|
|
GFM by default; |
|
|
PDF output backed by the Rust Typst engine. |
|
|
ANSI terminal output with an automatic pager on interactive stdout. |
--backend html5s remains an alias for --backend html --variant semantic.
Without --out-file, file input produces a backend-specific path next to each input.
Use --out-file - for stdout or --stdin for standard input.
acdc convert -o output.html document.adoc
acdc convert -o - document.adoc
printf '= Title\n\nBody.\n' | acdc convert --stdin -o -When --out-file is combined with several inputs, only the first input is processed.
--open opens converter-reported output files with the system’s default application and is ignored for stdout.
Use --timings for parse/conversion timings, --strict to turn supported fallbacks into errors, --safe or --safe-mode for parser safety policy, and --embedded to suppress enclosing document structure where the backend supports embedded output.
Values passed with -a or --attribute take precedence over matching attribute entries in the document.
Use -a name, -a name=value, or -a name! to set, assign, or unset a locked value.
Add @ to the name or value, such as -a name@=value, -a name=value@, or
-a !name=@, when the document must be allowed to replace that command-line default.
Build with pdf (or all-backends) and select --backend pdf:
cargo run -p acdc-cli --features pdf -- convert --backend pdf document.adoc \
--page a3 \
--page-layout landscape \
--font-dir fonts \
--logo assets/logo.svg \
--title "Internal Architecture" \
--watermark "Draft" \
--watermark-timestamp \
--toc--page accepts A3, A4, A5, Executive, Legal, Letter, or Tabloid.
--page-layout accepts portrait or landscape.
The pdf-page-size document attribute also accepts custom dimensions, and
pdf-page-margin sets one to four margins for that document.
--theme selects a YAML theme, --plain removes page chrome, and --emit-typst writes the generated Typst markup for one input.
--strict makes unresolved PDF images or logos fatal.
Remote PDF assets additionally require the network feature and remain subject to the PDF converter’s asset safety policy.
Interactive terminal output uses $PAGER, defaulting to less -FRX on Unix and more on Windows.
Use --no-pager or an empty PAGER to disable it.
The html-terminal feature enables acdc-specific terminal previews in HTML, including [terminal] blocks and source blocks opted in with :acdc-terminal:.
See the HTML converter documentation for the rendering syntax, attributes, replay support, and Asciidoctor differences.
The terminal-emulator feature enables Ghostty-backed [terminal] session rendering in the terminal backend and requires the documented Zig build prerequisite.
The default build includes the lint command:
acdc lint docs/*.adoc
acdc lint --output-style compact --deny image-alt-text docs/*.adocLint levels follow the Clippy/rustc shape: --allow/-A, --warn/-W, --deny/-D, and --forbid/-F.
Individual lint IDs can be scoped to source locations:
acdc lint -A section-title-capitalization@37 docs/architecture.adoc
acdc lint -D image-alt-text@10:1-10:80 docs/architecture.adocScopes support LINE, START-END, LINE:COLUMN, and LINE:COLUMN-LINE:COLUMN; comma-separated locations can follow one @.
Full diagnostics and lint statistics are the default.
Compact output omits colors and source snippets.
See the lint crate documentation for lint IDs, groups, levels, and location semantics.
Build with inspect to print a human-readable structural outline of a parsed file.
It honors file context and local includes; it is not a lossless AST serialization.
cargo run -p acdc-cli --features inspect -- inspect document.adoc --show-locations--max-depth limits displayed nesting.
Color is used only on interactive stdout and respects NO_COLOR.
Build with execute to run command blocks defined in an AsciiDoc document.
A command block is a listing or source block carrying the command role and an explicit id.
Ids contain only ASCII letters, digits, _, and -; they must be nonempty and cannot start with -.
The optional deps attribute names prerequisites, separated by commas.
The optional description attribute supplies a summary for --list.
== Build
[.command, id=build, description="Build the project"]
[source, bash]
----
cargo build
----
== Test
[.command, id=test, deps="build", description="Run the tests"]
[source, bash]
----
cargo nextest run
----acdc execute --dry-run README.adoc
acdc execute --list README.adoc
acdc execute --id build README.adoc
acdc execute --id-regex '^test-' --exit-on-failure README.adoc
acdc execute --id test --cwd project --env MODE=ci README.adocCommands are discovered in document order, including inside nested containers, AsciiDoc table cells, and included files, then executed in dependency order.
Exact --id and --id-regex selectors form a union, and selected commands always run together with their transitive dependencies; each command runs at most once.
Without selectors, every command is selected.
An unknown id or a regex that matches no commands is an error.
--dry-run prints the selected commands and scripts; --list prints a bulleted list with labeled ids, interpreters, enclosing section titles, direct dependencies, and optional descriptions.
Both include dependencies and run no commands; the two options cannot be combined.
For the example above, --list prints:
- id=build, interpreter="bash", section="Build", description="Build the project"
- id=test, interpreter="bash", section="Test", deps="build", description="Run the tests"Dependency ids are sorted alphabetically. The section is the nearest enclosing section’s title as plain text; commands outside sections omit it. Interpreters, section titles, and descriptions are quoted, with control characters escaped to keep each command on one line.
The block attribute interpreter overrides the source language: [source,python,role=command,id=check,interpreter=python3] uses Python highlighting and runs python3.
Without an override, the source language selects the interpreter; a block without either uses sh.
The interpreter is one executable name or path, passed directly to the operating system without shell argument splitting or an allowlist.
Relative interpreter paths are resolved from the caller’s working directory, including when --cwd is set; bare executable names use the operating system’s search rules.
Includes and conditionals are processed before execution.
Preprocessing normalizes line endings and removes trailing whitespace from lines.
Script bodies are literal by default, including attribute references and callout markers.
Enable attribute expansion with subs=attributes, subs=attributes`, or `subs=attributes on a command block.
The normal group also enables attributes; subs=none and subs=-attributes keep them literal.
Only enabled attribute references are expanded; other rendering substitutions do not change the script, and callouts remain literal.
Use comments in the script language for annotations.
:target: build-output
[.command,id=show-target,subs=+attributes]
----
printf '%s\n' '{target}'
----Attribute values are inserted as text without shell quoting; write the quoting required by the selected interpreter.
When attribute expansion is enabled, {name} becomes literal {name} without looking up the attribute.
An empty attribute value is valid; a missing unescaped attribute is an error.
Each command uses the attributes active at its source position.
Attributes defined inside an AsciiDoc table cell stay in that cell; values inherited by the cell cannot be reassigned there.
All scripts are prepared before selection or execution, so a missing attribute in an unselected command also stops the invocation.
Dry-run displays the same prepared script that execution passes to the interpreter.
Malformed command blocks, incomplete structural recovery, and missing required includes are errors before any command starts.
A command that exits with a nonzero status blocks its dependent commands; independent commands still run.
--exit-on-failure stops at the first failed command.
A signal termination or an error creating the script or starting its interpreter always stops the run.
Any failed command makes the invocation fail, including when independent commands finish successfully.
Each command inherits the caller’s working directory, environment, and standard streams.
--cwd PATH changes the child working directory; relative paths are resolved from the caller’s directory.
It does not change how the input document or its includes are resolved.
Repeat --env NAME=VALUE to override variables for the children; the last value for a name wins.
An empty value is allowed, and only the first = separates the name from its value.
These options leave the calling process unchanged.
-S/--safe-mode limits what the document may include while parsing; it does not sandbox the executed commands.
A build with the execute feature only is available via cargo build -p acdc-cli --no-default-features --features execute.
Add pre-spec-subs to that feature list to enable command attribute substitutions.
Without this feature, documents that request any subs setting are rejected before execution.
| Feature | Default | Effect |
|---|---|---|
|
yes |
HTML backend. |
|
yes |
Lint command. |
|
yes |
Asciidoctor-compatible pre-spec |
|
yes |
Compiles Setext header support; parsing is enabled per run with |
|
no |
Optional output backends. |
|
no |
Source highlighting in each selected HTML or terminal backend; does not select a backend. |
|
no |
HTML terminal previews and session/replay rendering. |
|
no |
Ghostty-backed terminal session rendering; selects the terminal backend. |
|
no |
Remote includes and remote PDF assets when PDF is selected. |
|
no |
|
|
no |
Developer/specification commands. |
Convenience groups are all-backends, dev-tools (execute, inspect), and test-tools (tck).
A build with no command-enabling features exits with a diagnostic that lists the available command features.
Parser and converter warnings are written to stderr with source snippets when available. Lint diagnostics use the selected output style. Command-line usage errors exit with status 2; processing failures and denied lint diagnostics exit with status 1; successful commands exit with status 0.