summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Färber <01mf02@gmail.com>2024-12-04 17:55:37 +0100
committerGitHub <noreply@github.com>2024-12-04 16:55:37 +0000
commit60f1d8f9b5f7c11eade2573eea39cfd656509eed (patch)
tree3fd0810c2bca2512e2097a344fa538a37c3d49ad
parentbf1c7db6fcee967ea802a19430c1e27444e16da1 (diff)
Prepend section numbers to headings in HTML output. (#5522)
-rw-r--r--crates/typst-library/src/model/heading.rs46
1 files changed, 22 insertions, 24 deletions
diff --git a/crates/typst-library/src/model/heading.rs b/crates/typst-library/src/model/heading.rs
index eb3c5413..fc0e4ad2 100644
--- a/crates/typst-library/src/model/heading.rs
+++ b/crates/typst-library/src/model/heading.rs
@@ -217,21 +217,7 @@ impl Synthesize for Packed<HeadingElem> {
impl Show for Packed<HeadingElem> {
#[typst_macros::time(name = "heading", span = self.span())]
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
- if TargetElem::target_in(styles).is_html() {
- // HTML's h1 is closer to a title element. There should only be one.
- // Meanwhile, a level 1 Typst heading is a section heading. For this
- // reason, levels are offset by one: A Typst level 1 heading becomes
- // a `<h2>`.
- let level = self.resolve_level(styles);
- let t = [tag::h2, tag::h3, tag::h4, tag::h5, tag::h6][level.get().min(5) - 1];
-
- // TODO: Don't ignore the various non-body properties.
- let body = self.body().clone();
- return Ok(HtmlElem::new(t)
- .with_body(Some(body))
- .pack()
- .spanned(self.span()));
- }
+ let html = TargetElem::target_in(styles).is_html();
const SPACING_TO_NUMBERING: Em = Em::new(0.3);
@@ -250,7 +236,7 @@ impl Show for Packed<HeadingElem> {
.display_at_loc(engine, location, styles, numbering)?
.spanned(span);
- if hanging_indent.is_auto() {
+ if hanging_indent.is_auto() && !html {
let pod = Region::new(Axes::splat(Abs::inf()), Axes::splat(false));
// We don't have a locator for the numbering here, so we just
@@ -268,19 +254,31 @@ impl Show for Packed<HeadingElem> {
indent = size.x + SPACING_TO_NUMBERING.resolve(styles);
}
- realized = numbering
- + HElem::new(SPACING_TO_NUMBERING.into()).with_weak(true).pack()
- + realized;
+ let spacing = if html {
+ SpaceElem::shared().clone()
+ } else {
+ HElem::new(SPACING_TO_NUMBERING.into()).with_weak(true).pack()
+ };
+
+ realized = numbering + spacing + realized;
}
- if indent != Abs::zero() {
+ if indent != Abs::zero() && !html {
realized = realized.styled(ParElem::set_hanging_indent(indent.into()));
}
- Ok(BlockElem::new()
- .with_body(Some(BlockBody::Content(realized)))
- .pack()
- .spanned(span))
+ Ok(if html {
+ // HTML's h1 is closer to a title element. There should only be one.
+ // Meanwhile, a level 1 Typst heading is a section heading. For this
+ // reason, levels are offset by one: A Typst level 1 heading becomes
+ // a `<h2>`.
+ let level = self.resolve_level(styles);
+ let t = [tag::h2, tag::h3, tag::h4, tag::h5, tag::h6][level.get().min(5) - 1];
+ HtmlElem::new(t).with_body(Some(realized)).pack().spanned(span)
+ } else {
+ let realized = BlockBody::Content(realized);
+ BlockElem::new().with_body(Some(realized)).pack().spanned(span)
+ })
}
}