The adoctra crate re-exports the parser and, behind features, the converters: html (default), docx, json, or all-backends.
[dependencies]
adoctra = "0.0.4" # or: { version = "0.0.4", features = ["docx", "json"] }
API reference: docs.rs/adoctra.
Parse and convert
use adoctra::Backend;
let result = adoctra::parse("= Hello\n\nWorld");
for diagnostic in &result.diagnostics {
eprintln!("{}: {}", diagnostic.severity.as_str(), diagnostic.message);
}
let html = adoctra::html::HtmlBackend::new().convert(&result.document)?;
std::fs::write("hello.html", html)?;
Parsing never fails: syntax problems become diagnostics with byte spans, and the document is still built. HtmlBackend::new() writes a standalone page, HtmlBackend::embedded() only the body content.
Attributes and options
use adoctra::ParseOptions;
let mut options = ParseOptions::default();
options.attributes.set("source-highlighter", "rouge");
options.attributes.set("toc", "");
let result = adoctra::parse_with_options(source, &options);
let html = adoctra::html::HtmlBackend::embedded().render(&result.document).html;
ParseOptions also holds the safe mode (safe, Safe by default), the base directory, include limits, document dates and the extension registry.
Includes and other resources
The parser never touches the file system by itself. Includes, images and other files are loaded through a ResourceProvider that you pass; MemoryResources keeps files in memory:
use adoctra::{MemoryResources, ParseOptions, SafeMode, SourceMap};
let mut resources = MemoryResources::new();
resources.insert("/book/main.adoc", "= Book\n\ninclude::chapter.adoc[]")?;
resources.insert("/book/chapter.adoc", "== Chapter\n\nText.")?;
let mut sources = SourceMap::new();
let source_id = sources.load("/book/main.adoc", None, &resources)?;
let options = ParseOptions { source_id, safe: SafeMode::Safe, ..Default::default() };
let result = adoctra::parse_resource(&mut sources, &options, &resources)?;
Implement ResourceProvider yourself to read from disk, a database or a virtual workspace.
DOCX
With the docx feature:
use adoctra::Backend;
let template = std::fs::read("corp.dotx")?;
let result = adoctra::parse(source);
let bytes = adoctra::docx::DocxBackend::new()
.with_template(template)
.convert(&result.document)?;
A template passed with with_template takes precedence over the docx-template attribute. See DOCX output for the style contract.
Extensions
Block, block macro, inline macro and tree processors are written in Rust and registered in a Registry:
use std::sync::Arc;
use adoctra::{BlockMacroProcessor, BlockMacroRequest, NewBlock, ParseOptions,
ProcessContext, Registry};
struct Version;
impl BlockMacroProcessor for Version {
fn name(&self) -> &str {
"version"
}
fn process(&self, request: BlockMacroRequest, _: &mut ProcessContext<'_>) -> Option<NewBlock> {
let text = format!("{} {}", request.target, env!("CARGO_PKG_VERSION"));
Some(NewBlock::listing(text, request.attributes))
}
}
let mut registry = Registry::new();
registry.register_block_macro(Version);
let options = ParseOptions { extensions: Some(Arc::new(registry)), ..Default::default() };
let result = adoctra::parse_with_options("version::myapp[]", &options);
The diagram support is itself an extension crate, adoctra-ext-diagram, registered with adoctra_ext_diagram::register(&mut registry, host).
Crates
| Crate | Purpose |
|---|---|
|
umbrella crate with feature-gated backends |
|
parser, document model, extension API (no backends) |
|
HTML5 backend |
|
DOCX backend |
|
JSON backend |
|
Rouge port for server-side highlighting |
|
diagram extension |
|
the |
|
WASM bindings for editors |