Skip to main content

Crate glyphweaveforge

Crate glyphweaveforge 

Source
Expand description

GlyphWeaveForge is a Markdown-to-PDF library with explicit adapter boundaries.

The public API is centered on Forge, with stable builder-style configuration for source selection, output selection, page settings, theme selection, backend selection, and adapter injection.

GlyphWeaveForge

Crates.io docs.rs License: MIT Made with Rust Documentation

§GlyphWeaveForge

GlyphWeaveForge converts Markdown into PDF through a small Rust pipeline with explicit boundaries:

api -> pipeline -> core -> adapters

The crate ships a lightweight built-in renderer by default and can optionally use Typst without changing the public builder API.

§What the crate provides today

  • A fluent Forge builder for Markdown-to-PDF conversion.
  • Three input modes: UTF-8 text, UTF-8 bytes, and filesystem paths (fs feature).
  • Three output modes: in-memory bytes, explicit file path, and output directory (fs feature).
  • Built-in page sizes (A4, Letter, Legal, custom millimeter sizes).
  • Built-in layout modes (Paged, SinglePage).
  • Built-in themes with optional JSON overrides.
  • Resource resolution through filesystem lookup (fs) or caller-provided resolvers.
  • Renderer extension points through public RenderBackend and ResourceResolver traits.
  • Two backend selections behind a stable builder API: Minimal by default and Typst when the feature is enabled.

§Installation

[dependencies]
glyphweaveforge = "0.1.6"

Enable optional features when you need them:

[dependencies]
glyphweaveforge = { version = "0.1.3", features = ["renderer-typst"] }

§Main builder flow

use glyphweaveforge::Forge;

let pdf = Forge::new()
    .from_text("# Hello\n\nWorld")
    .to_memory()
    .convert()
    .expect("conversion should succeed");

let bytes = pdf.bytes.expect("memory output should contain PDF bytes");
assert!(bytes.starts_with(b"%PDF"));

Forge::new() starts with these defaults:

  • source: not set
  • output: not set
  • backend: RenderBackendSelection::Minimal
  • page size: PageSize::A4
  • layout mode: LayoutMode::Paged
  • theme: BuiltInTheme::Professional

§Supported inputs and outputs

Always available:

  • from_text
  • from_bytes
  • to_memory
  • injected resource resolvers through with_resource_resolver or with_resource_adapter
  • explicit backend selection through with_backend
  • custom renderer injection through with_renderer
  • full option replacement through with_options

Available with the default fs feature:

  • from_path
  • to_file
  • to_directory
  • with_output_file_name for directory outputs
  • filesystem-based resource lookup for local assets relative to the markdown file

§Output behavior

  • to_memory() returns PdfOutput { bytes: Some(...), written_path: None }.
  • to_file(...) writes the PDF and returns PdfOutput { bytes: None, written_path: Some(...) }.
  • to_directory(...) creates the directory if needed and derives the file name from the source name unless with_output_file_name(...) overrides it.

When deriving a directory output name, the crate appends .pdf if it is missing.

§Page sizes, layout modes, and themes

§Page sizes

  • PageSize::A4
  • PageSize::Letter
  • PageSize::Legal
  • PageSize::Custom { width_mm, height_mm }

Custom page sizes must be strictly positive.

§Layout modes

  • LayoutMode::Paged: paginates rendered lines across pages.
  • LayoutMode::SinglePage: keeps the rendered content in a single page payload.

§Built-in themes

  • BuiltInTheme::Invoice
  • BuiltInTheme::ScientificArticle
  • BuiltInTheme::Professional (default)
  • BuiltInTheme::Engineering
  • BuiltInTheme::Informational

with_theme(...) selects a built-in preset. with_theme_config(...) lets you combine an optional built-in theme with JSON overrides such as:

  • name
  • body_font_size_pt
  • code_font_size_pt
  • heading_scale
  • margin_mm

The Typst backend applies the full theme profile, including fonts, colors, margins, body/code sizes, and heading scale. The default minimal backend is a fallback PDF writer; it applies layout-affecting values such as margins and font sizes, while color and font-family overrides are represented only in the resolved theme profile.

Current theme profiles do not yet expose explicit controls for line height, paragraph alignment/indentation, multi-column layout, or page background color. Built-in presets therefore approximate those style guides through currently supported properties (fonts, sizes, heading scale, margins, and palette).

Example:

use glyphweaveforge::{BuiltInTheme, Forge, LayoutMode, PageSize, ThemeConfig};
use serde_json::json;

let pdf = Forge::new()
    .from_text("# Report\n\nBody")
    .to_memory()
    .with_page_size(PageSize::Letter)
    .with_layout_mode(LayoutMode::SinglePage)
    .with_theme_config(ThemeConfig {
        built_in: Some(BuiltInTheme::Engineering),
        custom_theme_json: Some(json!({
            "name": "custom-engineering",
            "margin_mm": 14.0
        })),
    })
    .convert()
    .expect("conversion should succeed");

assert!(pdf.bytes.expect("bytes should exist").starts_with(b"%PDF"));

§Backend selection

The default build uses the minimal built-in renderer. To opt into the Typst backend, enable renderer-typst and select it explicitly:

use glyphweaveforge::{Forge, RenderBackendSelection};

let pdf = Forge::new()
    .from_text("# Hello from Typst")
    .to_memory()
    .with_backend(RenderBackendSelection::Typst)
    .convert()
    .expect("typst backend should succeed");

assert!(pdf.bytes.expect("bytes should exist").starts_with(b"%PDF"));

Backends exposed by the public API:

  • RenderBackendSelection::Minimal: always available in the default feature set.
  • RenderBackendSelection::Typst: available when renderer-typst is enabled.

The typst Cargo feature is a compatibility alias for renderer-typst.

If you need complete control, with_renderer(...) accepts any type implementing the public RenderBackend trait and overrides the built-in backend selection.

§Feature matrix

  • fs (default): enables path-based source/output helpers and filesystem resource loading.
  • renderer-minimal (default): keeps the built-in lightweight renderer enabled and addressable in tests/documentation.
  • renderer-typst: enables the Typst-backed renderer.
  • typst: compatibility alias for renderer-typst.
  • mermaid: enables a Rust-native Mermaid subset renderer for the Typst backend (no Node/npm/network required). Unsupported Mermaid syntax remains visible through explicit fallback notices.
  • Mermaid fenced-block rendering is available through this Rust-native subset renderer.
  • math: enables GFM math parsing ($...$, $$...$$) and TeX-subset conversion for real Typst math rendering. The minimal renderer remains a readable text fallback.

§Current Markdown behavior

Supported today:

  • headings
  • paragraphs
  • emphasis/strong text
  • inline code
  • links
  • unordered and ordered lists
  • block quotes
  • thematic breaks
  • fenced code blocks
  • images, including injected resolvers and memory-backed assets
  • basic HTML <img> tags with src/alt
  • tables

Resource handling behavior:

  • For path-based markdown sources with the fs feature, local assets are resolved relative to the markdown file directory.
  • For text/bytes sources, you can inject assets with with_resource_resolver(...) or with_resource_adapter(...).
  • Missing assets remain visible in the output as explicit fallback text.

Unsupported advanced Markdown stays visible instead of silently disappearing. Examples include:

  • footnotes
  • Mermaid diagrams (Rust-native rendering on Typst for supported subset types when mermaid + renderer-typst are enabled; unsupported syntax remains explicit fallback)
  • unsupported TeX environments/commands are surfaced as visible conversion notices in Typst output
  • unsupported raw HTML beyond basic <img> extraction

These paths render deterministic fallback labels with the original content preserved in the output when possible.

§Math support details

  • Inline math uses $...$ and display math uses $$...$$ in Markdown.
  • The Typst backend renders real math with Typst delimiters after converting a practical TeX subset.
  • Supported subset includes \frac, \sqrt, grouped superscripts/subscripts, \sum, \prod, \int, \lim, common Greek letters (\alpha, \beta, \gamma, \delta, \lambda, \pi, \sigma, \Omega, \Delta), symbols (\pm, \infty, \approx, \neq, \leq, \geq, \le, \ge, \to, \cdot, \times), spacing/wrappers (\,, \qquad, \left, \right), and common functions (\sin, \cos, \exp, \partial).
  • Unsupported environments (\begin{...} / \end{...}) and unknown commands produce explicit, visible error notices in Typst output instead of silent data loss.
  • Fenced code blocks like ```math are still treated as code fences (honest fallback), not as math AST nodes.

§Extending the crate

§Custom resource resolver

use std::io;

use glyphweaveforge::Forge;

let pdf = Forge::new()
    .from_text("![Logo](logo.png)")
    .to_memory()
    .with_resource_resolver(|href| {
        if href == "logo.png" {
            Ok(vec![1, 2, 3])
        } else {
            Err(io::Error::new(io::ErrorKind::NotFound, "missing"))
        }
    })
    .convert()
    .expect("conversion should succeed");

assert!(pdf.bytes.expect("bytes should exist").starts_with(b"%PDF"));

§Custom renderer

use glyphweaveforge::{Document, Forge, RenderBackend, RenderRequest, Result};

struct StubRenderer;

impl RenderBackend for StubRenderer {
    fn render(&self, _document: &Document, _request: &RenderRequest) -> Result<Vec<u8>> {
        Ok(b"stub-pdf".to_vec())
    }
}

let pdf = Forge::new()
    .from_text("hello")
    .to_memory()
    .with_renderer(StubRenderer)
    .convert()
    .expect("custom renderer should be used");

assert_eq!(pdf.bytes, Some(b"stub-pdf".to_vec()));

The public extension traits are:

  • RenderBackend
  • ResourceResolver

The rendering request/asset helper types exposed for adapters are:

  • RenderRequest
  • ResolvedAsset
  • ResourceStatus

§Limitations

  • This crate does not claim real Mermaid diagram rendering.
  • This crate does not claim real TeX/LaTeX or advanced math typesetting.
  • Footnotes are exposed through visible fallback text rather than full layout support.
  • General raw HTML is not a full rendering target; basic <img> extraction is supported, but broader HTML layout is not.
  • The minimal renderer writes a compact PDF text stream; it is designed for deterministic output and testability rather than rich page design.
  • renderer-typst is optional; docs.rs for the default documentation build does not require Typst support to use the crate.

§Public error and result types

  • Result<T> is an alias for std::result::Result<T, ForgeError>.
  • ForgeError::MissingSource and ForgeError::MissingOutput protect incomplete builder usage.
  • ForgeError::InputRead and ForgeError::InvalidUtf8 cover source loading.
  • ForgeError::Resource covers resolver failures.
  • ForgeError::InvalidConfiguration covers invalid runtime options such as non-positive custom page sizes.
  • ForgeError::Render, ForgeError::TypstCompile, ForgeError::TypstExport, and ForgeError::TypstAsset cover backend/rendering failures.
  • ForgeError::OutputWrite, ForgeError::OutputDirectory, and ForgeError::InvalidOutputFileName cover output persistence.

§Architecture note

Release work should preserve the internal boundary:

api -> pipeline -> core -> adapters

§Documentation

Full documentation is available at gustavogutierrez.github.io/glyph-weave-forge:

  • Getting Started — installation, quick start, feature flags
  • API Reference — complete builder API, types, and error handling
  • Contributing — how to contribute, areas to improve, pre-commit checklist

§Author

Created by Gustavo Gutiérrez — Bogotá, Colombia.

§License

MIT — see LICENSE for details.

Structs§

ConvertOptions
Conversion options used by the builder and pipeline.
Document
Forge
Main entrypoint for Markdown to PDF conversion.
PdfOutput
Result of a conversion.
RenderRequest
Render input passed to a RenderBackend.
ResolvedAsset
Resolved asset payload returned by a ResourceResolver.
ResourceContext
ThemeConfig
Theme selection and optional JSON overrides.

Enums§

BuiltInTheme
Predefined visual themes.
ForgeError
Errors produced by the conversion pipeline.
LayoutMode
Output pagination strategy.
MarkdownSource
Supported markdown input sources.
OutputTarget
Supported PDF output targets.
PageSize
Target page size.
RenderBackendSelection
Built-in renderer backends available through the composition layer.
ResourceStatus

Traits§

RenderBackend
Port for PDF rendering adapters.
ResourceResolver
Port for asset/resource resolution adapters.

Type Aliases§

Result
Crate-wide result type.