summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-23 15:58:59 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-23 16:07:54 +0100
commit5ae81971f299688b05d77af208d7bb44ffce5e2d (patch)
tree35b914f9bdf5565d4602c4bdda08ccbc30977df4 /src/model
parentb2a3d3f235fb5a23322435b854460f52db772114 (diff)
Introduce `Library`
Diffstat (limited to 'src/model')
-rw-r--r--src/model/eval.rs7
-rw-r--r--src/model/library.rs (renamed from src/model/items.rs)63
-rw-r--r--src/model/mod.rs4
-rw-r--r--src/model/vm.rs4
4 files changed, 46 insertions, 32 deletions
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() {