summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library/align.rs95
-rw-r--r--src/library/font.rs8
2 files changed, 55 insertions, 48 deletions
diff --git a/src/library/align.rs b/src/library/align.rs
index ba5de18a..e7a8eb77 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -16,18 +16,21 @@ use crate::prelude::*;
/// There may not be two alignment specifications for the same axis.
pub async fn align(mut args: Args, ctx: &mut LayoutContext) -> Value {
let body = args.find::<SynTree>();
- let h = args.get::<_, Spanned<SpecAlign>>(ctx, "horizontal");
- let v = args.get::<_, Spanned<SpecAlign>>(ctx, "vertical");
- let pos = args.find_all::<Spanned<SpecAlign>>();
+ let first = args.get::<_, Spanned<SpecAlign>>(ctx, 0);
+ let second = args.get::<_, Spanned<SpecAlign>>(ctx, 1);
+ let hor = args.get::<_, Spanned<SpecAlign>>(ctx, "horizontal");
+ let ver = args.get::<_, Spanned<SpecAlign>>(ctx, "vertical");
+ args.done(ctx);
- let iter = pos
+ let iter = first
+ .into_iter()
+ .chain(second.into_iter())
.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)));
+ .chain(hor.into_iter().map(|align| (Some(SpecAxis::Horizontal), align)))
+ .chain(ver.into_iter().map(|align| (Some(SpecAxis::Vertical), align)));
- let aligns = parse_aligns(ctx, iter);
+ let aligns = dedup_aligns(ctx, iter);
- args.done(ctx);
Value::Commands(match body {
Some(tree) => vec![
SetAlignment(aligns),
@@ -39,63 +42,67 @@ pub async fn align(mut args: Args, ctx: &mut LayoutContext) -> Value {
}
/// Deduplicate alignments and deduce to which axes they apply.
-fn parse_aligns(
+fn dedup_aligns(
ctx: &mut LayoutContext,
iter: impl Iterator<Item = (Option<SpecAxis>, Spanned<SpecAlign>)>,
) -> LayoutAlign {
let mut aligns = ctx.state.align;
- let mut had = [false; 2];
- let mut deferred_center = false;
+ let mut had = Gen2::new(false, false);
+ let mut had_center = false;
- for (axis, align) in iter {
- // Check whether we know which axis this alignment belongs to. We don't
- // if the alignment is `center` for a positional argument. Then we set
- // `deferred_center` to true and handle the situation once we know more.
+ for (axis, Spanned { v: align, span }) in iter {
+ // Check whether we know which axis this alignment belongs to.
if let Some(axis) = axis {
- if align.v.axis().map_or(false, |a| a != axis) {
+ // We know the axis.
+ let gen_axis = axis.to_gen(ctx.state.sys);
+ let gen_align = align.to_gen(ctx.state.sys);
+
+ if align.axis().map_or(false, |a| a != axis) {
ctx.diag(error!(
- align.span,
- "invalid alignment {} for {} axis", align.v, axis,
+ span,
+ "invalid alignment `{}` for {} axis", align, axis,
));
- } else if had[axis as usize] {
- ctx.diag(error!(align.span, "duplicate alignment for {} axis", axis));
+ } else if had.get(gen_axis) {
+ ctx.diag(error!(span, "duplicate alignment for {} axis", axis));
} else {
- 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;
+ *aligns.get_mut(gen_axis) = gen_align;
+ *had.get_mut(gen_axis) = true;
}
} else {
- if had == [true, true] {
- ctx.diag(error!(align.span, "duplicate alignment"));
- } else if deferred_center {
- // We have two unflushed centers, meaning we know that both axes
- // are to be centered.
- had = [true, true];
+ // We don't know the axis: This has to be a `center` alignment for a
+ // positional argument.
+ debug_assert_eq!(align, SpecAlign::Center);
+
+ if had.primary && had.secondary {
+ ctx.diag(error!(span, "duplicate alignment"));
+ } else if had_center {
+ // Both this and the previous one are unspecified `center`
+ // alignments. Both axes should be centered.
aligns = LayoutAlign::new(GenAlign::Center, GenAlign::Center);
+ had.primary = true;
+ had.secondary = true;
} else {
- deferred_center = true;
+ had_center = true;
}
}
- // Flush a deferred center alignment if we know have had at least one
- // known alignment.
- if deferred_center && had != [false, false] {
- let axis = if !had[SpecAxis::Horizontal as usize] {
- SpecAxis::Horizontal
+ // If we we know one alignment, we can handle the unspecified `center`
+ // alignment.
+ if had_center && (had.primary || had.secondary) {
+ if had.primary {
+ aligns.secondary = GenAlign::Center;
+ had.secondary = true;
} else {
- SpecAxis::Vertical
- };
-
- *aligns.get_mut(axis.to_gen(ctx.state.sys)) = GenAlign::Center;
-
- had[axis as usize] = true;
- deferred_center = false;
+ aligns.primary = GenAlign::Center;
+ had.primary = true;
+ }
+ had_center = false;
}
}
- // If center has not been flushed by known, it is the only argument and then
+ // If center has not been flushed by now, it is the only argument and then
// we default to applying it to the primary axis.
- if deferred_center {
+ if had_center {
aligns.primary = GenAlign::Center;
}
diff --git a/src/library/font.rs b/src/library/font.rs
index 60380def..21fb2d13 100644
--- a/src/library/font.rs
+++ b/src/library/font.rs
@@ -51,7 +51,7 @@ use crate::prelude::*;
/// ```
pub async fn font(mut args: Args, ctx: &mut LayoutContext) -> Value {
let mut text = ctx.state.text.clone();
- let mut needs_flatten = false;
+ let mut needs_flattening = false;
let body = args.find::<SynTree>();
@@ -67,7 +67,7 @@ pub async fn font(mut args: Args, ctx: &mut LayoutContext) -> Value {
let list: Vec<_> = args.find_all::<StringLike>().map(|s| s.to_lowercase()).collect();
if !list.is_empty() {
text.fallback.list = list;
- needs_flatten = true;
+ needs_flattening = true;
}
if let Some(style) = args.get::<_, FontStyle>(ctx, "style") {
@@ -89,12 +89,12 @@ pub async fn font(mut args: Args, ctx: &mut LayoutContext) -> Value {
.collect();
text.fallback.update_class_list(class, fallback);
- needs_flatten = true;
+ needs_flattening = true;
}
args.done(ctx);
- if needs_flatten {
+ if needs_flattening {
text.fallback.flatten();
}