A no-longer-minimal protocol to write typst plugins, featured with:
- auto bi-convert between typst and Nim types like float, string and tables
- support default arguments and
varargs - ability to export existing function to typst, via
export_typst_from - reserving doc from Nim to typst, means no need to write document twice (turn off via compile flag
-d:exportNimDocToTypst=off) - alternative cbor engine to choose, via
-d:cborious1 - Fine-grained control over exported name, serialization & deserialization (ref datetime-parse example)
For other languages like Rust, ref https://github.com/astrale-sharp/wasm-minimal-protocol, which is however really
minimal(lacks features above).
Nim plugins can use this repo to automatically implement the protocol with a macro:
# Nim file
# /path/to/plugin.nim
import pkg/wasm_minmal_protocol
import std/[math, strutils]
from std/sugar import `->`
# used as `{.exportc.}`
func mew(n: int): string{.export_typst.} =
"mew~".repeat n
export_typst_from_func spaces
export_typst_from_func fac, "factorial"
export_typst_from_func formatSize, ncTypst # use typst name convention
# overloaded functions must be specified with a signature:
export_typst_from_func cbrt, (float) -> float
export_typst_from_func format, "str-format", (string, varargs[string]) -> string
export_typst_from_func strCount, "str-count", (string, string) -> string
# or `export_typst_from fac` to export as `fac`compile using the binary this package provide, nim-typst-plugin (available if install via nimble install,
or after nimble build, it'll be in ./bin/ directory)
nim-typst-plugin -d:gen_typst /path/to/plugin.nimNote this reply on your Nim installation and
wasi-stub(see below)
-d:gen_typstto also generate .typ file for handy use, other than bare.wasm
Then write:
// Typst file
#import "/path/to/plugin.typ": *
// no need to call cbor
#assert.eq(2.0, cbrt(8.0))
#str-format("$1 $2 was somehow translated literally", "violet", "evergarden")
#str-format("$# and $# refer to each", "spice", "wolf")
#assert.eq(str-count("litlighilit", "i"), 4)
#factorial(3)You should also take a look at this repository's examples.
The runtime used by typst do not allow the plugin to import any function (beside the ones used by the protocol). In particular, if your plugin is compiled for WASI, it will not be able to be loaded by typst.
To get around that, you can use wasi-stub. It will detect all WASI-related imports, and replace them by stubs that do nothing.
Install it from wasi-stub repo,
either via cargo or Github Release
Footnotes
-
requires manually installation like
nimble install cborious↩