//! The compiler for the _Typst_ typesetting language. //! //! # Steps //! - **Parsing:** The parsing step first transforms a plain string into an //! [iterator of tokens][tokens]. This token stream is [parsed] into a [syntax //! tree]. The structures describing the tree can be found in the [syntax] //! module. //! - **Evaluation:** The next step is to [evaluate] the syntax tree. This //! computes the value of each node in the document and produces a [module]. //! - **Execution:** Now, we can [execute] the parsed and evaluated module. This //! results in a [layout tree], a high-level, fully styled representation of //! the document. The nodes of this tree are self-contained and //! order-independent and thus much better suited for layouting than the //! syntax tree. //! - **Layouting:** Next, the tree is [layouted] into a portable version of the //! typeset document. The output of this is a collection of [`Frame`]s (one //! per page), ready for exporting. //! - **Exporting:** The finished layout can be exported into a supported //! format. Currently, the only supported output format is [PDF]. //! //! [tokens]: parse::Tokens //! [parsed]: parse::parse //! [syntax tree]: syntax::SyntaxTree //! [evaluate]: eval::eval //! [module]: eval::Module //! [execute]: exec::exec //! [layout tree]: layout::LayoutTree //! [layouted]: layout::layout //! [PDF]: export::pdf #[macro_use] pub mod diag; #[macro_use] pub mod eval; pub mod color; pub mod exec; pub mod export; pub mod font; pub mod geom; pub mod image; pub mod layout; pub mod library; pub mod loading; pub mod paper; pub mod parse; pub mod pretty; pub mod syntax; pub mod util; use std::rc::Rc; use crate::diag::TypResult; use crate::eval::{ModuleCache, Scope}; use crate::exec::State; use crate::font::FontCache; use crate::image::ImageCache; use crate::layout::Frame; #[cfg(feature = "layout-cache")] use crate::layout::LayoutCache; use crate::loading::{FileId, Loader}; /// The core context which holds the loader, configuration and cached artifacts. pub struct Context { /// The loader the context was created with. pub loader: Rc, /// Caches parsed font faces. pub fonts: FontCache, /// Caches decoded images. pub images: ImageCache, /// Caches evaluated modules. pub modules: ModuleCache, /// Caches layouting artifacts. #[cfg(feature = "layout-cache")] pub layouts: LayoutCache, /// The standard library scope. std: Scope, /// The default state. state: State, } impl Context { /// Create a new context with the default settings. pub fn new(loader: Rc) -> Self { Self::builder().build(loader) } /// Create a new context with advanced settings. pub fn builder() -> ContextBuilder { ContextBuilder::default() } /// Garbage-collect caches. pub fn turnaround(&mut self) { #[cfg(feature = "layout-cache")] self.layouts.turnaround(); } /// Typeset a source file into a collection of layouted frames. /// /// The `file` identifies the source file and is used to resolve relative /// paths (for importing and image loading). /// /// Returns either a vector of frames representing individual pages or /// diagnostics in the form of a vector of error message with file and span /// information. pub fn typeset(&mut self, file: FileId, src: &str) -> TypResult>> { let ast = parse::parse(file, src)?; let module = eval::eval(self, file, Rc::new(ast))?; let tree = exec::exec(self, &module.template); let frames = layout::layout(self, &tree); Ok(frames) } } /// A builder for a [`Context`]. /// /// This struct is created by [`Context::builder`]. #[derive(Default)] pub struct ContextBuilder { std: Option, state: Option, } impl ContextBuilder { /// The scope containing definitions that are available everywhere /// (the standard library). pub fn std(mut self, std: Scope) -> Self { self.std = Some(std); self } /// The initial properties for page size, font selection and so on. pub fn state(mut self, state: State) -> Self { self.state = Some(state); self } /// Finish building the context by providing the `loader` used to load /// fonts, images, source files and other resources. pub fn build(self, loader: Rc) -> Context { Context { loader: Rc::clone(&loader), fonts: FontCache::new(Rc::clone(&loader)), images: ImageCache::new(loader), modules: ModuleCache::new(), #[cfg(feature = "layout-cache")] layouts: LayoutCache::new(), std: self.std.unwrap_or(library::new()), state: self.state.unwrap_or_default(), } } }