Repository: typst/typst
File: crates/typst-library/src/model/heading.rs (Rust)

Code before:
        }

        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)
        })
    }
}

impl ShowSet for Packed<HeadingElem> {
    fn show_set(&self, styles: StyleChain) -> Styles {
        let level = (**self).resolve_level(styles).get();
        let scale = match level {
            1 => 1.4,
            2 => 1.2,
            _ => 1.0,
        };

        let size = Em::new(scale);
        let above = Em::new(if level == 1 { 1.8 } else { 1.44 }) / scale;
        let below = Em::new(0.75) / scale;

        let mut out = Styles::new();
        out.set(TextElem::set_size(TextSize(size.into())));
        out.set(TextElem::set_weight(FontWeight::BOLD));
        out.set(BlockElem::set_above(Smart::Custom(above.into())));
        out.set(BlockElem::set_below(Smart::Custom(below.into())));
        out.set(BlockElem::set_sticky(true));
        out
    }
}

impl Count for Packed<HeadingElem> {
    fn update(&self) -> Option<CounterUpdate> {
        (**self)
            .numbering(StyleChain::default())
            .is_some()
            .then(|| CounterUpdate::Step((**self).resolve_level(StyleChain::default())))
    }
}

impl Refable for Packed<HeadingElem> {
    fn supplement(&self) -> Content {

Review comment (suggestion):
I think it should be 

```suggestion
                let t = [tag::h2, tag::h3, tag::h4, tag::h5, tag::h6][level + 1];
```


Code after:
            realized = realized.styled(ParElem::set_hanging_indent(indent.into()));
        }

        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).get();
            if level >= 6 {
                engine.sink.warn(warning!(span,
                    "heading of level {} was transformed to \
                    <div role=\"heading\" aria-level=\"{}\">, which is not \
                    supported by all assistive technology",
                    level, level + 1;
                    hint: "HTML only supports <h1> to <h6>, not <h{}>", level + 1;
                    hint: "you may want to restructure your document so that \
                          it doesn't contain deep headings"));
                HtmlElem::new(tag::div)
                    .with_body(Some(realized))
                    .with_attr(attr::role, "heading")
                    .with_attr(attr::aria_level, eco_format!("{}", level + 1))
                    .pack()
                    .spanned(span)
            } else {
                let t = [tag::h2, tag::h3, tag::h4, tag::h5, tag::h6][level - 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)
        })
    }
}

impl ShowSet for Packed<HeadingElem> {
    fn show_set(&self, styles: StyleChain) -> Styles {
        let level = (**self).resolve_level(styles).get();
        let scale = match level {
            1 => 1.4,
            2 => 1.2,
            _ => 1.0,
        };

        let size = Em::new(scale);
        let above = Em::new(if level == 1 { 1.8 } else { 1.44 }) / scale;
        let below = Em::new(0.75) / scale;

        let mut out = Styles::new();
        out.set(TextElem::set_size(TextSize(size.into())));
        out.set(TextElem::set_weight(FontWeight::BOLD));