Add auto option for page headers/footers (#4051)

Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
bluebear94 2024-05-06 11:23:32 -04:00 committed by GitHub
parent 6d0c159e97
commit 2f390c5317
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 19 deletions

View File

@ -228,6 +228,11 @@ pub struct PageElem {
/// The page's header. Fills the top margin of each page.
///
/// - Content: Shows the content as the header.
/// - `{auto}`: Shows the page number if a `numbering` is set and
/// `number-align` is `top`.
/// - `{none}`: Suppresses the header.
///
/// ```example
/// #set par(justify: true)
/// #set page(
@ -242,7 +247,7 @@ pub struct PageElem {
/// #lorem(19)
/// ```
#[borrowed]
pub header: Option<Content>,
pub header: Smart<Option<Content>>,
/// The amount the header is raised into the top margin.
#[resolve]
@ -251,8 +256,13 @@ pub struct PageElem {
/// The page's footer. Fills the bottom margin of each page.
///
/// For just a page number, the `numbering` property, typically suffices. If
/// you want to create a custom footer, but still display the page number,
/// - Content: Shows the content as the footer.
/// - `{auto}`: Shows the page number if a `numbering` is set and
/// `number-align` is `bottom`.
/// - `{none}`: Suppresses the footer.
///
/// For just a page number, the `numbering` property typically suffices. If
/// you want to create a custom footer but still display the page number,
/// you can directly access the [page counter]($counter).
///
/// ```example
@ -273,7 +283,7 @@ pub struct PageElem {
/// #lorem(48)
/// ```
#[borrowed]
pub footer: Option<Content>,
pub footer: Smart<Option<Content>>,
/// The amount the footer is lowered into the bottom margin.
#[resolve]
@ -402,17 +412,15 @@ impl Packed<PageElem> {
}
let fill = self.fill(styles);
let foreground = Cow::Borrowed(self.foreground(styles));
let background = Cow::Borrowed(self.background(styles));
let foreground = self.foreground(styles);
let background = self.background(styles);
let header_ascent = self.header_ascent(styles);
let footer_descent = self.footer_descent(styles);
let numbering = self.numbering(styles);
let number_align = self.number_align(styles);
let mut header = Cow::Borrowed(self.header(styles));
let mut footer = Cow::Borrowed(self.footer(styles));
// Construct the numbering (for header or footer).
let numbering_marginal = Cow::Owned(numbering.as_ref().map(|numbering| {
let numbering_marginal = numbering.as_ref().map(|numbering| {
let both = match numbering {
Numbering::Pattern(pattern) => pattern.pieces() >= 2,
Numbering::Func(_) => true,
@ -433,13 +441,21 @@ impl Packed<PageElem> {
}
counter
}));
});
if matches!(number_align.y(), Some(OuterVAlignment::Top)) {
header = if header.is_some() { header } else { numbering_marginal };
let header = self.header(styles);
let footer = self.footer(styles);
let (header, footer) = if matches!(number_align.y(), Some(OuterVAlignment::Top)) {
(
header.as_ref().unwrap_or(&numbering_marginal),
footer.as_ref().unwrap_or(&None),
)
} else {
footer = if footer.is_some() { footer } else { numbering_marginal };
}
(
header.as_ref().unwrap_or(&None),
footer.as_ref().unwrap_or(&numbering_marginal),
)
};
// Post-process pages.
let mut pages = Vec::with_capacity(frames.len());
@ -463,16 +479,16 @@ impl Packed<PageElem> {
let size = frame.size();
// Realize overlays.
for marginal in [&header, &footer, &background, &foreground] {
let Some(content) = &**marginal else { continue };
for marginal in [header, footer, background, foreground] {
let Some(content) = marginal.as_ref() else { continue };
let (pos, area, align);
if ptr::eq(marginal, &header) {
if ptr::eq(marginal, header) {
let ascent = header_ascent.relative_to(margin.top);
pos = Point::with_x(margin.left);
area = Size::new(pw, margin.top - ascent);
align = Alignment::BOTTOM;
} else if ptr::eq(marginal, &footer) {
} else if ptr::eq(marginal, footer) {
let descent = footer_descent.relative_to(margin.bottom);
pos = Point::new(margin.left, size.y - margin.bottom + descent);
area = Size::new(pw, margin.bottom - descent);
@ -490,7 +506,7 @@ impl Packed<PageElem> {
.layout(engine, styles, pod)?
.into_frame();
if ptr::eq(marginal, &header) || ptr::eq(marginal, &background) {
if ptr::eq(marginal, header) || ptr::eq(marginal, background) {
frame.prepend_frame(pos, sub);
} else {
frame.push_frame(pos, sub);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -229,3 +229,12 @@ The END.
#pagebreak()
#counter(page).update(53)
#filler
--- page-suppress-headers-and-footers ---
#set page(header: none, footer: none, numbering: "1")
Look, ma, no page numbers!
#pagebreak()
#set page(header: auto, footer: auto)
Default page numbers now.