typst-as-lib 0.14.0

Small wrapper for typst that makes it easier to use it as a templating engine
Documentation
# Typst as lib

Small wrapper around [Typst](https://github.com/typst/typst) that makes it easier to use it as a templating engine.
This API is currently not really stable, although I try to implement the features with as little change to the API as possible.

## Usage

#### rust code

```rust
// main.rs
static TEMPLATE_FILE: &str = include_str!("./templates/template.typ");
static FONT: &[u8] = include_bytes!("./fonts/texgyrecursor-regular.otf");
static OUTPUT: &str = "./examples/output.pdf";
static IMAGE: &[u8] = include_bytes!("./templates/images/typst.png");

fn main() {
    // Read in fonts and the main source file.
    // We can use this template more than once, if needed (Possibly
    // with different input each time).
    let template = TypstEngine::builder()
        .main_file(TEMPLATE_FILE)
        .fonts([FONT])
        .build();

    // Run it
    let doc = template
        .compile_with_input(dummy_data())
        .output
        .expect("typst::compile() returned an error!");

    // Create pdf
    let options = Default::default();
    let pdf = typst_pdf::pdf(&doc, &options)
        .expect("Could not generate pdf.");
    fs::write(OUTPUT, pdf).expect("Could not write pdf.");
}
```

[Full example file](https://github.com/Relacibo/typst-as-lib/blob/main/examples/small_example.rs)

#### Typst code

```typ
// template.typ
#import sys: inputs

#set page(paper: "a4")
#set text(font: "TeX Gyre Cursor", 11pt)

#let content = inputs.v
#let last_index = content.len() - 1

#for (i, elem) in content.enumerate() [
  == #elem.heading
  Text: #elem.text \
  Num1: #elem.num1 \
  Num2: #elem.num2 \
  #if elem.image != none [#image.decode(elem.image, height: 40pt)]
  #if i < last_index [
    #pagebreak()
  ]
]
```

Run example with:

```bash
cargo r --example=small_example
```

## Resolving files

### Binaries and Sources

Use `TypstEngineBuilder::with_static_file_resolver` and add the binaries as key value pairs (`(file_name, &[u8])`) to add static binary files, that typst can use.

Use `TypstEngineBuilder::with_static_source_file_resolver` and add the sources as key value pairs (`(file_name, String)`) to add static `Source`s.

See example [resolve_static](https://github.com/Relacibo/typst-as-lib/blob/main/examples/resolve_static.rs) which uses the static file resolvers.

```bash
cargo r --example=resolve_static
```

### Local files

Resolving local files can be enabled with `TypstEngineBuilder::with_file_system_resolver`. The root should be the template folder. Files cannot be resolved, if they are outside of root.

Can be enabled like this:

```rust
let template = TypstEngine::builder()
    .main_file(TEMPLATE_FILE)
    .fonts([font])
    .with_file_system_resolver("./examples/templates")
    .build();
```

If you want to use another local package install path, use:

```rust
let template = TypstEngine::builder()
    .main_file(TEMPLATE_FILE)
    .fonts([font])
    .add_file_resolver(
        FileSystemResolver::new("./examples/templates")
            .with_local_package_root("local/packages")
            .into_cached()
    )
    .build();
```

### Remote packages

The features `package` and one of `ureq` or `reqwest` need to be enabled.

Can be enabled like this:

```rust
let template = TypstEngine::builder()
    .main_file(TEMPLATE_FILE)
    .fonts([font])
    .with_package_file_resolver()
    .build();
```

This uses the file system as a cache.

If you want to use another cache root path, use:

```rust
let template = TypstEngine::builder()
    .main_file(TEMPLATE_FILE)
    .fonts([font])
    .add_file_resolver(PackageResolverBuilder::new()
        .cache(
            FileSystemCache(PathBuf::from("cache/root"))
        )
        .build().into_cached()
    )
    .build();
```
Note that the Cache Wrapper created with the call to `into_cached(self)` creates a in memory cache for Binary files and `Source` files. 

If you want to instead use the memory as (binary) cache, use:

```rust
let template = TypstEngine::build()
    .main_file(TEMPLATE_FILE)
    .add_fonts([font])
    .add_file_resolver(PackageResolverBuilder::builder()
        .cache(
            InMemoryCache::new()
        )
        .build().into_cached()
    )
    .build();
```

Note that the Cache Wrapper created with the call to `into_cached(self)` only caches the `Source` files (each single file lazily) here and the `InMemoryCache` caches all binaries (eagerly after the first download of the whole package, which is triggered (lazily), when requested in a typst script).

### Local files and remote packages example

See example [resolve_packages](https://github.com/Relacibo/typst-as-lib/blob/main/examples/resolve_packages.rs) which uses the file and the package resolver.

```bash
cargo r --example=resolve_files --features=package
```

### Custom file resolver

You can also write your own file resolver. You need to implement the Trait `FileResolver` and pass it to the `TypstEngineBuilder::add_file_resolver` function. There you can also have some additional config options for the `PackageFileResolver`, `FileSystemResolver`, and so on.

## Loading fonts

You can simply add fonts to the `TypstEngine` with `TypstEngineBuilder::fonts`. You can also activate the feature `typst-kit-fonts` that adds `search_fonts_with` to `TypstEngineBuilder`, which uses the `typst-kit` library to resolve system fonts. You also might additionally use the feature `typst-kit-embed-fonts`, that activates the feature `embed-fonts` for `typst-kit`. This causes `typst-kit` to also embed fonts from [typst-assets](https://github.com/typst/typst-assets) at compile time.

See example [font_searcher](https://github.com/Relacibo/typst-as-lib/blob/main/examples/font_searcher.rs).

```bash
cargo r --example=font_searcher --features=typst-kit-fonts,typst-kit-embed-fonts
```

### main file

The `TypstEngine::main_file` call is not needed, it's just for conveniance. You can omit it, and then you pass it to the `TypstEngine::compile` call later. (See example [resolve_static](https://github.com/Relacibo/typst-as-lib/blob/main/examples/resolve_static.rs))

## Previous work

- [https://github.com/tfachmann/typst-as-library]https://github.com/tfachmann/typst-as-library

## Maybe useful

- [https://github.com/KillTheMule/derive_typst_intoval]https://github.com/KillTheMule/derive_typst_intoval