mirror of
https://github.com/typst/typst
synced 2025-06-28 00:03:17 +08:00
Add std
module for names in the standard library (#4038)
This commit is contained in:
parent
44bc51ba4f
commit
1247c6d8e1
@ -48,8 +48,14 @@ impl<'a> Scopes<'a> {
|
|||||||
pub fn get(&self, var: &str) -> HintedStrResult<&Value> {
|
pub fn get(&self, var: &str) -> HintedStrResult<&Value> {
|
||||||
std::iter::once(&self.top)
|
std::iter::once(&self.top)
|
||||||
.chain(self.scopes.iter().rev())
|
.chain(self.scopes.iter().rev())
|
||||||
.chain(self.base.map(|base| base.global.scope()))
|
|
||||||
.find_map(|scope| scope.get(var))
|
.find_map(|scope| scope.get(var))
|
||||||
|
.or_else(|| {
|
||||||
|
self.base.and_then(|base| match base.global.scope().get(var) {
|
||||||
|
Some(value) => Some(value),
|
||||||
|
None if var == "std" => Some(&base.std),
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
|
})
|
||||||
.ok_or_else(|| unknown_variable(var))
|
.ok_or_else(|| unknown_variable(var))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +63,14 @@ impl<'a> Scopes<'a> {
|
|||||||
pub fn get_in_math(&self, var: &str) -> HintedStrResult<&Value> {
|
pub fn get_in_math(&self, var: &str) -> HintedStrResult<&Value> {
|
||||||
std::iter::once(&self.top)
|
std::iter::once(&self.top)
|
||||||
.chain(self.scopes.iter().rev())
|
.chain(self.scopes.iter().rev())
|
||||||
.chain(self.base.map(|base| base.math.scope()))
|
|
||||||
.find_map(|scope| scope.get(var))
|
.find_map(|scope| scope.get(var))
|
||||||
|
.or_else(|| {
|
||||||
|
self.base.and_then(|base| match base.math.scope().get(var) {
|
||||||
|
Some(value) => Some(value),
|
||||||
|
None if var == "std" => Some(&base.std),
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
|
})
|
||||||
.ok_or_else(|| unknown_variable(var))
|
.ok_or_else(|| unknown_variable(var))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +81,19 @@ impl<'a> Scopes<'a> {
|
|||||||
.find_map(|scope| scope.get_mut(var))
|
.find_map(|scope| scope.get_mut(var))
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
match self.base.and_then(|base| base.global.scope().get(var)) {
|
match self.base.and_then(|base| base.global.scope().get(var)) {
|
||||||
Some(_) => eco_format!("cannot mutate a constant: {}", var).into(),
|
Some(_) => cannot_mutate_constant(var),
|
||||||
|
_ if var == "std" => cannot_mutate_constant(var),
|
||||||
_ => unknown_variable(var),
|
_ => unknown_variable(var),
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
fn cannot_mutate_constant(var: &str) -> HintedString {
|
||||||
|
eco_format!("cannot mutate a constant: {}", var).into()
|
||||||
|
}
|
||||||
|
|
||||||
/// The error message when a variable is not found.
|
/// The error message when a variable is not found.
|
||||||
#[cold]
|
#[cold]
|
||||||
fn unknown_variable(var: &str) -> HintedString {
|
fn unknown_variable(var: &str) -> HintedString {
|
||||||
|
@ -67,7 +67,7 @@ use crate::diag::{warning, FileResult, SourceDiagnostic, SourceResult};
|
|||||||
use crate::engine::{Engine, Route};
|
use crate::engine::{Engine, Route};
|
||||||
use crate::eval::Tracer;
|
use crate::eval::Tracer;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
Array, Bytes, Content, Datetime, Dict, Module, Scope, StyleChain, Styles,
|
Array, Bytes, Content, Datetime, Dict, Module, Scope, StyleChain, Styles, Value,
|
||||||
};
|
};
|
||||||
use crate::introspection::{Introspector, Locator};
|
use crate::introspection::{Introspector, Locator};
|
||||||
use crate::layout::{Alignment, Dir, LayoutRoot};
|
use crate::layout::{Alignment, Dir, LayoutRoot};
|
||||||
@ -297,6 +297,9 @@ pub struct Library {
|
|||||||
/// The default style properties (for page size, font selection, and
|
/// The default style properties (for page size, font selection, and
|
||||||
/// everything else configurable via set and show rules).
|
/// everything else configurable via set and show rules).
|
||||||
pub styles: Styles,
|
pub styles: Styles,
|
||||||
|
/// The standard library as a value.
|
||||||
|
/// Used to provide the `std` variable.
|
||||||
|
pub std: Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Library {
|
impl Library {
|
||||||
@ -333,7 +336,8 @@ impl LibraryBuilder {
|
|||||||
let math = math::module();
|
let math = math::module();
|
||||||
let inputs = self.inputs.unwrap_or_default();
|
let inputs = self.inputs.unwrap_or_default();
|
||||||
let global = global(math.clone(), inputs);
|
let global = global(math.clone(), inputs);
|
||||||
Library { global, math, styles: Styles::new() }
|
let std = Value::Module(global.clone());
|
||||||
|
Library { global, math, styles: Styles::new(), std }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
tests/ref/std-math.png
Normal file
BIN
tests/ref/std-math.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 298 B |
31
tests/suite/foundations/std.typ
Normal file
31
tests/suite/foundations/std.typ
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Test 'std', a module with the standard library
|
||||||
|
|
||||||
|
--- std-basic-access ---
|
||||||
|
#test(std.grid, grid)
|
||||||
|
#test(std.calc, calc)
|
||||||
|
|
||||||
|
--- std-import ---
|
||||||
|
#import std: grid as banana
|
||||||
|
#test(grid, banana)
|
||||||
|
|
||||||
|
--- std-of-shadowed ---
|
||||||
|
#let my-grid = grid[a][b]
|
||||||
|
#let grid = "oh no!"
|
||||||
|
#test(my-grid.func(), std.grid)
|
||||||
|
|
||||||
|
--- std-shadowing ---
|
||||||
|
#let std = 5
|
||||||
|
// Error: 6-10 cannot access fields on type integer
|
||||||
|
#std.grid
|
||||||
|
|
||||||
|
--- std-mutation ---
|
||||||
|
// Error: 3-6 cannot mutate a constant: std
|
||||||
|
#(std = 10)
|
||||||
|
|
||||||
|
--- std-shadowed-mutation ---
|
||||||
|
#let std = 10
|
||||||
|
#(std = 7)
|
||||||
|
#test(std, 7)
|
||||||
|
|
||||||
|
--- std-math ---
|
||||||
|
$ std.rect(x + y = 5) $
|
Loading…
x
Reference in New Issue
Block a user