Крейт adoctra реэкспортирует парсер и, за feature-флагами, конвертеры: html (по умолчанию), docx, json или all-backends.

[dependencies]
adoctra = "0.0.4"   # или: { version = "0.0.4", features = ["docx", "json"] }

Справочник API: docs.rs/adoctra.

Разбор и конвертация

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)?;

Разбор никогда не завершается ошибкой: синтаксические проблемы становятся диагностиками с байтовыми диапазонами, а документ всё равно строится. HtmlBackend::new() записывает полную страницу, HtmlBackend::embedded() — только содержимое.

Атрибуты и опции

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 также задаются режим безопасности (safe, по умолчанию Safe), базовый каталог, лимиты включений, даты документа и реестр расширений.

Включения и другие ресурсы

Парсер сам не обращается к файловой системе. Включения, изображения и другие файлы загружаются через переданный ResourceProvider; MemoryResources хранит файлы в памяти:

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)?;

Реализуйте ResourceProvider, чтобы читать с диска, из базы данных или виртуального рабочего пространства.

DOCX

С feature docx:

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)?;

Шаблон из with_template важнее атрибута docx-template. Контракт стилей — на странице Вывод DOCX.

Расширения

Процессоры блоков, блочных и inline-макросов и дерева пишутся на Rust и регистрируются в 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);

Поддержка диаграмм сама является крейтом-расширением adoctra-ext-diagram и регистрируется вызовом adoctra_ext_diagram::register(&mut registry, host).

Крейты

Крейт Назначение

adoctra

зонтичный крейт с бэкендами за feature-флагами

adoctra-core

парсер, модель документа, API расширений (без бэкендов)

adoctra-html

бэкенд HTML5

adoctra-docx

бэкенд DOCX

adoctra-json

бэкенд JSON

adoctra-highlight

порт Rouge для подсветки на сервере

adoctra-ext-diagram

расширение для диаграмм

adoctra-cli

команда adoctra

adoctra-wasm

WASM-привязки для редакторов