= adoctra :toc: macro :toc-title: Contents
An AsciiDoc processor written in Rust: a command-line tool, a library and WASM bindings for editors. It converts AsciiDoc documents to HTML, DOCX and JSON, aiming at the behavior of Asciidoctor 2.0.23.
NOTE: AsciiDoc is a registered trademark of the Eclipse Foundation, Inc. This project is an independent processor of the AsciiDoc markup language and is not affiliated with or endorsed by the Eclipse Foundation or the Asciidoctor project.
Status: version 0.0.4, an early release. Real-world documents convert (the test corpus includes the documentation of Asciidoctor, Spring, Quarkus, Gradle, Hibernate ORM, JUnit and others), but the API and the output may still change between releases. See <> for what is and is not covered.
toc::[]
== Features
- Language: preprocessor directives and includes, document header and attributes, sections and numbering, all delimited blocks, lists and callouts, tables (including AsciiDoc cells), images, audio and video, cross references, footnotes, index terms, STEM, table of contents and the full substitution pipeline, compared with Asciidoctor 2.0.23.
- HTML: modern semantic HTML5 with the bundled
adoctra.cssstylesheet, visually matching Asciidoctor's default output (standalone or embedded, HTML or XHTML syntax). - DOCX: Word documents rendered into a template; every element gets a
named style that your own
.docx/.dotxtemplate can restyle. - JSON: the document tree, attributes and diagnostics.
- Syntax highlighting: a port of Rouge with all 228 lexers
(
source-highlighter=rouge), no Ruby required. - Diagrams: all 58 diagram types of asciidoctor-diagram 3.2.1 (PlantUML, Graphviz, Mermaid, D2, ditaa, barcodes and more) through their tools, Kroki or a PlantUML server.
- Editors: error-tolerant parsing (malformed input gives a partial document and diagnostics, never an error), byte spans for every block, a token stream for highlighting, compiled to WASM.
== Installation
Download a binary for Linux (static, x86_64), Windows or macOS (Apple Silicon or Intel) from the https://github.com/avskor/adoctra/releases[releases page], or install from crates.io with Rust 1.94 or newer (https://rustup.rs[rustup]):
[source,sh]
cargo install adoctra-cli # installs the adoctra command
adoctra --version
To build from a checkout: cargo install --path crates/adoctra-cli.
== Command line
adoctra follows the asciidoctor command: the output is written next to
the input, named after it.
[source,sh]
adoctra document.adoc # document.html adoctra -o - document.adoc # HTML to stdout adoctra -e document.adoc # embedded HTML (no header/footer) adoctra --to docx document.adoc # document.docx adoctra --to json document.adoc # document.json adoctra -D build/ docs/*.adoc # several files into a directory adoctra -a toc -a icons=font -n book.adoc # attributes, section numbers adoctra -a source-highlighter=rouge document.adoc
Common options (adoctra --help lists all of them):
[cols="1,3",options="header"]
|===
|Option |Meaning
|-b, --backend |html5 (default), xhtml5, docx, json
|--to FORMAT |html, docx or json
|-d, --doctype |article (default), book, manpage or inline
|-a NAME[=VALUE] |set a document attribute (name@ or value@: the document may override it)
|-o FILE, -D DIR |output file (- for stdout) or directory
|-B DIR |base directory of the document and its resources
|-S MODE |safe mode: unsafe, safe (default), server or secure
|-e, -s |embedded document, without header and footer
|-n |number sections
|--failure-level LEVEL |exit with status 1 on messages of this level (WARN, ERROR, …)
|-q, -v |no messages, or also informational ones
|-r asciidoctor-diagram |enable diagrams (see <>)
|===
NOTE: The default safe mode is safe, not unsafe as in the asciidoctor
command: includes and output files stay inside the base directory unless
you pass -S unsafe.
== DOCX
Without a template, a built-in one is chosen by doctype (article or book
with a cover page). To use your corporate look, pass a Word document or
template whose styles (Heading 1, Code, Admonition Note Table, …)
restyle the output:
[source,sh]
adoctra --to docx -a docx-template=corp.dotx report.adoc
The built-in templates can be exported for editing in Word with
cargo run -p adoctra-docx --example export_templates -- <dir>. The style
contract is described in link:docs/docx.adoc[docs/docx.adoc] (in Russian).
[[diagrams]] == Diagrams
Diagrams are enabled with the same option as in Asciidoctor:
[source,sh]
adoctra -r asciidoctor-diagram document.adoc
[source,asciidoc] .... [graphviz, flow, svg]
digraph { a -> b }
plantuml::diagrams/sequence.puml[svg] ....
Each type runs its own tool, which must be installed: dot (Graphviz),
mmdc (mermaid-cli), PlantUML (plantuml on PATH or the JAR files in
DIAGRAM_PLANTUML_CLASSPATH), d2, svgbob and so on. Barcodes need no
tools. Without local tools, render every diagram through
https://kroki.io[Kroki] or your own Kroki server:
[source,sh]
adoctra -r asciidoctor-diagram
-a diagram-server-url=https://kroki.io -a diagram-server-type=kroki_io
document.adoc
Like Asciidoctor, diagrams run external programs and send the diagram source to the server, so they are enabled only on request.
== Library
The adoctra crate re-exports the parser and, behind features, the backends
(html by default, docx, json, all-backends):
[source,toml]
[dependencies] adoctra = "0.0.4" # or features = ["docx", "json"]
[source,rust]
use adoctra::Backend;
let result = adoctra::parse("= Hello\n\nWorld"); for diagnostic in &result.diagnostics { eprintln!("{}", diagnostic.message); } let html = adoctra::html::HtmlBackend::new().convert(&result.document)?;
Parsing never fails: syntax problems are reported as diagnostics. Includes and
other resources are loaded only through a ResourceProvider you pass
(MemoryResources for in-memory files); see
link:docs/parser-api.adoc[docs/parser-api.adoc]. Own block, block macro,
inline macro and tree processors are registered in a Registry
(ParseOptions::extensions).
== WASM for editors
adoctra-wasm exposes the parser (not the converters) to JavaScript:
[source,sh]
rustup target add wasm32-unknown-unknown wasm-pack build crates/adoctra-wasm --target web # or --target bundler
parse_json(text):{ document, diagnostics, tokens }; diagnostics and tokens carry UTF-8 byte spans ({ source_id, start, end }).tokens_json(text): highlighting tokens only.ResourceWorkspace: a virtual file system for includes and images (set,set_binary,load,parse_json).- Diagrams through Kroki:
DiagramWorkspace, orResourceWorkspace.enable_diagrams(url, type)to read diagram files from the workspace. A parse lists the server requests it still needs; the host fetches them and passes the responses back.
[source,js]
const ws = new DiagramWorkspace("https://kroki.io/", "kroki_io");
let result = JSON.parse(ws.parse_json(text, 0));
for (const r of result.diagrams.requests) {
const response = await fetch(r.url, r.body === undefined ? {} :
{ method: "POST", body: r.body, headers: { "Content-Type": r.content_type } });
if (response.ok) ws.set_response(r.key, new Uint8Array(await response.arrayBuffer()));
else ws.set_error(r.key, ${response.status} "${response.statusText}");
}
result = JSON.parse(ws.parse_json(text, 0)); // images in result.diagrams.images
cargo run --example editor_demo -p adoctra-wasm prints the JSON an editor
receives.
[[compatibility]] == Compatibility with Asciidoctor
The reference is Asciidoctor 2.0.23. Document content, structure, diagnostics and command-line behavior are compared with it on pinned corpora and the upstream test suite; HTML is compared visually (screenshots), not byte for byte. Known differences:
- HTML uses modern semantic markup, so stylesheets or scripts that depend on Asciidoctor's exact HTML need checking.
- No DocBook or man page backends; no PDF or EPUB.
- Ruby extensions, templates (
-T) and libraries (-rother thanasciidoctor-diagram) are not supported; use the Rust extension API. - The default safe mode of the command is
safe. - In the browser, PlantUML diagrams need
preprocess=false, and diagrams are rendered only through a server.
The full register of verified areas and open differences is in link:docs/compatibility.adoc[docs/compatibility.adoc] (in Russian).
== Workspace
[cols="1,3",options="header"]
|===
|Crate |Purpose
|adoctra-core |parser, document model, extension API (no backends)
|adoctra-html |HTML5 backend
|adoctra-docx |DOCX backend
|adoctra-json |JSON backend
|adoctra-highlight |Rouge port for server-side highlighting
|adoctra-ext-diagram |diagram extension (asciidoctor-diagram port)
|adoctra |umbrella crate with feature-gated backends
|adoctra-cli |the adoctra command
|adoctra-wasm |WASM bindings for editors
|===
[source,sh]
cargo build --workspace --all-features cargo test --workspace --all-features
Implementation notes, the plan and the compatibility harnesses are in link:docs/[docs/]. Changes are listed in link:CHANGELOG.md[CHANGELOG.md].
== License
Licensed under either of
- Apache License, Version 2.0 (link:LICENSE-APACHE[LICENSE-APACHE])
- MIT license (link:LICENSE-MIT[LICENSE-MIT])
at your option. Copyright (c) 2026 Alexey Skorobogatov.
Ported code keeps its own notices: Rouge (link:crates/adoctra-highlight/LICENSE-rouge[LICENSE-rouge], MIT) and the libraries ported for diagrams (link:crates/adoctra-ext-diagram/LICENSE-third-party[LICENSE-third-party]).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.