typst_library/foundations/
mod.rs1pub mod calc;
4pub mod ops;
5pub mod repr;
6pub mod sys;
7
8mod args;
9mod array;
10mod auto;
11mod bool;
12mod bytes;
13mod cast;
14mod content;
15mod context;
16mod datetime;
17mod decimal;
18mod dict;
19mod duration;
20mod fields;
21mod float;
22mod func;
23mod int;
24mod label;
25mod module;
26mod none;
27#[path = "plugin.rs"]
28mod plugin_;
29mod scope;
30mod selector;
31mod str;
32mod styles;
33mod symbol;
34#[path = "target.rs"]
35mod target_;
36mod ty;
37mod value;
38mod version;
39
40pub use self::args::*;
41pub use self::array::*;
42pub use self::auto::*;
43pub use self::bytes::*;
44pub use self::cast::*;
45pub use self::content::*;
46pub use self::context::*;
47pub use self::datetime::*;
48pub use self::decimal::*;
49pub use self::dict::*;
50pub use self::duration::*;
51pub use self::fields::*;
52pub use self::float::*;
53pub use self::func::*;
54pub use self::int::*;
55pub use self::label::*;
56pub use self::module::*;
57pub use self::none::*;
58pub use self::plugin_::*;
59pub use self::repr::Repr;
60pub use self::scope::*;
61pub use self::selector::*;
62pub use self::str::*;
63pub use self::styles::*;
64pub use self::symbol::*;
65pub use self::target_::*;
66pub use self::ty::*;
67pub use self::value::*;
68pub use self::version::*;
69pub use typst_macros::{scope, ty};
70use typst_syntax::SyntaxMode;
71
72#[rustfmt::skip]
73#[doc(hidden)]
74pub use {
75 ecow::{eco_format, eco_vec},
76 indexmap::IndexMap,
77 smallvec::SmallVec,
78};
79
80use comemo::TrackedMut;
81use ecow::EcoString;
82use typst_syntax::Spanned;
83
84use crate::diag::{SourceResult, StrResult, bail};
85use crate::engine::Engine;
86use crate::{Feature, Features};
87
88pub(super) fn define(global: &mut Scope, inputs: Dict, features: &Features) {
90 global.start_category(crate::Category::Foundations);
91 global.define_type::<bool>();
92 global.define_type::<i64>();
93 global.define_type::<f64>();
94 global.define_type::<Str>();
95 global.define_type::<Label>();
96 global.define_type::<Bytes>();
97 global.define_type::<Content>();
98 global.define_type::<Array>();
99 global.define_type::<Dict>();
100 global.define_type::<Func>();
101 global.define_type::<Args>();
102 global.define_type::<Type>();
103 global.define_type::<Module>();
104 global.define_type::<Regex>();
105 global.define_type::<Selector>();
106 global.define_type::<Datetime>();
107 global.define_type::<Decimal>();
108 global.define_type::<Symbol>();
109 global.define_type::<Duration>();
110 global.define_type::<Version>();
111 global.define_func::<repr::repr>();
112 global.define_func::<panic>();
113 global.define_func::<assert>();
114 global.define_func::<eval>();
115 global.define_func::<plugin>();
116 if features.is_enabled(Feature::Html) {
117 global.define_func::<target>();
118 }
119 global.define("calc", calc::module());
120 global.define("sys", sys::module(inputs));
121 global.reset_category();
122}
123
124#[func(keywords = ["error"])]
135pub fn panic(
136 #[variadic]
138 values: Vec<Value>,
139) -> StrResult<Never> {
140 let mut msg = EcoString::from("panicked");
141 if !values.is_empty() {
142 msg.push_str(" with: ");
143 for (i, value) in values.iter().enumerate() {
144 if i > 0 {
145 msg.push_str(", ");
146 }
147 msg.push_str(&value.repr());
148 }
149 }
150 Err(msg)
151}
152
153#[func(scope)]
166pub fn assert(
167 condition: bool,
169 #[named]
171 message: Option<EcoString>,
172) -> StrResult<NoneValue> {
173 if !condition {
174 if let Some(message) = message {
175 bail!("assertion failed: {message}");
176 } else {
177 bail!("assertion failed");
178 }
179 }
180 Ok(NoneValue)
181}
182
183#[scope]
184impl assert {
185 #[func(title = "Assert Equal")]
194 pub fn eq(
195 left: Value,
197 right: Value,
199 #[named]
202 message: Option<EcoString>,
203 ) -> StrResult<NoneValue> {
204 if left != right {
205 if let Some(message) = message {
206 bail!("equality assertion failed: {message}");
207 } else {
208 bail!(
209 "equality assertion failed: value {} was not equal to {}",
210 left.repr(),
211 right.repr()
212 );
213 }
214 }
215 Ok(NoneValue)
216 }
217
218 #[func(title = "Assert Not Equal")]
227 pub fn ne(
228 left: Value,
230 right: Value,
232 #[named]
235 message: Option<EcoString>,
236 ) -> StrResult<NoneValue> {
237 if left == right {
238 if let Some(message) = message {
239 bail!("inequality assertion failed: {message}");
240 } else {
241 bail!(
242 "inequality assertion failed: value {} was equal to {}",
243 left.repr(),
244 right.repr()
245 );
246 }
247 }
248 Ok(NoneValue)
249 }
250}
251
252#[func(title = "Evaluate")]
263pub fn eval(
264 engine: &mut Engine,
265 source: Spanned<String>,
267 #[named]
275 #[default(SyntaxMode::Code)]
276 mode: SyntaxMode,
277 #[named]
291 #[default]
292 scope: Dict,
293) -> SourceResult<Value> {
294 let Spanned { v: text, span } = source;
295 let dict = scope;
296 let mut scope = Scope::new();
297 for (key, value) in dict {
298 scope.bind(key.into(), Binding::new(value, span));
299 }
300
301 (engine.routines.eval_string)(
302 engine.routines,
303 engine.world,
304 TrackedMut::reborrow_mut(&mut engine.sink),
305 &text,
306 span,
307 mode,
308 scope,
309 )
310}