typst

package module
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 13, 2025 License: MIT Imports: 20 Imported by: 0

README

go-typst test

go-typst is a Go library that leverages the command-line interface of Typst to provide functions for the creation of documents and reports in various formats (PDF, SVG, PNG, HTML). Its goal is to provide Go developers with a seamless, "Go-like" interface to Typst's powerful document generation capabilities.

Stability and Compatibility

go-typst is a work in progress, and the API may change as Typst evolves. Supported Typst versions are tested by unit tests to ensure compatibility.

Supported Versions:

  • Typst 0.12.0
  • Typst 0.13.0
  • Typst 0.13.1
  • Typst 0.14.0
  • Typst 0.14.1
  • Typst 0.14.2

While breaking changes may occur, i aim to minimize disruptions. Use at your own discretion for production systems.

Features

  • PDF, SVG, PNG and HTML generation.
  • All Typst parameters are discoverable and documented in options.go.
  • Go-to-Typst Value Encoder: Seamlessly encode any Go values as Typst markup.
  • Encode and inject images as a Typst markup simply by wrapping image.Image types or raw image data.
  • Errors from Typst CLI are returned as structured Go error objects with detailed information, such as line numbers and file paths.
  • Uses stdio; No temporary files will be created.
  • Supports native Typst installations and the official Docker image.
  • Good unit test coverage.

Installation

Use go get github.com/Dadido3/go-typst inside of your project to add this module to your project.

Usage

This module needs either a native installation of Typst, or a working Docker installation. The following subsections will show how to use this library in detail.

Native Typst installation

The basic usage pattern for calling a natively installed Typst executable looks like this:

typstCaller := typst.CLI{}

err := typstCaller.Compile(input, output, options)

In this case the module assumes that the Typst executable is accessible from your system's PATH. Ensure that you have Typst installed on any machine that your project will be executed. You can install it by following the instructions in the Typst repository.

Alternatively you can pack the Typst executable with your application. In this case you have to provide the path to the executable when setting up the typst.CLI object:

typstCaller := typst.CLI{
    ExecutablePath: "./typst", // Relative path to executable.
}

[!NOTE] Make sure to follow the Typst license requirements when you pack and distribute the Typst executable with your software.

Official Docker image

To use the official Typst Docker image ensure that you have a working Docker installation.

go-typst will automatically pull and run a Docker container with the latest supported Typst image. The basic usage pattern is similar to the CLI variant:

typstCaller := typst.Docker{}

err := typstCaller.Compile(input, output, options)
Tips and tricks

As the Typst instance that's running inside the container is fully encapsulated, you have pass through any resources manually. This requires a bit more set up than using a native installation.

Let's say you want to compile a document which imports other local Typst markup files. In this case you have to ensure that you mount any needed folders and files to the Docker container. You also have to set up the root of Typst to that mounted directory, or a parent of it:

typstCaller := typst.Docker{
    Volumes: []string{"./test-files:/markup"},
}

r := bytes.NewBufferString(`#include "hello-world.typ"`)

var w bytes.Buffer
err := typstCaller.Compile(r, &w, &typst.OptionsCompile{Root: "/markup"})

This will mount ./test-files to /markup inside the Docker container. When Typst compiles the input buffer r, it expects ./test-files/hello-world.typ to exist outside of the container.

Another thing is that the Dockerized version of Typst doesn't see your system fonts. To get all your system fonts mounted into the container, you can add the volume parameter /usr/share/fonts:/usr/share/fonts to your typst.Docker. For example:

typstCaller := typst.Docker{
    Volumes: []string{
        "./test-files:/markup",
        "/usr/share/fonts:/usr/share/fonts",
    },
}

The same applies when you want to use custom fonts. You need to mount the folder containing the fonts, and then you have to tell Typst where the fonts are mounted to inside the container:

typstCaller := typst.Docker{
    Volumes: []string{"./test-files:/fonts"},
}

err := typstCaller.Compile(input, output, &typst.OptionsCompile{FontPaths: []string{"/fonts"}})
Named Docker containers

If you have an already running Docker container that you want to (re)use, you can use typst.DockerExec to invoke the Typst executable inside any running container by its name:

typstCaller := typst.DockerExec{
    ContainerName: "typst",
}

err := typstCaller.Compile(input, output, options)

This method has a lower latency than using typst.Docker, as it doesn't need to spin up a Docker container every call. But you need to manage the lifetime of the Container yourself, or use a Docker orchestrator.

Caller interface

typst.CLI, typst.Docker and typst.DockerExec implement the typst.Caller interface.

Examples

Simple document

Here we will create a simple document by passing a reader with Typst markup into typstCaller.Compile and then let it write the resulting SVG data into a file:

func main() {
    markup := bytes.NewBufferString(`#set page(width: 100mm, height: auto, margin: 5mm)
= go-typst

A library to generate documents and reports by utilizing the command line version of Typst.
#footnote[https://typst.app/]

== Features

- Encoder to convert Go objects into Typst objects which then can be injected into Typst documents.
- Parsing of returned errors into Go error objects.
- Uses stdio; No temporary files need to be created.
- Test coverage of most features.`)

    typstCaller := typst.CLI{}

    f, err := os.Create(filepath.Join(".", "documentation", "images", "readme-example-simple.svg"))
    if err != nil {
        t.Fatalf("Failed to create output file: %v.", err)
    }
    defer f.Close()

    if err := typstCaller.Compile(markup, f, &typst.OptionsCompile{Format: typst.OutputFormatSVG}); err != nil {
        t.Fatalf("Failed to compile document: %v.", err)
    }
}

Output:

readme-example-simple.svg

Value injection

If you need to create documents that rely on data coming from your Go application, you can use typst.InjectValues to encode any Go variables, structures, maps, arrays, slices into their respective Typst markup counterparts:

func main() {
    customValues := map[string]any{
        "time":       time.Now(),
        "customText": "Hey there!",
        "struct": struct {
            Foo int
            Bar []string
        }{
            Foo: 123,
            Bar: []string{"this", "is", "a", "string", "slice"},
        },
    }

    // Inject Go values as Typst markup.
    var markup bytes.Buffer
    if err := typst.InjectValues(&markup, customValues); err != nil {
        t.Fatalf("Failed to inject values into Typst markup: %v.", err)
    }

    // Add some Typst markup using the previously injected values.
    markup.WriteString(`#set page(width: 100mm, height: auto, margin: 5mm)
#customText Today's date is #time.display("[year]-[month]-[day]") and the time is #time.display("[hour]:[minute]:[second]").

#struct`)

    f, err := os.Create(filepath.Join(".", "documentation", "images", "readme-example-injection.svg"))
    if err != nil {
        t.Fatalf("Failed to create output file: %v.", err)
    }
    defer f.Close()

    typstCaller := typst.CLI{}
    if err := typstCaller.Compile(&markup, f, &typst.OptionsCompile{Format: typst.OutputFormatSVG}); err != nil {
        t.Fatalf("Failed to compile document: %v.", err)
    }
}

Output:

readme-example-injection.svg

More examples

It's also possible to write Typst templates that can be invoked from go-typst. A full setup can be found in the passing-values example package.

Documentation

Index

Constants

View Source
const DockerDefaultImage = "ghcr.io/typst/typst:0.14.2"

The default Docker image to use. This is the latest supported version of Typst.

Variables

View Source
var ExecutablePath = "typst"

The path to the Typst executable.

Functions

func CleanIdentifier

func CleanIdentifier(input string) string

CleanIdentifier will return the input cleaned up in a way so that it can safely be used as a Typst identifier. This function will replace all illegal characters, which means collisions are possible in some cases.

See https://github.com/typst/typst/blob/76c24ee6e35715cd14bb892d7b6b8d775c680bf7/crates/typst-syntax/src/lexer.rs#L932 for details.

func InjectValues added in v0.3.0

func InjectValues(output io.Writer, values map[string]any) error

InjectValues will write the given key-value pairs as Typst markup into output. This can be used to inject Go values into Typst documents.

Every key in values needs to be a valid identifier, otherwise this function will return an error. Every value in values will be marshaled according to ValueEncoder into equivalent Typst markup.

Passing {"foo": 1, "bar": 60 * time.Second} as values will produce the following output:

#let foo = 1
#let bar = duration(seconds: 60)

func IsIdentifier

func IsIdentifier(input string) bool

IsIdentifier will return whether input is a valid typst identifier.

See https://github.com/typst/typst/blob/76c24ee6e35715cd14bb892d7b6b8d775c680bf7/crates/typst-syntax/src/lexer.rs#L932 for details.

func MarshalValue added in v0.3.0

func MarshalValue(v any) ([]byte, error)

MarshalValue takes any Go type and returns a Typst markup representation as a byte slice.

func MarshalVariable deprecated

func MarshalVariable(v any) ([]byte, error)

Deprecated: Use MarshalValue instead, as this will be removed in a future version.

func ParseStderr

func ParseStderr(stderr string, inner error) error

ParseStderr will parse the given stderr output and return a typst.Error.

Types

type CLI

type CLI struct {
	ExecutablePath   string // The Typst executable path can be overridden here. Otherwise the default path will be used.
	WorkingDirectory string // The path where the Typst executable is run in. When left empty, the Typst executable will be run in the process's current directory.
}

CLI allows you to invoke commands on a native Typst executable.

func (CLI) Compile

func (c CLI) Compile(input io.Reader, output io.Writer, options *OptionsCompile) error

Compile takes a Typst document from input, and renders it into the output writer. The options parameter is optional, and can be nil.

func (CLI) CompileWithVariables deprecated

func (c CLI) CompileWithVariables(input io.Reader, output io.Writer, options *OptionsCompile, variables map[string]any) error

Deprecated: You should use typst.InjectValues in combination with the normal Compile method instead.

func (CLI) Fonts added in v0.7.0

func (c CLI) Fonts(options *OptionsFonts) ([]string, error)

Fonts returns all fonts that are available to Typst. The options parameter is optional, and can be nil.

func (CLI) VersionString

func (c CLI) VersionString() (string, error)

VersionString returns the Typst version as a string.

type CLIOptions deprecated

type CLIOptions = OptionsCompile

Deprecated: Use typst.OptionsCompile instead.

type Caller added in v0.7.0

type Caller interface {
	// VersionString returns the Typst version as a string.
	VersionString() (string, error)

	// Fonts returns all fonts that are available to Typst.
	// The options parameter is optional, and can be nil.
	Fonts(options *OptionsFonts) ([]string, error)

	// Compile takes a Typst document from the supplied input reader, and renders it into the output writer.
	// The options parameter is optional, and can be nil.
	Compile(input io.Reader, output io.Writer, options *OptionsCompile) error
}

Caller contains all Typst commands that are supported by this library.

type Docker added in v0.7.0

type Docker struct {
	Image            string // The image to use, defaults to the latest supported official Typst Docker image if left empty. See: typst.DockerDefaultImage.
	WorkingDirectory string // The working directory of Docker. When left empty, Docker will be run with the process's current working directory.

	// Additional bind-mounts or volumes that are passed via "--volume" flag to Docker.
	// For details, see: https://docs.docker.com/engine/storage/volumes/#syntax
	//
	// Example:
	//	typst.Docker{Volumes: []string{".:/markup"}} // This bind mounts the current working directory to "/markup" inside the container.
	//	typst.Docker{Volumes: []string{"/usr/share/fonts:/usr/share/fonts"}} // This makes all system fonts available to Typst running inside the container.
	Volumes []string

	// Custom "docker run" command line options go here.
	// For all available options, see: https://docs.docker.com/reference/cli/docker/container/run/
	//
	// Example:
	//	typst.Docker{Custom: []string{"--user", "1000"}} // Use a non-root user inside the docker container.
	Custom []string // Custom "docker run" command line options go here.
}

Docker allows you to invoke commands on a Typst Docker image.

This uses docker run to automatically pull and run a container. Therefore the container will start and stop automatically. To have more control over the lifetime of a Docker container see typst.DockerExec.

func (Docker) Compile added in v0.7.0

func (d Docker) Compile(input io.Reader, output io.Writer, options *OptionsCompile) error

Compile takes a Typst document from input, and renders it into the output writer. The options parameter is optional, and can be nil.

func (Docker) Fonts added in v0.7.0

func (d Docker) Fonts(options *OptionsFonts) ([]string, error)

Fonts returns all fonts that are available to Typst. The options parameter is optional, and can be nil.

func (Docker) VersionString added in v0.7.0

func (d Docker) VersionString() (string, error)

VersionString returns the Typst version as a string.

type DockerExec added in v0.8.0

type DockerExec struct {
	ContainerName string // The name of the running container you want to invoke Typst in.
	TypstPath     string // The path to the Typst executable inside of the container. Defaults to `typst` if left empty.

	// Custom "docker exec" command line options go here.
	// For all available options, see: https://docs.docker.com/reference/cli/docker/container/exec/
	//
	// Example:
	//	typst.DockerExec{Custom: []string{"--user", "1000"}} // Use a non-root user inside the docker container.
	Custom []string
}

DockerExec allows you to invoke Typst commands in a running Docker container.

This uses docker exec, and therefore needs you to set up a running container beforehand. For a less complex setup see typst.Docker.

func (DockerExec) Compile added in v0.8.0

func (d DockerExec) Compile(input io.Reader, output io.Writer, options *OptionsCompile) error

Compile takes a Typst document from input, and renders it into the output writer. The options parameter is optional, and can be nil.

func (DockerExec) Fonts added in v0.8.0

func (d DockerExec) Fonts(options *OptionsFonts) ([]string, error)

Fonts returns all fonts that are available to Typst. The options parameter is optional, and can be nil.

func (DockerExec) VersionString added in v0.8.0

func (d DockerExec) VersionString() (string, error)

VersionString returns the Typst version as a string.

type Error

type Error struct {
	Inner error

	Raw string // The raw output from stderr.

	// Raw output parsed into errors and warnings.
	Details []ErrorDetails
}

Error represents an error as returned by Typst. This can contain multiple sub-errors or sub-warnings which are listed in the field Details.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type ErrorDetails added in v0.2.0

type ErrorDetails struct {
	Message string // The parsed error message.
	Path    string // Path of the Typst file where the error is located in. Zero value means that there is no further information.
	Line    int    // Line number of the error. Zero value means that there is no further information.
	Column  int    // Column of the error. Zero value means that there is no further information.
}

ErrorDetails contains the details of a typst.Error.

type Image

type Image struct{ image.Image }

Image can be used to encode any image.Image into a Typst image.

For this, just wrap any image.Image with this type before passing it to MarshalValue or a ValueEncoder:

typstImage := typst.Image{img}
typst.InjectValues(&r, map[string]any{"TestImage": typstImage})

func (Image) MarshalTypstValue added in v0.3.0

func (i Image) MarshalTypstValue() ([]byte, error)

type ImageRaw added in v0.6.0

type ImageRaw []byte

ImageRaw can be used to pass the raw data of any image to Typst. This will pass the raw byte values of a PNG, JPEG or any other image format that is supported by Typst.

For this, just wrap any byte slice with this type before passing it to MarshalValue or a ValueEncoder:

typstImage := typst.ImageRaw(bufferPNG)
typst.InjectValues(&r, map[string]any{"TestImage": typstImage})

func (ImageRaw) MarshalTypstValue added in v0.6.0

func (i ImageRaw) MarshalTypstValue() ([]byte, error)

type OptionsCompile added in v0.7.0

type OptionsCompile struct {
	Root                string            // Configures the project root (for absolute paths).
	Input               map[string]string // String key-value pairs visible through `sys.inputs`.
	FontPaths           []string          // Adds additional directories that are recursively searched for fonts.
	IgnoreSystemFonts   bool              // Ensures system fonts won't be searched, unless explicitly included via FontPaths.
	IgnoreEmbeddedFonts bool              // Disables the use of fonts embedded into the Typst binary. (Available since Typst 0.14.0)
	NoPDFTags           bool              // Disables the automatic generation of accessibility tags. These are emitted when no particular standard like PDF/UA-1 is selected to provide a baseline of accessibility. (Available since Typst 0.14.0)
	CreationTime        time.Time         // The document's creation date. For more information, see https://reproducible-builds.org/specs/source-date-epoch/.
	PackagePath         string            // Custom path to local packages, defaults to system-dependent location.
	PackageCachePath    string            // Custom path to package cache, defaults to system-dependent location.
	Jobs                int               // Number of parallel jobs spawned during compilation, defaults to number of CPUs. Setting it to 1 disables parallelism.

	// Which pages to export. When unspecified, all document pages are exported.
	//
	// Pages to export are separated by commas, and can be either simple page numbers (e.g. '2,5' to export only pages 2 and 5) or page ranges (e.g. '2,3-6,8-' to export page 2, pages 3 to 6 (inclusive), page 8 and any pages after it).
	//
	// Page numbers are one-indexed and correspond to real page numbers in the document (therefore not being affected by the document's page counter).
	Pages string

	Format OutputFormat // The format of the output file, inferred from the extension by default.
	PPI    int          // The PPI (pixels per inch) to use for PNG export. Defaults to 144.

	// One (or multiple) PDF standards that Typst will enforce conformance with.
	//
	// See typst.PDFStandard for possible values.
	PDFStandards []PDFStandard

	Custom []string // Custom command line options go here.
}

OptionsCompile contains all supported parameters for the compile command.

func (*OptionsCompile) Args added in v0.7.0

func (o *OptionsCompile) Args() (result []string)

Args returns a list of CLI arguments that should be passed to the executable.

type OptionsFonts added in v0.7.0

type OptionsFonts struct {
	FontPaths           []string // Adds additional directories that are recursively searched for fonts.
	IgnoreSystemFonts   bool     // Ensures system fonts won't be searched, unless explicitly included via FontPaths.
	IgnoreEmbeddedFonts bool     // Disables the use of fonts embedded into the Typst binary. (Available since Typst 0.14.0)
	Variants            bool     // Also lists style variants of each font family.

	Custom []string // Custom command line options go here.
}

OptionsFonts contains all supported parameters for the fonts command.

func (*OptionsFonts) Args added in v0.7.0

func (o *OptionsFonts) Args() (result []string)

Args returns a list of CLI arguments that should be passed to the executable.

type OutputFormat

type OutputFormat string
const (
	OutputFormatAuto OutputFormat = ""

	OutputFormatPDF  OutputFormat = "pdf"
	OutputFormatPNG  OutputFormat = "png"
	OutputFormatSVG  OutputFormat = "svg"
	OutputFormatHTML OutputFormat = "html" // this format is only available since 0.13.0
)

type PDFStandard added in v0.3.0

type PDFStandard string
const (
	PDFStandard1_4 PDFStandard = "1.4" // PDF 1.4 (Available since Typst 0.14.0)
	PDFStandard1_5 PDFStandard = "1.5" // PDF 1.5 (Available since Typst 0.14.0)
	PDFStandard1_6 PDFStandard = "1.6" // PDF 1.6 (Available since Typst 0.14.0)
	PDFStandard1_7 PDFStandard = "1.7" // PDF 1.7
	PDFStandard2_0 PDFStandard = "2.0" // PDF 2.0 (Available since Typst 0.14.0)

	PDFStandardA_1B PDFStandard = "a-1b" // PDF/A-1b (Available since Typst 0.14.0)
	PDFStandardA_1A PDFStandard = "a-1a" // PDF/A-1a (Available since Typst 0.14.0)
	PDFStandardA_2B PDFStandard = "a-2b" // PDF/A-2b
	PDFStandardA_2U PDFStandard = "a-2u" // PDF/A-2u (Available since Typst 0.14.0)
	PDFStandardA_2A PDFStandard = "a-2a" // PDF/A-2a (Available since Typst 0.14.0)
	PDFStandardA_3B PDFStandard = "a-3b" // PDF/A-3b (Available since Typst 0.13.0)
	PDFStandardA_3U PDFStandard = "a-3u" // PDF/A-3u (Available since Typst 0.14.0)
	PDFStandardA_3A PDFStandard = "a-3a" // PDF/A-3a (Available since Typst 0.14.0)
	PDFStandardA_4  PDFStandard = "a-4"  // PDF/A-4 (Available since Typst 0.14.0)
	PDFStandardA_4F PDFStandard = "a-4f" // PDF/A-4f (Available since Typst 0.14.0)
	PDFStandardA_4E PDFStandard = "a-4e" // PDF/A-4e (Available since Typst 0.14.0)
	PDFStandardUA_1 PDFStandard = "ua-1" // PDF/UA-1 (Available since Typst 0.14.0)
)

type ValueEncoder added in v0.3.0

type ValueEncoder struct {
	// contains filtered or unexported fields
}

func NewValueEncoder added in v0.3.0

func NewValueEncoder(w io.Writer) *ValueEncoder

NewValueEncoder returns a new encoder that writes into w.

func NewVariableEncoder deprecated

func NewVariableEncoder(w io.Writer) *ValueEncoder

Deprecated: Use NewValueEncoder instead, as this will be removed in a future version.

func (*ValueEncoder) Encode added in v0.3.0

func (e *ValueEncoder) Encode(v any) error

func (*ValueEncoder) EncodeByteSlice added in v0.3.0

func (e *ValueEncoder) EncodeByteSlice(bb []byte) error

type ValueMarshaler added in v0.3.0

type ValueMarshaler interface {
	MarshalTypstValue() ([]byte, error)
}

ValueMarshaler can be implemented by types to support custom Typst marshaling.

type VariableMarshaler deprecated

type VariableMarshaler interface {
	MarshalTypstVariable() ([]byte, error)
}

Deprecated: Use ValueMarshaler interface instead, as this will be removed in a future version.

Directories

Path Synopsis
examples
passing-values command
simple command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL