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