mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Make align not behave box-like and smarter 📦
Doesn't layout contents into a box anymore, instead layouting inline in the parent context. Also makes axis inferring for center alignents smarter (just because I had fun doing it). It's unsure whether we want to keep it because it might be confusing.
This commit is contained in:
parent
8a45ec2875
commit
6febc03273
@ -5,16 +5,19 @@ use super::*;
|
|||||||
/// # Positional arguments
|
/// # Positional arguments
|
||||||
/// - At most two of `left`, `right`, `top`, `bottom`, `center`.
|
/// - At most two of `left`, `right`, `top`, `bottom`, `center`.
|
||||||
///
|
///
|
||||||
|
/// When `center` is used as a positional argument, it is automatically inferred
|
||||||
|
/// which axis it should apply to depending on further arguments, defaulting
|
||||||
|
/// to the axis, text is set along.
|
||||||
|
///
|
||||||
/// # Keyword arguments
|
/// # Keyword arguments
|
||||||
/// - `horizontal`: Any of `left`, `right` or `center`.
|
/// - `horizontal`: Any of `left`, `right` or `center`.
|
||||||
/// - `vertical`: Any of `top`, `bottom` or `center`.
|
/// - `vertical`: Any of `top`, `bottom` or `center`.
|
||||||
///
|
///
|
||||||
/// There may not be two alignment specifications for the same axis.
|
/// There may not be two alignment specifications for the same axis.
|
||||||
pub async fn align(_: Span, mut args: TableValue, mut ctx: LayoutContext<'_>) -> Pass<Value> {
|
pub async fn align(_: Span, mut args: TableValue, ctx: LayoutContext<'_>) -> Pass<Value> {
|
||||||
let mut f = Feedback::new();
|
let mut f = Feedback::new();
|
||||||
|
|
||||||
let content = args.take::<SyntaxTree>();
|
let content = args.take::<SyntaxTree>();
|
||||||
|
|
||||||
let h = args.take_key::<Spanned<SpecAlign>>("horizontal", &mut f);
|
let h = args.take_key::<Spanned<SpecAlign>>("horizontal", &mut f);
|
||||||
let v = args.take_key::<Spanned<SpecAlign>>("vertical", &mut f);
|
let v = args.take_key::<Spanned<SpecAlign>>("vertical", &mut f);
|
||||||
let all = args
|
let all = args
|
||||||
@ -23,40 +26,69 @@ pub async fn align(_: Span, mut args: TableValue, mut ctx: LayoutContext<'_>) ->
|
|||||||
.chain(h.into_iter().map(|align| (Some(Horizontal), align)))
|
.chain(h.into_iter().map(|align| (Some(Horizontal), align)))
|
||||||
.chain(v.into_iter().map(|align| (Some(Vertical), align)));
|
.chain(v.into_iter().map(|align| (Some(Vertical), align)));
|
||||||
|
|
||||||
|
let mut aligns = ctx.align;
|
||||||
let mut had = [false; 2];
|
let mut had = [false; 2];
|
||||||
for (axis, align) in all {
|
let mut deferred_center = false;
|
||||||
let axis = axis.unwrap_or_else(|| align.v.axis().unwrap_or_else(|| {
|
|
||||||
let primary = ctx.axes.primary.axis();
|
|
||||||
if !had[primary as usize] {
|
|
||||||
primary
|
|
||||||
} else {
|
|
||||||
ctx.axes.secondary.axis()
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
if align.v.axis().map(|a| a != axis).unwrap_or(false) {
|
for (axis, align) in all {
|
||||||
error!(
|
// Check whether we know which axis this alignment belongs to. We don't
|
||||||
@f, align.span,
|
// if the alignment is `center` for a positional argument. Then we set
|
||||||
"invalid alignment {} for {} axis", align.v, axis,
|
// `deferred_center` to true and handle the situation once we know more.
|
||||||
);
|
if let Some(axis) = axis {
|
||||||
} else if had[axis as usize] {
|
if align.v.axis().map(|a| a != axis).unwrap_or(false) {
|
||||||
error!(@f, align.span, "duplicate alignment for {} axis", axis);
|
error!(
|
||||||
|
@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);
|
||||||
|
} else {
|
||||||
|
let gen_align = align.v.to_generic(ctx.axes);
|
||||||
|
*aligns.get_mut(axis.to_generic(ctx.axes)) = gen_align;
|
||||||
|
had[axis as usize] = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if had == [true, true] {
|
||||||
|
error!(@f, 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];
|
||||||
|
aligns = LayoutAlign::new(Center, Center);
|
||||||
|
} else {
|
||||||
|
deferred_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[Horizontal as usize] {
|
||||||
|
Horizontal
|
||||||
|
} else {
|
||||||
|
Vertical
|
||||||
|
};
|
||||||
|
|
||||||
|
*aligns.get_mut(axis.to_generic(ctx.axes)) = Center;
|
||||||
|
|
||||||
had[axis as usize] = true;
|
had[axis as usize] = true;
|
||||||
let gen_axis = axis.to_generic(ctx.axes);
|
deferred_center = false;
|
||||||
let gen_align = align.v.to_generic(ctx.axes);
|
|
||||||
*ctx.align.get_mut(gen_axis) = gen_align;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If center has not been flushed by known, it is the only argument and then
|
||||||
|
// we default to applying it to the primary axis.
|
||||||
|
if deferred_center {
|
||||||
|
aligns.primary = Center;
|
||||||
|
}
|
||||||
|
|
||||||
let commands = match content {
|
let commands = match content {
|
||||||
Some(tree) => {
|
Some(tree) => vec![
|
||||||
ctx.base = ctx.spaces[0].size;
|
SetAlignment(aligns),
|
||||||
let layouted = layout(&tree, ctx).await;
|
LayoutSyntaxTree(tree),
|
||||||
f.extend(layouted.feedback);
|
SetAlignment(ctx.align),
|
||||||
vec![AddMultiple(layouted.output)]
|
],
|
||||||
}
|
None => vec![SetAlignment(aligns)],
|
||||||
None => vec![SetAlignment(ctx.align)],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
args.unexpected(&mut f);
|
args.unexpected(&mut f);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
Dr. Max Mustermann \
|
Dr. Max Mustermann \
|
||||||
Ola Nordmann, John Doe
|
Ola Nordmann, John Doe
|
||||||
]
|
]
|
||||||
[align: right][
|
[align: right >> box][
|
||||||
*WiSe 2019/2020* \
|
*WiSe 2019/2020* \
|
||||||
Woche 3
|
Woche 3
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user