Skip to content

Commit

Permalink
add sys.inputs arguments
Browse files Browse the repository at this point in the history
This adds the possibility to specify string based key-value arguments to
be passed into the compiled document. It reuses the cli arguments
mechanism.
  • Loading branch information
Icxolu committed Mar 15, 2024
1 parent ad2595d commit f5d293e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
8 changes: 7 additions & 1 deletion python/typst/__init__.pyi
Original file line number Diff line number Diff line change
@@ -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)

Expand All @@ -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,
Expand All @@ -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(
Expand All @@ -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,
Expand All @@ -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:
Expand All @@ -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`.
"""
22 changes: 18 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<PathBuf>, font_paths: Vec<PathBuf>) -> PyResult<Self> {
#[pyo3(signature = (input, root = None, font_paths = Vec::new(), sys_inputs = HashMap::new()))]
fn new(
input: PathBuf,
root: Option<PathBuf>,
font_paths: Vec<PathBuf>,
sys_inputs: HashMap<String, String>,
) -> PyResult<Self> {
let input = input.canonicalize()?;
let root = if let Some(root) = root {
root.canonicalize()?
Expand All @@ -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()
Expand Down Expand Up @@ -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,
Expand All @@ -122,8 +135,9 @@ fn compile(
font_paths: Vec<PathBuf>,
format: Option<&str>,
ppi: Option<f32>,
sys_inputs: HashMap<String, String>,
) -> PyResult<PyObject> {
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)
}

Expand Down
13 changes: 10 additions & 3 deletions src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -132,6 +132,7 @@ pub struct SystemWorldBuilder {
main: PathBuf,
font_paths: Vec<PathBuf>,
font_files: Vec<PathBuf>,
inputs: Dict,
}

impl SystemWorldBuilder {
Expand All @@ -141,6 +142,7 @@ impl SystemWorldBuilder {
main,
font_paths: Vec::new(),
font_files: Vec::new(),
inputs: Dict::default(),
}
}

Expand All @@ -154,6 +156,11 @@ impl SystemWorldBuilder {
self
}

pub fn inputs(mut self, inputs: Dict) -> Self {
self.inputs = inputs;
self
}

pub fn build(self) -> StrResult<SystemWorld> {
let mut searcher = FontSearcher::new();
searcher.search(&self.font_paths, &self.font_files);
Expand All @@ -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(),
Expand Down

0 comments on commit f5d293e

Please sign in to comment.