mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Add auto
option for page headers/footers (#4051)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
parent
6d0c159e97
commit
2f390c5317
@ -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);
|
||||
|
BIN
tests/ref/page-suppress-headers-and-footers.png
Normal file
BIN
tests/ref/page-suppress-headers-and-footers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user