typst-batch 0.2.2

Typst helper library for batch processing — friendly API, shared resources, virtual files, customizable diagnostics
Documentation
# typst-batch

Typst → HTML batch compilation library with shared resources.

> **Note**: This library was extracted from [tola-ssg]https://github.com/tola-ssg/tola-ssg. It is designed for Typst → HTML workflows and may not be generic enough for all use cases.

## Features

- **Shared resources**: Fonts loaded once, packages cached
- **Batch compilation**: Parallel processing with shared file snapshot
- **Fast scanning**: Skip Layout phase for metadata extraction
- **Virtual file system**: Inject dynamic content without physical files
- **Structured diagnostics**: Rich error messages with source locations

## Installation

```toml
[dependencies]
typst-batch = "0.1"
```

### Feature Flags

| Feature | Default | Description |
|---------|---------|-------------|
| `colored-diagnostics` || ANSI colored output |
| `scan` || Fast scanning API (skips Layout) |
| `batch` || Parallel batch compilation (rayon) |
| `svg` | | SVG rendering for frames |

## Quick Start

```rust
use typst_batch::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize fonts once at startup
    get_fonts(&[]);

    // Compile a single file
    let result = Compiler::new(Path::new("."))
        .with_path(Path::new("doc.typ"))
        .compile()?;

    let html = result.html()?;
    std::fs::write("output.html", &html)?;

    // Print warnings
    if !result.diagnostics().is_empty() {
        eprintln!("{}", result.diagnostics());
    }

    Ok(())
}
```

## API

### Single File Compilation

```rust
use typst_batch::prelude::*;

// Basic compilation
let result = Compiler::new(root)
    .with_path(path)
    .compile()?;

// With sys.inputs
let result = Compiler::new(root)
    .with_inputs([("title", "Hello"), ("author", "Alice")])
    .with_path(path)
    .compile()?;

// Query metadata: #metadata((title: "Hello")) <post-meta>
if let Some(meta) = result.document().query_metadata("post-meta") {
    println!("Title: {}", meta["title"]);
}
```

### Batch Compilation

```rust
use typst_batch::prelude::*;

// Create batcher with shared snapshot
let batcher = Compiler::new(root)
    .into_batch()
    .with_inputs_obj(inputs)
    .with_snapshot_from(&files)?;

// Batch scan (Eval-only, skips Layout)
let scans = batcher.batch_scan(&files)?;

// Filter drafts, then compile
let non_drafts: Vec<_> = files.iter()
    .zip(&scans)
    .filter(|(_, r)| r.as_ref().map(|s| !s.is_draft()).unwrap_or(false))
    .map(|(p, _)| p)
    .collect();

// Batch compile with progress callback
let results = batcher.batch_compile_each(&non_drafts, |path| {
    println!("Compiled: {}", path.display());
})?;

// Batch compile with per-file context
let results = batcher.batch_compile_with_context(&files, |path| {
    serde_json::json!({
        "current_file": path.to_string_lossy(),
    })
})?;
```

### Fast Scanning

```rust
use typst_batch::prelude::*;

// Single file scan
let result = Scanner::new(path, root).scan()?;
let links = result.links();
let headings = result.headings();
let meta = result.metadata("post-meta");

// Batch scan (lightweight, no fonts)
let scanner = Batcher::for_scan(root)
    .with_snapshot_from(&files)?;
let scans = scanner.batch_scan(&files)?;
```

### Virtual File System

```rust
use typst_batch::prelude::*;

let mut vfs = MapVirtualFS::new();
vfs.insert("/_data/site.json", r#"{"title":"My Blog"}"#);
set_virtual_fs(vfs);
```

In Typst:
```typst
#let site = json("/_data/site.json")
= #site.title
```

### SVG Frame Rendering

```rust
use typst_batch::prelude::*;

let result = Compiler::new(root).with_path(path).compile()?;
let doc = result.document();

// Collect frames from document tree
let frames: Vec<HtmlFrame> = collect_frames(&doc);

// Render frames to SVG (parallel with `batch` feature)
let svgs: Vec<String> = doc.render_frames(&frames);
```

### Diagnostics

```rust
use typst_batch::prelude::*;

let result = Compiler::new(root).with_path(path).compile()?;

// Filter out unwanted diagnostics
let filtered = result.diagnostics().filter_out(&[
    DiagnosticFilter::new(DiagnosticSeverity::Warning, FilterType::HtmlExport),
    DiagnosticFilter::new(DiagnosticSeverity::Warning, FilterType::Package(PackageKind::AllPreview)),
]);

if !filtered.is_empty() {
    eprintln!("{}", filtered);
}
```

## Modules

| Module | Description |
|--------|-------------|
| `process` | Compile and scan APIs (`Compiler`, `Scanner`, `Batcher`) |
| `html` | HTML document types (`HtmlDocument`, `HtmlElement`, `HtmlFrame`) |
| `codegen` | JSON ↔ Typst value conversion |
| `resource` | Shared resources (fonts, packages, file cache) |
| `world` | Typst World implementation |
| `diagnostic` | Error formatting and filtering |

## Typst Access

For advanced use cases:

```rust
use typst_batch::unstable::typst;
use typst_batch::unstable::typst_html;
```

## Requirements

- Typst 0.14.1
- Rust Edition 2024

## License

MIT