diff --git a/python/typst/__init__.pyi b/python/typst/__init__.pyi index 4249d82..a66eee0 100644 --- a/python/typst/__init__.pyi +++ b/python/typst/__init__.pyi @@ -1,5 +1,5 @@ import pathlib -from typing import List, Optional, TypeVar, overload +from typing import List, Optional, TypeVar, overload, Dict PathLike = TypeVar("PathLike", str, pathlib.Path) @@ -9,12 +9,14 @@ class Compiler: input: PathLike, root: Optional[PathLike] = None, font_paths: List[PathLike] = [], + sys_inputs: Dict[str, str] = {} ) -> None: """Initialize a Typst compiler. Args: input (PathLike): Project's main .typ file. root (Optional[PathLike], optional): Root path for the Typst project. font_paths (List[PathLike]): Folders with fonts. + sys_inputs (Dict[str, str]): string key-value pairs to be passed to the document via sys.inputs """ def compile( self, @@ -41,6 +43,7 @@ def compile( font_paths: List[PathLike] = [], format: Optional[str] = None, ppi: Optional[float] = None, + sys_inputs: Dict[str, str] = {} ) -> None: ... @overload def compile( @@ -50,6 +53,7 @@ def compile( font_paths: List[PathLike] = [], format: Optional[str] = None, ppi: Optional[float] = None, + sys_inputs: Dict[str, str] = {} ) -> bytes: ... def compile( input: PathLike, @@ -58,6 +62,7 @@ def compile( font_paths: List[PathLike] = [], format: Optional[str] = None, ppi: Optional[float] = None, + sys_inputs: Dict[str, str] = {} ) -> Optional[bytes]: """Compile a Typst project. Args: @@ -69,6 +74,7 @@ def compile( format (Optional[str]): Output format. Allowed values are `pdf`, `svg` and `png`. ppi (Optional[float]): Pixels per inch for PNG output, defaults to 144. + sys_inputs (Dict[str, str]): string key-value pairs to be passed to the document via sys.inputs Returns: Optional[bytes]: Return the compiled file as `bytes` if output is `None`. """ diff --git a/src/lib.rs b/src/lib.rs index b544adf..8107570 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,8 @@ use pyo3::exceptions::{PyIOError, PyRuntimeError}; use pyo3::prelude::*; use pyo3::types::PyBytes; +use std::collections::HashMap; +use typst::foundations::{Dict, Value}; use world::SystemWorld; mod compiler; @@ -59,8 +61,13 @@ impl Compiler { impl Compiler { /// Create a new typst compiler instance #[new] - #[pyo3(signature = (input, root = None, font_paths = Vec::new()))] - fn new(input: PathBuf, root: Option, font_paths: Vec) -> PyResult { + #[pyo3(signature = (input, root = None, font_paths = Vec::new(), sys_inputs = HashMap::new()))] + fn new( + input: PathBuf, + root: Option, + font_paths: Vec, + sys_inputs: HashMap, + ) -> PyResult { let input = input.canonicalize()?; let root = if let Some(root) = root { root.canonicalize()? @@ -85,6 +92,11 @@ impl Compiler { } } let world = SystemWorld::builder(root, input) + .inputs(Dict::from_iter( + sys_inputs + .into_iter() + .map(|(k, v)| (k.into(), Value::Str(v.into()))), + )) .font_paths(font_paths) .font_files(default_fonts) .build() @@ -113,7 +125,8 @@ impl Compiler { /// Compile a typst document to PDF #[pyfunction] -#[pyo3(signature = (input, output = None, root = None, font_paths = Vec::new(), format = None, ppi = None))] +#[pyo3(signature = (input, output = None, root = None, font_paths = Vec::new(), format = None, ppi = None, sys_inputs = HashMap::new()))] +#[allow(clippy::too_many_arguments)] fn compile( py: Python<'_>, input: PathBuf, @@ -122,8 +135,9 @@ fn compile( font_paths: Vec, format: Option<&str>, ppi: Option, + sys_inputs: HashMap, ) -> PyResult { - let mut compiler = Compiler::new(input, root, font_paths)?; + let mut compiler = Compiler::new(input, root, font_paths, sys_inputs)?; compiler.py_compile(py, output, format, ppi) } diff --git a/src/world.rs b/src/world.rs index f778bfe..b1fda05 100644 --- a/src/world.rs +++ b/src/world.rs @@ -7,10 +7,10 @@ use chrono::{DateTime, Datelike, Local}; use comemo::Prehashed; use ecow::eco_format; use typst::diag::{FileError, FileResult, StrResult}; -use typst::foundations::{Bytes, Datetime}; +use typst::foundations::{Bytes, Datetime, Dict}; use typst::syntax::{FileId, Source, VirtualPath}; use typst::text::{Font, FontBook}; -use typst::{Library, World}; +use typst::{Library, LibraryBuilder, World}; use crate::fonts::{FontSearcher, FontSlot}; use crate::package::prepare_package; @@ -132,6 +132,7 @@ pub struct SystemWorldBuilder { main: PathBuf, font_paths: Vec, font_files: Vec, + inputs: Dict, } impl SystemWorldBuilder { @@ -141,6 +142,7 @@ impl SystemWorldBuilder { main, font_paths: Vec::new(), font_files: Vec::new(), + inputs: Dict::default(), } } @@ -154,6 +156,11 @@ impl SystemWorldBuilder { self } + pub fn inputs(mut self, inputs: Dict) -> Self { + self.inputs = inputs; + self + } + pub fn build(self) -> StrResult { let mut searcher = FontSearcher::new(); searcher.search(&self.font_paths, &self.font_files); @@ -170,7 +177,7 @@ impl SystemWorldBuilder { input, root: self.root, main: FileId::new(None, main_path), - library: Prehashed::new(Library::default()), + library: Prehashed::new(LibraryBuilder::default().with_inputs(self.inputs).build()), book: Prehashed::new(searcher.book), fonts: searcher.fonts, slots: RefCell::default(),