mirror of
https://github.com/typst/typst
synced 2025-07-27 06:17:53 +08:00
Merge 3a96fe70d885c99173a1cd4a67ac95cfcb7f4373 into e9f1b5825a9d37ca0c173a7b2830ba36a27ca9e0
This commit is contained in:
commit
7a61743e9f
@ -1,5 +1,6 @@
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
|
use ecow::EcoString;
|
||||||
use typst_utils::NonZeroExt;
|
use typst_utils::NonZeroExt;
|
||||||
|
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
@ -103,6 +104,16 @@ pub struct HeadingElem {
|
|||||||
/// ```
|
/// ```
|
||||||
pub numbering: Option<Numbering>,
|
pub numbering: Option<Numbering>,
|
||||||
|
|
||||||
|
/// Plain-text displayed numbering.
|
||||||
|
///
|
||||||
|
/// This field is only necessary for creating PDF bookmarks.
|
||||||
|
/// The problem is that in the export stage, we don't have access to the World/Engine etc.
|
||||||
|
/// which is needed to resolve numbers and numbering patterns (or functions) into a concrete string/content.
|
||||||
|
/// Therefore, we have to save the result before the export stage.
|
||||||
|
#[internal]
|
||||||
|
#[synthesized]
|
||||||
|
pub numbering_displayed: EcoString,
|
||||||
|
|
||||||
/// A supplement for the heading.
|
/// A supplement for the heading.
|
||||||
///
|
///
|
||||||
/// For references to headings, this is added before the referenced number.
|
/// For references to headings, this is added before the referenced number.
|
||||||
@ -202,10 +213,23 @@ impl Synthesize for Packed<HeadingElem> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let numbering_displayed = if let (Some(numbering), Some(location)) =
|
||||||
|
(self.numbering.get_ref(styles).as_ref(), self.location())
|
||||||
|
{
|
||||||
|
Some(
|
||||||
|
self.counter()
|
||||||
|
.display_at_loc(engine, location, styles, numbering)?
|
||||||
|
.plain_text(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let elem = self.as_mut();
|
let elem = self.as_mut();
|
||||||
elem.level.set(Smart::Custom(elem.resolve_level(styles)));
|
elem.level.set(Smart::Custom(elem.resolve_level(styles)));
|
||||||
elem.supplement
|
elem.supplement
|
||||||
.set(Smart::Custom(Some(Supplement::Content(supplement))));
|
.set(Smart::Custom(Some(Supplement::Content(supplement))));
|
||||||
|
elem.numbering_displayed = numbering_displayed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,13 @@ impl<'a> HeadingNode<'a> {
|
|||||||
let pos = gc.document.introspector.position(loc);
|
let pos = gc.document.introspector.position(loc);
|
||||||
let page_index = pos.page.get() - 1;
|
let page_index = pos.page.get() - 1;
|
||||||
|
|
||||||
|
// Prepend the numbering to title if it exists
|
||||||
|
let title = match &self.element.numbering_displayed {
|
||||||
|
// The space should be a `h(0.3em)`, but only plain-texts are supported here.
|
||||||
|
Some(num) => format!("{num} {title}"),
|
||||||
|
None => title,
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(index) = gc.page_index_converter.pdf_page_index(page_index) {
|
if let Some(index) = gc.page_index_converter.pdf_page_index(page_index) {
|
||||||
let y = (pos.point.y - Abs::pt(10.0)).max(Abs::zero());
|
let y = (pos.point.y - Abs::pt(10.0)).max(Abs::zero());
|
||||||
let dest = XyzDestination::new(
|
let dest = XyzDestination::new(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user