summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbluebear94 <uruwi@protonmail.com>2024-05-06 11:23:32 -0400
committerGitHub <noreply@github.com>2024-05-06 15:23:32 +0000
commit2f390c53173707671387292b18cc40e4c3f12a60 (patch)
treefc55fcf691c1d858d24483693244748b493a641f /crates
parent6d0c159e97a9274fedcdd269b886385e987da6e0 (diff)
Add `auto` option for page headers/footers (#4051)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates')
-rw-r--r--crates/typst/src/layout/page.rs56
1 files changed, 36 insertions, 20 deletions
diff --git a/crates/typst/src/layout/page.rs b/crates/typst/src/layout/page.rs
index f6221887..c354dc81 100644
--- a/crates/typst/src/layout/page.rs
+++ b/crates/typst/src/layout/page.rs
@@ -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);