summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/library')
-rw-r--r--src/library/align.rs32
-rw-r--r--src/library/boxed.rs43
-rw-r--r--src/library/color.rs19
-rw-r--r--src/library/font.rs25
-rw-r--r--src/library/mod.rs2
-rw-r--r--src/library/page.rs56
-rw-r--r--src/library/spacing.rs31
7 files changed, 94 insertions, 114 deletions
diff --git a/src/library/align.rs b/src/library/align.rs
index d36108a4..c3512b7f 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -14,19 +14,17 @@ use super::*;
/// - `vertical`: Any of `top`, `bottom` or `center`.
///
/// There may not be two alignment specifications for the same axis.
-pub async fn align(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass<Value> {
- let mut f = Feedback::new();
-
+pub async fn align(mut args: DictValue, ctx: &mut LayoutContext) -> Value {
let content = args.take::<SynTree>();
- let h = args.take_key::<Spanned<SpecAlign>>("horizontal", &mut f);
- let v = args.take_key::<Spanned<SpecAlign>>("vertical", &mut f);
+ let h = args.take_key::<Spanned<SpecAlign>>("horizontal", &mut ctx.f);
+ let v = args.take_key::<Spanned<SpecAlign>>("vertical", &mut ctx.f);
let all = args
.take_all_num_vals::<Spanned<SpecAlign>>()
.map(|align| (align.v.axis(), align))
.chain(h.into_iter().map(|align| (Some(SpecAxis::Horizontal), align)))
.chain(v.into_iter().map(|align| (Some(SpecAxis::Vertical), align)));
- let mut aligns = ctx.align;
+ let mut aligns = ctx.state.align;
let mut had = [false; 2];
let mut deferred_center = false;
@@ -37,19 +35,19 @@ pub async fn align(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass
if let Some(axis) = axis {
if align.v.axis().map_or(false, |a| a != axis) {
error!(
- @f, align.span,
+ @ctx.f, align.span,
"invalid alignment {} for {} axis", align.v, axis,
);
} else if had[axis as usize] {
- error!(@f, align.span, "duplicate alignment for {} axis", axis);
+ error!(@ctx.f, align.span, "duplicate alignment for {} axis", axis);
} else {
- let gen_align = align.v.to_gen(ctx.sys);
- *aligns.get_mut(axis.to_gen(ctx.sys)) = gen_align;
+ let gen_align = align.v.to_gen(ctx.state.sys);
+ *aligns.get_mut(axis.to_gen(ctx.state.sys)) = gen_align;
had[axis as usize] = true;
}
} else {
if had == [true, true] {
- error!(@f, align.span, "duplicate alignment");
+ error!(@ctx.f, align.span, "duplicate alignment");
} else if deferred_center {
// We have two unflushed centers, meaning we know that both axes
// are to be centered.
@@ -69,7 +67,7 @@ pub async fn align(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass
SpecAxis::Vertical
};
- *aligns.get_mut(axis.to_gen(ctx.sys)) = GenAlign::Center;
+ *aligns.get_mut(axis.to_gen(ctx.state.sys)) = GenAlign::Center;
had[axis as usize] = true;
deferred_center = false;
@@ -82,15 +80,13 @@ pub async fn align(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass
aligns.primary = GenAlign::Center;
}
- let commands = match content {
+ args.unexpected(&mut ctx.f);
+ Value::Commands(match content {
Some(tree) => vec![
SetAlignment(aligns),
LayoutSyntaxTree(tree),
- SetAlignment(ctx.align),
+ SetAlignment(ctx.state.align),
],
None => vec![SetAlignment(aligns)],
- };
-
- args.unexpected(&mut f);
- Pass::commands(commands, f)
+ })
}
diff --git a/src/library/boxed.rs b/src/library/boxed.rs
index fe0272bf..94aac48a 100644
--- a/src/library/boxed.rs
+++ b/src/library/boxed.rs
@@ -6,37 +6,32 @@ use crate::geom::Linear;
/// # Keyword arguments
/// - `width`: The width of the box (length or relative to parent's width).
/// - `height`: The height of the box (length or relative to parent's height).
-pub async fn boxed(
- _: Span,
- mut args: DictValue,
- mut ctx: LayoutContext<'_>,
-) -> Pass<Value> {
- let mut f = Feedback::new();
-
+pub async fn boxed(mut args: DictValue, ctx: &mut LayoutContext) -> Value {
let content = args.take::<SynTree>().unwrap_or_default();
- ctx.base = ctx.spaces[0].size;
- ctx.spaces.truncate(1);
- ctx.repeat = false;
+ let constraints = &mut ctx.constraints;
+ constraints.base = constraints.spaces[0].size;
+ constraints.spaces.truncate(1);
+ constraints.repeat = false;
- if let Some(width) = args.take_key::<Linear>("width", &mut f) {
- let abs = width.eval(ctx.base.width);
- ctx.base.width = abs;
- ctx.spaces[0].size.width = abs;
- ctx.spaces[0].expansion.horizontal = true;
+ if let Some(width) = args.take_key::<Linear>("width", &mut ctx.f) {
+ let abs = width.eval(constraints.base.width);
+ constraints.base.width = abs;
+ constraints.spaces[0].size.width = abs;
+ constraints.spaces[0].expansion.horizontal = true;
}
- if let Some(height) = args.take_key::<Linear>("height", &mut f) {
- let abs = height.eval(ctx.base.height);
- ctx.base.height = abs;
- ctx.spaces[0].size.height = abs;
- ctx.spaces[0].expansion.vertical = true;
+ if let Some(height) = args.take_key::<Linear>("height", &mut ctx.f) {
+ let abs = height.eval(constraints.base.height);
+ constraints.base.height = abs;
+ constraints.spaces[0].size.height = abs;
+ constraints.spaces[0].expansion.vertical = true;
}
+ args.unexpected(&mut ctx.f);
+
let layouted = layout_tree(&content, ctx).await;
- let layout = layouted.output.into_iter().next().unwrap();
- f.extend(layouted.feedback);
+ let layout = layouted.into_iter().next().unwrap();
- args.unexpected(&mut f);
- Pass::commands(vec![Add(layout)], f)
+ Value::Commands(vec![Add(layout)])
}
diff --git a/src/library/color.rs b/src/library/color.rs
index a11966ea..631c3668 100644
--- a/src/library/color.rs
+++ b/src/library/color.rs
@@ -2,12 +2,12 @@ use super::*;
use crate::color::RgbaColor;
/// `rgb`: Create an RGB(A) color.
-pub async fn rgb(span: Span, mut args: DictValue, _: LayoutContext<'_>) -> Pass<Value> {
+pub async fn rgb(mut args: DictValue, ctx: &mut LayoutContext) -> Value {
let mut f = Feedback::new();
- let r = args.expect::<Spanned<i64>>("red value", span, &mut f);
- let g = args.expect::<Spanned<i64>>("green value", span, &mut f);
- let b = args.expect::<Spanned<i64>>("blue value", span, &mut f);
+ let r = args.expect::<Spanned<i64>>("red value", Span::ZERO, &mut f);
+ let g = args.expect::<Spanned<i64>>("green value", Span::ZERO, &mut f);
+ let b = args.expect::<Spanned<i64>>("blue value", Span::ZERO, &mut f);
let a = args.take::<Spanned<i64>>();
let mut clamp = |component: Option<Spanned<i64>>, default| {
@@ -19,8 +19,11 @@ pub async fn rgb(span: Span, mut args: DictValue, _: LayoutContext<'_>) -> Pass<
})
};
- let color = RgbaColor::new(clamp(r, 0), clamp(g, 0), clamp(b, 0), clamp(a, 255));
-
- args.unexpected(&mut f);
- Pass::new(Value::Color(color), f)
+ args.unexpected(&mut ctx.f);
+ Value::Color(RgbaColor::new(
+ clamp(r, 0),
+ clamp(g, 0),
+ clamp(b, 0),
+ clamp(a, 255),
+ ))
}
diff --git a/src/library/font.rs b/src/library/font.rs
index e12bda2f..40d8d30b 100644
--- a/src/library/font.rs
+++ b/src/library/font.rs
@@ -49,9 +49,8 @@ use crate::geom::Linear;
/// ```typst
/// [font: "My Serif", serif]
/// ```
-pub async fn font(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass<Value> {
- let mut f = Feedback::new();
- let mut text = ctx.style.text.clone();
+pub async fn font(mut args: DictValue, ctx: &mut LayoutContext) -> Value {
+ let mut text = ctx.state.text.clone();
let mut updated_fallback = false;
let content = args.take::<SynTree>();
@@ -75,15 +74,15 @@ pub async fn font(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass<
updated_fallback = true;
}
- if let Some(style) = args.take_key::<FontStyle>("style", &mut f) {
+ if let Some(style) = args.take_key::<FontStyle>("style", &mut ctx.f) {
text.variant.style = style;
}
- if let Some(weight) = args.take_key::<FontWeight>("weight", &mut f) {
+ if let Some(weight) = args.take_key::<FontWeight>("weight", &mut ctx.f) {
text.variant.weight = weight;
}
- if let Some(stretch) = args.take_key::<FontStretch>("stretch", &mut f) {
+ if let Some(stretch) = args.take_key::<FontStretch>("stretch", &mut ctx.f) {
text.variant.stretch = stretch;
}
@@ -101,15 +100,13 @@ pub async fn font(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass<
text.fallback.flatten();
}
- let commands = match content {
+ args.unexpected(&mut ctx.f);
+ Value::Commands(match content {
Some(tree) => vec![
- SetTextStyle(text),
+ SetTextState(text),
LayoutSyntaxTree(tree),
- SetTextStyle(ctx.style.text.clone()),
+ SetTextState(ctx.state.text.clone()),
],
- None => vec![SetTextStyle(text)],
- };
-
- args.unexpected(&mut f);
- Pass::commands(commands, f)
+ None => vec![SetTextState(text)],
+ })
}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 43f74318..4db544e9 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -30,7 +30,7 @@ macro_rules! std {
macro_rules! wrap {
($func:expr) => {
- FuncValue::new(|name, args, ctx| Box::pin($func(name, args, ctx)))
+ FuncValue::new(|args, ctx| Box::pin($func(args, ctx)))
};
}
diff --git a/src/library/page.rs b/src/library/page.rs
index 77eb6244..5fda9d5d 100644
--- a/src/library/page.rs
+++ b/src/library/page.rs
@@ -19,56 +19,54 @@ use crate::paper::{Paper, PaperClass};
/// - `top`: The top margin (length or relative to height).
/// - `bottom`: The bottom margin (length or relative to height).
/// - `flip`: Flips custom or paper-defined width and height (boolean).
-pub async fn page(_: Span, mut args: DictValue, ctx: LayoutContext<'_>) -> Pass<Value> {
- let mut f = Feedback::new();
- let mut style = ctx.style.page;
+pub async fn page(mut args: DictValue, ctx: &mut LayoutContext) -> Value {
+ let mut page = ctx.state.page.clone();
if let Some(paper) = args.take::<Paper>() {
- style.class = paper.class;
- style.size = paper.size();
+ page.class = paper.class;
+ page.size = paper.size();
}
- if let Some(Abs(width)) = args.take_key::<Abs>("width", &mut f) {
- style.class = PaperClass::Custom;
- style.size.width = width;
+ if let Some(Abs(width)) = args.take_key::<Abs>("width", &mut ctx.f) {
+ page.class = PaperClass::Custom;
+ page.size.width = width;
}
- if let Some(Abs(height)) = args.take_key::<Abs>("height", &mut f) {
- style.class = PaperClass::Custom;
- style.size.height = height;
+ if let Some(Abs(height)) = args.take_key::<Abs>("height", &mut ctx.f) {
+ page.class = PaperClass::Custom;
+ page.size.height = height;
}
- if let Some(margins) = args.take_key::<Linear>("margins", &mut f) {
- style.margins = Sides::uniform(Some(margins));
+ if let Some(margins) = args.take_key::<Linear>("margins", &mut ctx.f) {
+ page.margins = Sides::uniform(Some(margins));
}
- if let Some(left) = args.take_key::<Linear>("left", &mut f) {
- style.margins.left = Some(left);
+ if let Some(left) = args.take_key::<Linear>("left", &mut ctx.f) {
+ page.margins.left = Some(left);
}
- if let Some(top) = args.take_key::<Linear>("top", &mut f) {
- style.margins.top = Some(top);
+ if let Some(top) = args.take_key::<Linear>("top", &mut ctx.f) {
+ page.margins.top = Some(top);
}
- if let Some(right) = args.take_key::<Linear>("right", &mut f) {
- style.margins.right = Some(right);
+ if let Some(right) = args.take_key::<Linear>("right", &mut ctx.f) {
+ page.margins.right = Some(right);
}
- if let Some(bottom) = args.take_key::<Linear>("bottom", &mut f) {
- style.margins.bottom = Some(bottom);
+ if let Some(bottom) = args.take_key::<Linear>("bottom", &mut ctx.f) {
+ page.margins.bottom = Some(bottom);
}
- if args.take_key::<bool>("flip", &mut f).unwrap_or(false) {
- mem::swap(&mut style.size.width, &mut style.size.height);
+ if args.take_key::<bool>("flip", &mut ctx.f).unwrap_or(false) {
+ mem::swap(&mut page.size.width, &mut page.size.height);
}
- args.unexpected(&mut f);
- Pass::commands(vec![SetPageStyle(style)], f)
+ args.unexpected(&mut ctx.f);
+ Value::Commands(vec![SetPageState(page)])
}
/// `pagebreak`: Ends the current page.
-pub async fn pagebreak(_: Span, args: DictValue, _: LayoutContext<'_>) -> Pass<Value> {
- let mut f = Feedback::new();
- args.unexpected(&mut f);
- Pass::commands(vec![BreakPage], f)
+pub async fn pagebreak(args: DictValue, ctx: &mut LayoutContext) -> Value {
+ args.unexpected(&mut ctx.f);
+ Value::Commands(vec![BreakPage])
}
diff --git a/src/library/spacing.rs b/src/library/spacing.rs
index 03f52ba4..91f407fe 100644
--- a/src/library/spacing.rs
+++ b/src/library/spacing.rs
@@ -6,35 +6,26 @@ use crate::layout::SpacingKind;
///
/// # Positional arguments
/// - The spacing (length or relative to font size).
-pub async fn h(name: Span, args: DictValue, ctx: LayoutContext<'_>) -> Pass<Value> {
- spacing(name, args, ctx, SpecAxis::Horizontal)
+pub async fn h(args: DictValue, ctx: &mut LayoutContext) -> Value {
+ spacing(args, ctx, SpecAxis::Horizontal)
}
/// `v`: Add vertical spacing.
///
/// # Positional arguments
/// - The spacing (length or relative to font size).
-pub async fn v(name: Span, args: DictValue, ctx: LayoutContext<'_>) -> Pass<Value> {
- spacing(name, args, ctx, SpecAxis::Vertical)
+pub async fn v(args: DictValue, ctx: &mut LayoutContext) -> Value {
+ spacing(args, ctx, SpecAxis::Vertical)
}
-fn spacing(
- name: Span,
- mut args: DictValue,
- ctx: LayoutContext<'_>,
- axis: SpecAxis,
-) -> Pass<Value> {
- let mut f = Feedback::new();
-
- let spacing = args.expect::<Linear>("spacing", name, &mut f);
- let commands = if let Some(spacing) = spacing {
- let axis = axis.to_gen(ctx.sys);
- let spacing = spacing.eval(ctx.style.text.font_size());
+fn spacing(mut args: DictValue, ctx: &mut LayoutContext, axis: SpecAxis) -> Value {
+ let spacing = args.expect::<Linear>("spacing", Span::ZERO, &mut ctx.f);
+ args.unexpected(&mut ctx.f);
+ Value::Commands(if let Some(spacing) = spacing {
+ let axis = axis.to_gen(ctx.state.sys);
+ let spacing = spacing.eval(ctx.state.text.font_size());
vec![AddSpacing(spacing, SpacingKind::Hard, axis)]
} else {
vec![]
- };
-
- args.unexpected(&mut f);
- Pass::commands(commands, f)
+ })
}