use std::sync::Arc;
use typst::diag::{FileError, FileResult};
use typst::foundations::{Bytes, Datetime, Duration};
use typst::syntax::{FileId, RootedPath, Source, VirtualPath, VirtualRoot};
use typst::text::{Font, FontBook};
use typst::{self, Library, LibraryExt, World};
use typst_kit::fonts::{self,FontStore};
use typst_layout::PagedDocument;
use typst_utils::LazyHash;
use crate::document::Document;
fn default_font_store() -> FontStore {
let mut store = FontStore::new();
store.extend(fonts::system());
store.extend(fonts::embedded());
store
}
pub(crate) struct Compiler {
src: Source,
lib: LazyHash<Library>,
store: Arc<FontStore>,
}
impl World for Compiler {
fn library(&self) -> &LazyHash<Library> {
&self.lib
}
fn book(&self) -> &LazyHash<FontBook> {
self.store.book()
}
fn main(&self) -> FileId {
self.src.id()
}
fn source(&self, id: FileId) -> FileResult<Source> {
if id == self.src.id() {
Ok(self.src.clone())
} else {
Err(FileError::NotFound(std::path::PathBuf::new()))
}
}
fn file(&self, _id: FileId) -> FileResult<Bytes> {
Err(FileError::NotFound(std::path::PathBuf::new()))
}
fn font(&self, i: usize) -> Option<Font> {
self.store.font(i)
}
fn today(&self, _offset: Option<Duration>) -> Option<Datetime> {
None
}
}
pub(crate) fn compile(src: String) -> Result<Document, String> {
let c = Compiler::new(src);
match typst::compile::<PagedDocument>(&c).output {
Err(err) => Err(format!("Compilation failed: {err:?}")),
Ok(doc) => Ok(Document::new(doc)),
}
}
impl Compiler {
pub(crate) fn new(src: String) -> Compiler {
let vpath = VirtualPath::new("file.typ").unwrap();
let fid = RootedPath::new(VirtualRoot::Project, vpath).intern();
let src = Source::new(fid, src);
Compiler {
src,
lib: Library::default().into(),
store: Arc::new(default_font_store()),
}
}
}