diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-23 15:58:59 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-23 16:07:54 +0100 |
| commit | 5ae81971f299688b05d77af208d7bb44ffce5e2d (patch) | |
| tree | 35b914f9bdf5565d4602c4bdda08ccbc30977df4 /src | |
| parent | b2a3d3f235fb5a23322435b854460f52db772114 (diff) | |
Introduce `Library`
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 33 | ||||
| -rw-r--r-- | src/model/eval.rs | 7 | ||||
| -rw-r--r-- | src/model/library.rs (renamed from src/model/items.rs) | 63 | ||||
| -rw-r--r-- | src/model/mod.rs | 4 | ||||
| -rw-r--r-- | src/model/vm.rs | 4 |
5 files changed, 56 insertions, 55 deletions
@@ -42,14 +42,14 @@ pub mod frame; pub mod image; pub mod syntax; -use std::path::{Path, PathBuf}; +use std::path::Path; use comemo::{Prehashed, Track}; use crate::diag::{FileResult, SourceResult}; use crate::font::{Font, FontBook}; use crate::frame::Frame; -use crate::model::{LangItems, Route, Scope, StyleChain, StyleMap}; +use crate::model::{Library, Route, StyleChain}; use crate::syntax::{Source, SourceId}; use crate::util::Buffer; @@ -62,24 +62,24 @@ pub fn typeset( world: &(dyn World + 'static), source: &Source, ) -> SourceResult<Vec<Frame>> { - // Set up the language items. - let config = world.config(); - crate::model::set_lang_items(config.items); - // Evaluate the source file into a module. let route = Route::default(); let module = model::eval(world.track(), route.track(), source)?; // Layout the module's contents. - let styles = StyleChain::with_root(&config.styles); - item!(layout)(&module.content, world.track(), styles) + let library = world.library(); + let styles = StyleChain::with_root(&library.styles); + (library.items.layout)(&module.content, world.track(), styles) } /// The environment in which typesetting occurs. #[comemo::track] pub trait World { - /// Access the global configuration. - fn config(&self) -> &Prehashed<Config>; + /// The compilation root. + fn root(&self) -> &Path; + + /// The standard library. + fn library(&self) -> &Prehashed<Library>; /// Metadata about all known fonts. fn book(&self) -> &Prehashed<FontBook>; @@ -96,16 +96,3 @@ pub trait World { /// Access a source file by id. fn source(&self, id: SourceId) -> &Source; } - -/// The global configuration for typesetting. -#[derive(Debug, Clone, Hash)] -pub struct Config { - /// The compilation root, relative to which absolute paths are. - pub root: PathBuf, - /// The scope containing definitions that are available everywhere. - pub scope: Scope, - /// The default properties for page size, font selection and so on. - pub styles: StyleMap, - /// Defines which standard library items fulfill which syntactical roles. - pub items: LangItems, -} diff --git a/src/model/eval.rs b/src/model/eval.rs index 7f2cea63..fb1bd121 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -35,10 +35,13 @@ pub fn eval( panic!("Tried to cyclicly evaluate {}", path); } + // Hook up the lang items. + let library = world.library(); + super::set_lang_items(library.items.clone()); + // Evaluate the module. let route = unsafe { Route::insert(route, id) }; - let std = &world.config().scope; - let scopes = Scopes::new(Some(std)); + let scopes = Scopes::new(Some(&library.scope)); let mut vm = Vm::new(world, route.track(), id, scopes); let result = source.ast()?.eval(&mut vm); diff --git a/src/model/items.rs b/src/model/library.rs index 50ea8b60..8433e514 100644 --- a/src/model/items.rs +++ b/src/model/library.rs @@ -5,41 +5,26 @@ use std::num::NonZeroUsize; use comemo::Tracked; use once_cell::sync::OnceCell; -use super::{Content, NodeId, StyleChain}; +use super::{Content, NodeId, Scope, StyleChain, StyleMap}; use crate::diag::SourceResult; use crate::frame::Frame; use crate::geom::{Abs, Dir}; use crate::util::{hash128, EcoString}; use crate::World; -/// Global storage for lang items. -#[doc(hidden)] -pub static LANG_ITEMS: OnceCell<LangItems> = OnceCell::new(); - -/// Set the lang items. This is a hack :( -/// -/// Passing the lang items everywhere they are needed (especially the text node -/// related things) is very painful. By storing them globally, in theory, we -/// break incremental, but only when different sets of lang items are used in -/// the same program. For this reason, if this function is called multiple -/// times, the items must be the same. -pub(crate) fn set_lang_items(items: LangItems) { - if LANG_ITEMS.set(items).is_err() { - let first = hash128(LANG_ITEMS.get().unwrap()); - let second = hash128(&items); - assert_eq!(first, second, "set differing lang items"); - } -} - -/// Access a lang item. -macro_rules! item { - ($name:ident) => { - $crate::model::LANG_ITEMS.get().unwrap().$name - }; +/// A Typst standard library. +#[derive(Debug, Clone, Hash)] +pub struct Library { + /// The scope containing definitions that are available everywhere. + pub scope: Scope, + /// The default properties for page size, font selection and so on. + pub styles: StyleMap, + /// Defines which standard library items fulfill which syntactical roles. + pub items: LangItems, } /// Definition of certain standard library items the language is aware of. -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct LangItems { /// The root layout function. pub layout: fn( @@ -128,3 +113,29 @@ impl Hash for LangItems { self.math_align.hash(state); } } + +/// Global storage for lang items. +#[doc(hidden)] +pub static LANG_ITEMS: OnceCell<LangItems> = OnceCell::new(); + +/// Set the lang items. This is a hack :( +/// +/// Passing the lang items everywhere they are needed (especially the text node +/// related things) is very painful. By storing them globally, in theory, we +/// break incremental, but only when different sets of lang items are used in +/// the same program. For this reason, if this function is called multiple +/// times, the items must be the same. +pub(crate) fn set_lang_items(items: LangItems) { + if let Err(items) = LANG_ITEMS.set(items) { + let first = hash128(LANG_ITEMS.get().unwrap()); + let second = hash128(&items); + assert_eq!(first, second, "set differing lang items"); + } +} + +/// Access a lang item. +macro_rules! item { + ($name:ident) => { + $crate::model::LANG_ITEMS.get().unwrap().$name + }; +} diff --git a/src/model/mod.rs b/src/model/mod.rs index 0f946a40..93e33d5c 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -1,7 +1,7 @@ //! Document and computation model. #[macro_use] -mod items; +mod library; #[macro_use] mod cast; #[macro_use] @@ -34,7 +34,7 @@ pub use self::content::*; pub use self::dict::*; pub use self::eval::*; pub use self::func::*; -pub use self::items::*; +pub use self::library::*; pub use self::scope::*; pub use self::str::*; pub use self::styles::*; diff --git a/src/model/vm.rs b/src/model/vm.rs index 28885f29..d13be29c 100644 --- a/src/model/vm.rs +++ b/src/model/vm.rs @@ -38,7 +38,7 @@ impl<'a> Vm<'a> { location, scopes, flow: None, - items: world.config().items, + items: world.library().items.clone(), } } @@ -47,7 +47,7 @@ impl<'a> Vm<'a> { pub fn locate(&self, path: &str) -> StrResult<PathBuf> { if !self.location.is_detached() { if let Some(path) = path.strip_prefix('/') { - return Ok(self.world.config().root.join(path).normalize()); + return Ok(self.world.root().join(path).normalize()); } if let Some(dir) = self.world.source(self.location).path().parent() { |
