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 element;
21mod fields;
22mod float;
23mod func;
24mod int;
25mod label;
26mod module;
27mod none;
28#[path = "plugin.rs"]
29mod plugin_;
30mod scope;
31mod selector;
32mod str;
33mod styles;
34mod symbol;
35#[path = "target.rs"]
36mod target_;
37mod ty;
38mod value;
39mod version;
40
41pub use self::args::*;
42pub use self::array::*;
43pub use self::auto::*;
44pub use self::bytes::*;
45pub use self::cast::*;
46pub use self::content::*;
47pub use self::context::*;
48pub use self::datetime::*;
49pub use self::decimal::*;
50pub use self::dict::*;
51pub use self::duration::*;
52pub use self::element::*;
53pub use self::fields::*;
54pub use self::float::*;
55pub use self::func::*;
56pub use self::int::*;
57pub use self::label::*;
58pub use self::module::*;
59pub use self::none::*;
60pub use self::plugin_::*;
61pub use self::repr::Repr;
62pub use self::scope::*;
63pub use self::selector::*;
64pub use self::str::*;
65pub use self::styles::*;
66pub use self::symbol::*;
67pub use self::target_::*;
68pub use self::ty::*;
69pub use self::value::*;
70pub use self::version::*;
71pub use typst_macros::{scope, ty};
72
73#[rustfmt::skip]
74#[doc(hidden)]
75pub use {
76 ecow::{eco_format, eco_vec},
77 indexmap::IndexMap,
78};
79
80use ecow::EcoString;
81use typst_syntax::Spanned;
82
83use crate::diag::{bail, SourceResult, StrResult};
84use crate::engine::Engine;
85use crate::routines::EvalMode;
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(EvalMode::Code)]
276 mode: EvalMode,
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 (engine.routines.eval_string)(engine.routines, engine.world, &text, span, mode, scope)
301}