summaryrefslogtreecommitdiff
path: root/src
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
parentb2a3d3f235fb5a23322435b854460f52db772114 (diff)
Introduce `Library`
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs33
-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
5 files changed, 56 insertions, 55 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 319c13ab..75200144 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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() {