summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-07-18 21:53:42 +0200
committerLaurenz <laurmaedje@gmail.com>2023-07-18 21:53:42 +0200
commit803ae9309f54eaffff1340a81d06ede1969e26b1 (patch)
treee6be076653f4760982c98a8be040d801fb1f327d /crates
parentf52c39c388c2e3e38be0022fda6d78b12f0a9544 (diff)
Support `scope` argument for `eval`
Diffstat (limited to 'crates')
-rw-r--r--crates/typst-library/src/compute/foundations.rs23
-rw-r--r--crates/typst/src/eval/mod.rs4
-rw-r--r--crates/typst/src/eval/scope.rs11
3 files changed, 34 insertions, 4 deletions
diff --git a/crates/typst-library/src/compute/foundations.rs b/crates/typst-library/src/compute/foundations.rs
index ecac3ffa..b7663113 100644
--- a/crates/typst-library/src/compute/foundations.rs
+++ b/crates/typst-library/src/compute/foundations.rs
@@ -218,9 +218,30 @@ pub fn eval(
#[named]
#[default(EvalMode::Code)]
mode: EvalMode,
+ /// A scope of definitions that are made available.
+ ///
+ /// ```example
+ /// #eval("x + 1", scope: (x: 2)) \
+ /// #eval(
+ /// "abc/xyz",
+ /// mode: "math",
+ /// scope: (
+ /// abc: $a + b + c$,
+ /// xyz: $x + y + z$,
+ /// ),
+ /// )
+ /// ```
+ #[named]
+ #[default]
+ scope: Dict,
/// The virtual machine.
vm: &mut Vm,
) -> SourceResult<Value> {
let Spanned { v: text, span } = source;
- typst::eval::eval_string(vm.world(), &text, mode, span)
+ let dict = scope;
+ let mut scope = Scope::new();
+ for (key, value) in dict {
+ scope.define(key, value);
+ }
+ typst::eval::eval_string(vm.world(), &text, span, mode, scope)
}
diff --git a/crates/typst/src/eval/mod.rs b/crates/typst/src/eval/mod.rs
index 6f684a7b..f72eeaa4 100644
--- a/crates/typst/src/eval/mod.rs
+++ b/crates/typst/src/eval/mod.rs
@@ -145,8 +145,9 @@ pub fn eval(
pub fn eval_string(
world: Tracked<dyn World + '_>,
string: &str,
- mode: EvalMode,
span: Span,
+ mode: EvalMode,
+ scope: Scope,
) -> SourceResult<Value> {
let mut root = match mode {
EvalMode::Code => parse_code(string),
@@ -179,6 +180,7 @@ pub fn eval_string(
let id = FileId::detached();
let scopes = Scopes::new(Some(world.library()));
let mut vm = Vm::new(vt, route.track(), id, scopes);
+ vm.scopes.scopes.push(scope);
// Evaluate the code.
let result = match mode {
diff --git a/crates/typst/src/eval/scope.rs b/crates/typst/src/eval/scope.rs
index f3e13715..b8d5b75a 100644
--- a/crates/typst/src/eval/scope.rs
+++ b/crates/typst/src/eval/scope.rs
@@ -72,7 +72,11 @@ impl<'a> Scopes<'a> {
#[cold]
fn unknown_variable(var: &str) -> EcoString {
if var.contains('-') {
- eco_format!("unknown variable: {} - if you meant to use subtraction, try adding spaces around the minus sign.", var)
+ eco_format!(
+ "unknown variable: {} - if you meant to use subtraction, \
+ try adding spaces around the minus sign.",
+ var
+ )
} else {
eco_format!("unknown variable: {}", var)
}
@@ -171,7 +175,10 @@ impl Slot {
match self.kind {
Kind::Normal => Ok(&mut self.value),
Kind::Captured => {
- bail!("variables from outside the function are read-only and cannot be modified")
+ bail!(
+ "variables from outside the function are \
+ read-only and cannot be modified"
+ )
}
}
}