use std::path::Path;
use comemo::{Prehashed, Track};
use typst::diag::{FileError, FileResult};
use typst::eval::{Bytes, Datetime, Library, Module};
use typst::font::{Font, FontBook};
use typst::syntax::{FileId, Source, VirtualPath};
use typst::World;
struct EvalWorld {
library: Prehashed<Library>,
font_book: Prehashed<FontBook>,
main: Source,
}
impl EvalWorld {
fn new(main_file: impl AsRef<Path>) -> std::io::Result<Self> {
let main_data = std::fs::read_to_string(main_file.as_ref())?;
let main_id = FileId::new(None, VirtualPath::new(main_file));
Ok(Self {
library: Prehashed::new(typst_library::build()),
font_book: Prehashed::new(FontBook::new()),
main: Source::new(main_id, main_data),
})
}
}
impl World for EvalWorld {
fn library(&self) -> &Prehashed<Library> {
&self.library
}
fn book(&self) -> &Prehashed<FontBook> {
&self.font_book
}
fn main(&self) -> Source {
self.main.clone()
}
fn source(&self, id: FileId) -> FileResult<Source> {
let bytes = self.file(id)?;
let text = String::from_utf8_lossy(bytes.as_slice());
let source = Source::new(id, text.to_string());
Ok(source)
}
fn file(&self, id: FileId) -> FileResult<Bytes> {
let path = id.vpath().as_rootless_path();
match std::fs::read(path) {
Ok(bytes) => Ok(Bytes::from(bytes)),
Err(io_error) => Err(FileError::from_io(io_error, path)),
}
}
fn font(&self, _index: usize) -> Option<Font> {
None
}
fn today(&self, _offset: Option<i64>) -> Option<Datetime> {
None
}
}
pub fn eval_file(main_file: impl AsRef<Path>) -> Module {
let world = EvalWorld::new(main_file).unwrap();
let route = typst::eval::Route::default();
let mut tracer = typst::eval::Tracer::default();
typst::eval::eval(
(&world as &dyn World).track(),
route.track(),
tracer.track_mut(),
&world.main(),
)
.unwrap()
}