mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Interpret vertical page number alignment differently
The vertical alignment of `number-align` now selects header or footer instead of aligning within the footer. This is a minor breaking change because - top behaves differently now - horizon is now forbidden - bottom (the new default) behaves differently, too Typical number-align usage will likely not use the vertical component at all, though. Fixes #645
This commit is contained in:
parent
87c0a5171a
commit
b76e8d5db9
@ -177,7 +177,8 @@ pub struct PageElem {
|
|||||||
|
|
||||||
/// How to [number]($func/numbering) the pages.
|
/// How to [number]($func/numbering) the pages.
|
||||||
///
|
///
|
||||||
/// If an explicit `footer` is given, the numbering is ignored.
|
/// If an explicit `footer` (or `header` for top-aligned numbering) is
|
||||||
|
/// given, the numbering is ignored.
|
||||||
///
|
///
|
||||||
/// ```example
|
/// ```example
|
||||||
/// #set page(
|
/// #set page(
|
||||||
@ -192,6 +193,11 @@ pub struct PageElem {
|
|||||||
|
|
||||||
/// The alignment of the page numbering.
|
/// The alignment of the page numbering.
|
||||||
///
|
///
|
||||||
|
/// If the vertical component is `top`, the numbering is placed into the
|
||||||
|
/// header and if it is `bottom`, it is placed in the footer. Horizon
|
||||||
|
/// alignment is forbidden. If an explicit matching `header` or `footer` is
|
||||||
|
/// given, the numbering is ignored.
|
||||||
|
///
|
||||||
/// ```example
|
/// ```example
|
||||||
/// #set page(
|
/// #set page(
|
||||||
/// margin: (top: 16pt, bottom: 24pt),
|
/// margin: (top: 16pt, bottom: 24pt),
|
||||||
@ -202,6 +208,15 @@ pub struct PageElem {
|
|||||||
/// #lorem(30)
|
/// #lorem(30)
|
||||||
/// ```
|
/// ```
|
||||||
#[default(Align::Center.into())]
|
#[default(Align::Center.into())]
|
||||||
|
#[parse({
|
||||||
|
let spanned: Option<Spanned<Axes<_>>> = args.named("number-align")?;
|
||||||
|
if let Some(Spanned { v, span }) = spanned {
|
||||||
|
if matches!(v.y, Some(GenAlign::Specific(Align::Horizon))) {
|
||||||
|
bail!(span, "page number cannot be `horizon`-aligned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spanned.map(|s| s.v)
|
||||||
|
})]
|
||||||
pub number_align: Axes<Option<GenAlign>>,
|
pub number_align: Axes<Option<GenAlign>>,
|
||||||
|
|
||||||
/// The page's header. Fills the top margin of each page.
|
/// The page's header. Fills the top margin of each page.
|
||||||
@ -372,25 +387,40 @@ impl PageElem {
|
|||||||
let fill = self.fill(styles);
|
let fill = self.fill(styles);
|
||||||
let foreground = self.foreground(styles);
|
let foreground = self.foreground(styles);
|
||||||
let background = self.background(styles);
|
let background = self.background(styles);
|
||||||
let header = self.header(styles);
|
|
||||||
let header_ascent = self.header_ascent(styles);
|
let header_ascent = self.header_ascent(styles);
|
||||||
let footer = self.footer(styles).or_else(|| {
|
|
||||||
self.numbering(styles).map(|numbering| {
|
|
||||||
let both = match &numbering {
|
|
||||||
Numbering::Pattern(pattern) => pattern.pieces() >= 2,
|
|
||||||
Numbering::Func(_) => true,
|
|
||||||
};
|
|
||||||
Counter::new(CounterKey::Page)
|
|
||||||
.display(Some(numbering), both)
|
|
||||||
.aligned(self.number_align(styles))
|
|
||||||
})
|
|
||||||
});
|
|
||||||
let footer_descent = self.footer_descent(styles);
|
let footer_descent = self.footer_descent(styles);
|
||||||
|
let numbering = self.numbering(styles);
|
||||||
|
let number_align = self.number_align(styles);
|
||||||
|
let mut header = self.header(styles);
|
||||||
|
let mut footer = self.footer(styles);
|
||||||
|
|
||||||
let numbering_meta = FrameItem::Meta(
|
// Construct the numbering (for header or footer).
|
||||||
Meta::PageNumbering(self.numbering(styles).into_value()),
|
let numbering_marginal = numbering.clone().map(|numbering| {
|
||||||
Size::zero(),
|
let both = match &numbering {
|
||||||
);
|
Numbering::Pattern(pattern) => pattern.pieces() >= 2,
|
||||||
|
Numbering::Func(_) => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut counter =
|
||||||
|
Counter::new(CounterKey::Page).display(Some(numbering), both);
|
||||||
|
|
||||||
|
// We interpret the Y alignment as selecting header or footer
|
||||||
|
// and then ignore it for aligning the actual number.
|
||||||
|
if let Some(x) = number_align.x {
|
||||||
|
counter = counter.aligned(Axes::with_x(Some(x)));
|
||||||
|
}
|
||||||
|
|
||||||
|
counter
|
||||||
|
});
|
||||||
|
|
||||||
|
if matches!(number_align.y, Some(GenAlign::Specific(Align::Top))) {
|
||||||
|
header = header.or(numbering_marginal);
|
||||||
|
} else {
|
||||||
|
footer = footer.or(numbering_marginal);
|
||||||
|
}
|
||||||
|
|
||||||
|
let numbering_meta =
|
||||||
|
FrameItem::Meta(Meta::PageNumbering(numbering.into_value()), Size::zero());
|
||||||
|
|
||||||
// Post-process pages.
|
// Post-process pages.
|
||||||
for frame in frames.iter_mut() {
|
for frame in frames.iter_mut() {
|
||||||
|
@ -34,7 +34,7 @@ document or in your template.
|
|||||||
"iso-b7",
|
"iso-b7",
|
||||||
header: rect[Header],
|
header: rect[Header],
|
||||||
footer: rect[Footer],
|
footer: rect[Footer],
|
||||||
number-align: top + center,
|
number-align: center,
|
||||||
)
|
)
|
||||||
|
|
||||||
#rect(fill: rgb("#565565"))
|
#rect(fill: rgb("#565565"))
|
||||||
|
BIN
tests/ref/layout/page-number-align.png
Normal file
BIN
tests/ref/layout/page-number-align.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
25
tests/typ/layout/page-number-align.typ
Normal file
25
tests/typ/layout/page-number-align.typ
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Test page number alignment.
|
||||||
|
|
||||||
|
---
|
||||||
|
#set page(
|
||||||
|
height: 100pt,
|
||||||
|
margin: 30pt,
|
||||||
|
numbering: "(1)",
|
||||||
|
number-align: top + right,
|
||||||
|
)
|
||||||
|
|
||||||
|
#block(width: 100%, height: 100%, fill: aqua.lighten(50%))
|
||||||
|
|
||||||
|
---
|
||||||
|
#set page(
|
||||||
|
height: 100pt,
|
||||||
|
margin: 30pt,
|
||||||
|
numbering: "[1]",
|
||||||
|
number-align: bottom + left,
|
||||||
|
)
|
||||||
|
|
||||||
|
#block(width: 100%, height: 100%, fill: aqua.lighten(50%))
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 25-39 page number cannot be `horizon`-aligned
|
||||||
|
#set page(number-align: left + horizon)
|
Loading…
x
Reference in New Issue
Block a user