//! The _Typst_ standard library. use crate::syntax::Scope; use crate::func::prelude::*; pub_use_mod!(font); pub_use_mod!(layout); pub_use_mod!(page); pub_use_mod!(spacing); /// Create a scope with all standard functions. pub fn std() -> Scope { let mut std = Scope::new::(); // Basics std.add::("val"); // Font setup std.add::("font.family"); std.add::("font.style"); std.add::("font.weight"); std.add::("font.size"); std.add_with_meta::("word.spacing", ContentKind::Word); // Layout std.add_with_meta::("line.spacing", ContentKind::Line); std.add_with_meta::("par.spacing", ContentKind::Paragraph); std.add::("align"); std.add::("direction"); std.add::("box"); // Spacing std.add::("n"); std.add::("line.break"); std.add::("par.break"); std.add::("page.break"); std.add_with_meta::("spacing", None); std.add_with_meta::("h", Some(Horizontal)); std.add_with_meta::("v", Some(Vertical)); // Page setup std.add::("page.size"); std.add::("page.margins"); std } function! { /// `val`: Layouts the body with no special effect. #[derive(Debug, Clone, PartialEq)] pub struct ValFunc { body: Option, } parse(header, body, ctx, f) { header.args.pos.items.clear(); header.args.key.pairs.clear(); ValFunc { body: body!(opt: body, ctx, f) } } layout(self, ctx, errors) { match &self.body { Some(model) => vec![LayoutSyntaxModel(model)], None => vec![], } } } /// Layout an optional body with a change of the text style. fn styled<'a, T, F>( body: &'a Option, ctx: LayoutContext<'_>, data: Option, f: F, ) -> Commands<'a> where F: FnOnce(&mut TextStyle, T) { if let Some(data) = data { let mut style = ctx.style.text.clone(); f(&mut style, data); match body { Some(model) => vec![ SetTextStyle(style), LayoutSyntaxModel(model), SetTextStyle(ctx.style.text.clone()), ], None => vec![SetTextStyle(style)], } } else { vec![] } }