diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-11-23 12:45:20 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-11-23 12:45:20 +0100 |
| commit | 4f9e5819bbab1f93ad4f4b789038c60487a76368 (patch) | |
| tree | 488a4e0422db4531d9882cf08f0b5cc21ae55a23 /src/library | |
| parent | d3f6040cedacad1b6c323be721c9086f6c5d9a44 (diff) | |
2d alignments with plus operator
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/align.rs | 20 | ||||
| -rw-r--r-- | src/library/image.rs | 5 | ||||
| -rw-r--r-- | src/library/mod.rs | 9 | ||||
| -rw-r--r-- | src/library/par.rs | 10 | ||||
| -rw-r--r-- | src/library/placed.rs | 11 | ||||
| -rw-r--r-- | src/library/shape.rs | 24 | ||||
| -rw-r--r-- | src/library/sized.rs | 10 | ||||
| -rw-r--r-- | src/library/transform.rs | 5 |
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) }))) } |
