typst/src/lib.rs

165 lines
4.7 KiB
Rust

//! 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 tree itself is untyped, but the [AST] module provides a typed
//! layer over it.
//! - **Evaluation:** The next step is to [evaluate] the markup. This produces a
//! [module], consisting of a scope of values that were exported by the code
//! and [content], a hierarchical, styled representation of the text,
//! structure, layouts, etc. of the module. The nodes of the content tree are
//! well structured and order-independent and thus much better suited for
//! layouting than the raw markup.
//! - **Layouting:** Next, the content 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::SyntaxNode
//! [AST]: syntax::ast
//! [evaluate]: eval::evaluate
//! [module]: eval::Module
//! [content]: model::Content
//! [layouted]: model::layout
//! [PDF]: export::pdf
#![allow(clippy::len_without_is_empty)]
#![allow(clippy::or_fun_call)]
#![allow(clippy::try_err)]
#[macro_use]
pub mod util;
#[macro_use]
pub mod geom;
#[macro_use]
pub mod diag;
#[macro_use]
pub mod eval;
pub mod export;
pub mod font;
pub mod frame;
pub mod image;
pub mod library;
pub mod loading;
pub mod model;
pub mod parse;
pub mod source;
pub mod syntax;
use std::path::PathBuf;
use std::sync::Arc;
use crate::diag::TypResult;
use crate::eval::Scope;
use crate::font::FontStore;
use crate::frame::Frame;
use crate::loading::Loader;
use crate::model::StyleMap;
use crate::source::{SourceId, SourceStore};
/// Typeset a source file into a collection of layouted frames.
///
/// 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(ctx: &mut Context, id: SourceId) -> TypResult<Vec<Frame>> {
let module = eval::evaluate(ctx, id, vec![])?;
model::layout(ctx, &module.content)
}
/// The core context which holds the configuration and stores.
pub struct Context {
/// The loader for fonts and files.
pub loader: Arc<dyn Loader>,
/// Stores loaded source files.
pub sources: SourceStore,
/// Stores parsed fonts.
pub fonts: FontStore,
/// The context's configuration.
config: Config,
}
impl Context {
/// Create a new context.
pub fn new(loader: Arc<dyn Loader>, config: Config) -> Self {
Self {
loader: Arc::clone(&loader),
sources: SourceStore::new(Arc::clone(&loader)),
fonts: FontStore::new(Arc::clone(&loader)),
config,
}
}
}
/// Compilation configuration.
pub struct Config {
/// The compilation root.
pub root: PathBuf,
/// The standard library scope.
pub std: Arc<Scope>,
/// The default styles.
pub styles: Arc<StyleMap>,
}
impl Config {
/// Create a new configuration builder.
pub fn builder() -> ConfigBuilder {
ConfigBuilder::default()
}
}
impl Default for Config {
fn default() -> Self {
Self::builder().build()
}
}
/// A builder for a [`Config`].
///
/// This struct is created by [`Config::builder`].
#[derive(Debug, Default, Clone)]
pub struct ConfigBuilder {
root: PathBuf,
std: Option<Arc<Scope>>,
styles: Option<Arc<StyleMap>>,
}
impl ConfigBuilder {
/// The compilation root, relative to which absolute paths are.
///
/// Default: Empty path.
pub fn root(&mut self, root: impl Into<PathBuf>) -> &mut Self {
self.root = root.into();
self
}
/// The scope containing definitions that are available everywhere.
///
/// Default: Typst's standard library.
pub fn std(&mut self, std: impl Into<Arc<Scope>>) -> &mut Self {
self.std = Some(std.into());
self
}
/// The default properties for page size, font selection and so on.
///
/// Default: Empty style map.
pub fn styles(&mut self, styles: impl Into<Arc<StyleMap>>) -> &mut Self {
self.styles = Some(styles.into());
self
}
/// Finish building the configuration.
pub fn build(&self) -> Config {
Config {
root: self.root.clone(),
std: self.std.clone().unwrap_or_else(|| Arc::new(library::new())),
styles: self.styles.clone().unwrap_or_default(),
}
}
}