diff --git a/examples/latex_typst/Cargo.toml b/examples/latex_typst/Cargo.toml new file mode 100644 index 00000000..d2dccf74 --- /dev/null +++ b/examples/latex_typst/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "latex_typst" +version = "0.1.0" +license.workspace = true +edition.workspace = true +rust-version.workspace = true +publish = false + +[lints] +workspace = true + +[dependencies] + +typst = "0.14.0" +typst-svg = "0.14.0" +typst-assets = { version = "0.14.0", features = ["fonts"] } diff --git a/examples/latex_typst/src/main.rs b/examples/latex_typst/src/main.rs new file mode 100644 index 00000000..0b58d057 --- /dev/null +++ b/examples/latex_typst/src/main.rs @@ -0,0 +1,83 @@ +use typst::diag::{FileError, FileResult, SourceDiagnostic, SourceResult}; +use typst::ecow::EcoVec; +use typst::foundations::{Bytes, Datetime, Smart}; +use typst::layout::PagedDocument; +use typst::syntax::{FileId, Source, Span}; +use typst::text::{Font, FontBook}; +use typst::utils::LazyHash; +use typst::{Library, LibraryExt, World}; + +struct SimpleWorld { + library: LazyHash, + book: LazyHash, + fonts: Vec, + source: Source, +} + +impl SimpleWorld { + fn new(text: &str) -> Self { + let fonts: Vec = typst_assets::fonts() + .flat_map(|data| Font::iter(Bytes::new(data.to_vec()))) + .collect(); + + assert!(!fonts.is_empty(), "typst-assets failed to load any fonts"); + + let input = format!("#set page(width: auto, height: auto, margin: 0cm)\n{text}"); + + Self { + library: LazyHash::new(Library::builder().build()), + book: LazyHash::new(FontBook::from_fonts(&fonts)), + fonts, + source: Source::detached(input), + } + } + + fn get_svg(&self) -> SourceResult { + let mut page = typst::compile::(&self) + .output? + .pages + .first() + .ok_or_else(|| EcoVec::from_iter([SourceDiagnostic::error(Span::detached(), "document contains no pages")])) + .cloned()?; + page.fill = Smart::Custom(None); + Ok(typst_svg::svg(&page)) + } +} + +impl World for SimpleWorld { + fn library(&self) -> &LazyHash { + &self.library + } + + fn book(&self) -> &LazyHash { + &self.book + } + + fn main(&self) -> FileId { + self.source.id() + } + + fn source(&self, id: FileId) -> FileResult { + if id == self.source.id() { + Ok(self.source.clone()) + } else { + Err(FileError::NotFound(id.vpath().as_rooted_path().into())) + } + } + + fn file(&self, id: FileId) -> FileResult { + Err(FileError::NotFound(id.vpath().as_rooted_path().into())) + } + + fn font(&self, index: usize) -> Option { + self.fonts.get(index).cloned() + } + + fn today(&self, _offset: Option) -> Option { + None + } +} + +fn main() { + println!("{}", SimpleWorld::new("$ f(x) = x^2 $").get_svg().unwrap()); +}