A library for building Typst documents with Nix. Goals:
- Hermetic document building
- Support non-Typst Universe packages
- Easy devShell support, just use
inputsFromand it supports your packages and fonts with incremental development. - Integrates with Nixpkg's
typstPackages - Supports key-values inputs (Typst's
sys.inputsdictionary) - Nixpkg's fonts
mkdir my-typst-document
cd my-typst-document
nix flake init --template github:RossSmyth/press
nix buildBasically done. In "maintenence mode". Let me know if you find any issues or have feature requests.
See the template for full API details and documentation.
Limitations:
- Cannot automatically detect third-party package dependencies (i.e. through the
extraPackagesattribute)
Just import the overlay.
pkgs = import nixpkgs {
overlays = [ (import press) ];
};
...
document = pkgs.buildTypstDocument {
name = "myDoc";
src = ./.;
};With Nixpkg's Typst Universe integration:
document = pkgs.buildTypstDocument {
name = "myDoc";
src = ./.;
# Adds note-me from Nixpkgs
typstEnv = p: [ p.note-me ];
};Only list the packages your document imports directly; their dependencies are resolved and added to the environment for you.
If you want to use a non-Universe package:
Recommended by extending the Nixpkgs typstPackages package set:
let
pkgs = import nixpkgs {
overlays = [
(import press)
(final: prev:
typstPackages = prev.typstPackages.extend (finalTypst: _: {
cool-package = final.buildTypstPackage {
pname = "cool-package";
version = "1.0";
src = coolPackageSrc;
typstDeps = [ finalTypst.note-me ];
};
})
)
];
};
in
pkgs.buildTypstDocument {
name = "myDoc";
src = ./.;
typstEnv = p: [ p.treet p.cool-package ];
} Or you can also use them directly, or if you want them in a custom namespace.
Warning
If pname and version are not specified, IFD will be used to determine the name and version.
pkgs.buildTypstDocument {
name = myDoc;
src = ./.;
extraPackages = {
local = [
somePackage
anotherPack
];
foospace = [ fooPackage ];
# Can specify the name and version explicitly to avoid IFD.
coolspace = [
{
pname = coolPackage;
version = "1.0";
src = coolPackage;
}
];
};
}If you want to use custom fonts:
documents = pkgs.buildTypstDocument {
name = "myDoc";
src = ./.;
fonts = [
pkgs.roboto
];
};Then for a devShell:
devShell = mkShell {
inputsFrom = [ document ];
packages = [
tinymist
typstyle
];
};Where local is the package namespace, and somePackage is a store path that has a typst.toml file in it.
You can put packages in whatever namespace you want, not just local.
See the template for more API details.
Press's inputs maps onto Typst's sys.inputs, so you can pass values
in from the flake:
document = pkgs.buildTypstDocument {
name = "myDoc";
src = ./.;
inputs = {
"git-hash" = self.rev or self.dirtyRev or "unknown";
};
creationTimestamp = self.lastModified;
};creationTimestamp sets SOURCE_DATE_EPOCH, which datetime.today()
respects, so the commit date is available in your document and stays
reproducible:
#set document(
title: "My Document",
author: "Jane Doe",
date: datetime.today(),
)The commit hash can now be attached as a file with
pdf.attach:
#let commit = sys.inputs.at("git-hash", default: none)
#if commit != none {
pdf.attach(
"build-info.json",
bytes(json.encode((commit: commit))),
relationship: "source",
mime-type: "application/json",
description: "Git commit this document was built from",
)
}