summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-11-23 12:45:20 +0100
committerLaurenz <laurmaedje@gmail.com>2021-11-23 12:45:20 +0100
commit4f9e5819bbab1f93ad4f4b789038c60487a76368 (patch)
tree488a4e0422db4531d9882cf08f0b5cc21ae55a23 /src/library
parentd3f6040cedacad1b6c323be721c9086f6c5d9a44 (diff)
2d alignments with plus operator
Diffstat (limited to 'src/library')
-rw-r--r--src/library/align.rs20
-rw-r--r--src/library/image.rs5
-rw-r--r--src/library/mod.rs9
-rw-r--r--src/library/par.rs10
-rw-r--r--src/library/placed.rs11
-rw-r--r--src/library/shape.rs24
-rw-r--r--src/library/sized.rs10
-rw-r--r--src/library/transform.rs5
8 files changed, 40 insertions, 54 deletions
diff --git a/src/library/align.rs b/src/library/align.rs
index 97196aa7..7ce749d1 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -2,32 +2,18 @@ use super::prelude::*;
/// `align`: Configure the alignment along the layouting axes.
pub fn align(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let Spec { x, y } = parse_aligns(args)?;
+ let aligns = args.expect::<Spec<_>>("alignment")?;
let body = args.expect::<Template>("body")?;
Ok(Value::Template(Template::from_block(move |style| {
let mut style = style.clone();
- if let Some(x) = x {
+ if let Some(x) = aligns.x {
style.par_mut().align = x;
}
- body.pack(&style).aligned(x, y)
+ body.pack(&style).aligned(aligns)
})))
}
-/// Parse alignment arguments with shorthand.
-pub(super) fn parse_aligns(args: &mut Args) -> TypResult<Spec<Option<Align>>> {
- let mut x = args.named("horizontal")?;
- let mut y = args.named("vertical")?;
- for Spanned { v, span } in args.all::<Spanned<Align>>() {
- match v.axis() {
- SpecAxis::Horizontal if x.is_none() => x = Some(v),
- SpecAxis::Vertical if y.is_none() => y = Some(v),
- _ => bail!(span, "unexpected argument"),
- }
- }
- Ok(Spec::new(x, y))
-}
-
/// A node that aligns its child.
#[derive(Debug, Hash)]
pub struct AlignNode {
diff --git a/src/library/image.rs b/src/library/image.rs
index b0d66a63..a53eacc5 100644
--- a/src/library/image.rs
+++ b/src/library/image.rs
@@ -7,8 +7,7 @@ use crate::image::ImageId;
/// `image`: An image.
pub fn image(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let path = args.expect::<Spanned<EcoString>>("path to image file")?;
- let width = args.named("width")?;
- let height = args.named("height")?;
+ let sizing = Spec::new(args.named("width")?, args.named("height")?);
let fit = args.named("fit")?.unwrap_or_default();
// Load the image.
@@ -21,7 +20,7 @@ pub fn image(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
})?;
Ok(Value::Template(Template::from_inline(move |_| {
- ImageNode { id, fit }.pack().sized(width, height)
+ ImageNode { id, fit }.pack().sized(sizing)
})))
}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 9fe15a0f..9e7f6f28 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -142,6 +142,15 @@ dynamic! {
}
dynamic! {
+ Spec<Option<Align>>: "2d alignment",
+ @align: Align => {
+ let mut aligns = Spec::default();
+ aligns.set(align.axis(), Some(*align));
+ aligns
+ },
+}
+
+dynamic! {
FontFamily: "font family",
Value::Str(string) => Self::Named(string.to_lowercase()),
}
diff --git a/src/library/par.rs b/src/library/par.rs
index 4d291fdc..5edffeaa 100644
--- a/src/library/par.rs
+++ b/src/library/par.rs
@@ -24,20 +24,18 @@ pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
});
if let Some(Spanned { v, span }) = args.named::<Spanned<Dir>>("dir")? {
- if v.axis() == SpecAxis::Horizontal {
- dir = Some(v);
- } else {
+ if v.axis() != SpecAxis::Horizontal {
bail!(span, "must be horizontal");
}
+ dir = Some(v);
}
let mut align = None;
if let Some(Spanned { v, span }) = args.named::<Spanned<Align>>("align")? {
- if v.axis() == SpecAxis::Horizontal {
- align = Some(v);
- } else {
+ if v.axis() != SpecAxis::Horizontal {
bail!(span, "must be horizontal");
}
+ align = Some(v);
}
ctx.template.modify(move |style| {
diff --git a/src/library/placed.rs b/src/library/placed.rs
index 0d92fc35..e2c2e9e8 100644
--- a/src/library/placed.rs
+++ b/src/library/placed.rs
@@ -1,18 +1,13 @@
-use super::parse_aligns;
use super::prelude::*;
/// `place`: Place content at an absolute position.
pub fn place(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let Spec { x, y } = parse_aligns(args)?;
- let dx = args.named("dx")?;
- let dy = args.named("dy")?;
+ let aligns = args.find().unwrap_or(Spec::new(Some(Align::Left), None));
+ let offset = Spec::new(args.named("dx")?, args.named("dy")?);
let body: Template = args.expect("body")?;
Ok(Value::Template(Template::from_block(move |style| {
PlacedNode {
- child: body
- .pack(style)
- .moved(dx, dy)
- .aligned(Some(x.unwrap_or(Align::Left)), y),
+ child: body.pack(style).moved(offset).aligned(aligns),
}
})))
}
diff --git a/src/library/shape.rs b/src/library/shape.rs
index f47da82f..061b4d25 100644
--- a/src/library/shape.rs
+++ b/src/library/shape.rs
@@ -5,9 +5,8 @@ use crate::util::RcExt;
/// `rect`: A rectangle with optional content.
pub fn rect(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let width = args.named("width")?;
- let height = args.named("height")?;
- shape_impl(args, ShapeKind::Rect, width, height)
+ let sizing = Spec::new(args.named("width")?, args.named("height")?);
+ shape_impl(args, ShapeKind::Rect, sizing)
}
/// `square`: A square with optional content.
@@ -21,14 +20,14 @@ pub fn square(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
None => args.named("height")?,
size => size,
};
- shape_impl(args, ShapeKind::Square, width, height)
+ let sizing = Spec::new(width, height);
+ shape_impl(args, ShapeKind::Square, sizing)
}
/// `ellipse`: An ellipse with optional content.
pub fn ellipse(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let width = args.named("width")?;
- let height = args.named("height")?;
- shape_impl(args, ShapeKind::Ellipse, width, height)
+ let sizing = Spec::new(args.named("width")?, args.named("height")?);
+ shape_impl(args, ShapeKind::Ellipse, sizing)
}
/// `circle`: A circle with optional content.
@@ -42,14 +41,14 @@ pub fn circle(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
None => args.named("height")?,
diameter => diameter,
};
- shape_impl(args, ShapeKind::Circle, width, height)
+ let sizing = Spec::new(width, height);
+ shape_impl(args, ShapeKind::Circle, sizing)
}
fn shape_impl(
args: &mut Args,
kind: ShapeKind,
- width: Option<Linear>,
- height: Option<Linear>,
+ sizing: Spec<Option<Linear>>,
) -> TypResult<Value> {
// The default appearance of a shape.
let default = Stroke {
@@ -67,7 +66,10 @@ fn shape_impl(
}),
};
+ // Shorthand for padding.
let padding = Sides::splat(args.named("padding")?.unwrap_or_default());
+
+ // The shape's contents.
let body = args.find::<Template>();
Ok(Value::Template(Template::from_inline(move |style| {
@@ -78,7 +80,7 @@ fn shape_impl(
child: body.as_ref().map(|body| body.pack(style).padded(padding)),
}
.pack()
- .sized(width, height)
+ .sized(sizing)
})))
}
diff --git a/src/library/sized.rs b/src/library/sized.rs
index 3089f90b..8d69afac 100644
--- a/src/library/sized.rs
+++ b/src/library/sized.rs
@@ -2,21 +2,19 @@ use super::prelude::*;
/// `box`: Size content and place it into a paragraph.
pub fn box_(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let width = args.named("width")?;
- let height = args.named("height")?;
+ let sizing = Spec::new(args.named("width")?, args.named("height")?);
let body: Template = args.find().unwrap_or_default();
Ok(Value::Template(Template::from_inline(move |style| {
- body.pack(style).sized(width, height)
+ body.pack(style).sized(sizing)
})))
}
/// `block`: Size content and place it into the flow.
pub fn block(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let width = args.named("width")?;
- let height = args.named("height")?;
+ let sizing = Spec::new(args.named("width")?, args.named("height")?);
let body: Template = args.find().unwrap_or_default();
Ok(Value::Template(Template::from_block(move |style| {
- body.pack(style).sized(width, height)
+ body.pack(style).sized(sizing)
})))
}
diff --git a/src/library/transform.rs b/src/library/transform.rs
index 10752358..7553bef2 100644
--- a/src/library/transform.rs
+++ b/src/library/transform.rs
@@ -2,11 +2,10 @@ use super::prelude::*;
/// `move`: Move content without affecting layout.
pub fn move_(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let dx = args.named("dx")?;
- let dy = args.named("dy")?;
+ let offset = Spec::new(args.named("x")?, args.named("y")?);
let body: Template = args.expect("body")?;
Ok(Value::Template(Template::from_inline(move |style| {
- body.pack(style).moved(dx, dy)
+ body.pack(style).moved(offset)
})))
}