Repository: typst/typst
File: crates/typst-html/src/rules.rs (Rust)

Code before:
        }

        realized = blockquote.pack().spanned(span);

        if let Some(attribution) = attribution.as_ref() {
            realized += attribution.realize(span);
        }
    } else if let Some(Attribution::Label(label)) = attribution {
        realized += SpaceElem::shared().clone();
        realized += CiteElem::new(*label).pack().spanned(span);
    }

    Ok(realized)
};

const FOOTNOTE_RULE: ShowFn<FootnoteElem> = |elem, engine, styles| {
    let span = elem.span();
    let (dest, num) = elem.realize(engine, styles)?;
    let sup = SuperElem::new(num).pack().spanned(span);

    // Link to the footnote entry.
    let link = LinkElem::new(dest.into(), sup)
        .pack()
        .styled(HtmlElem::role.set(Some("doc-noteref".into())));

    // Indicates the presence of a default footnote rule to emit a warning when
    // no footnote container is available.
    let marker = FootnoteMarker::new().pack().spanned(span);

    Ok(HElem::hole().clone() + link + marker)
};

/// This is inserted at the end of the body to display footnotes. In the future,
/// we can expose this to allow customizing where the footnotes appear. It could
/// also be exposed for paged export.
#[elem]
pub struct FootnoteContainer {}

impl FootnoteContainer {
    /// Get the globally shared footnote container element.
    pub fn shared() -> &'static Content {
        singleton!(Content, FootnoteContainer::new().pack())
    }

    /// Fails with an error if there are footnotes.
    pub fn unsupported_with_custom_dom(engine: &Engine) -> SourceResult<()> {
        let markers = engine.introspector.query(&FootnoteMarker::ELEM.select());
        if markers.is_empty() {
            return Ok(());
        }


Review comment (suggestion):
```suggestion
    // Indicates the presence of a default footnote rule to emit an error when
```

Code after:
        }

        realized = blockquote.pack().spanned(span);

        if let Some(attribution) = attribution.as_ref() {
            realized += attribution.realize(span);
        }
    } else if let Some(Attribution::Label(label)) = attribution {
        realized += SpaceElem::shared().clone();
        realized += CiteElem::new(*label).pack().spanned(span);
    }

    Ok(realized)
};

const FOOTNOTE_RULE: ShowFn<FootnoteElem> = |elem, engine, styles| {
    let span = elem.span();
    let (dest, num) = elem.realize(engine, styles)?;
    let sup = SuperElem::new(num).pack().spanned(span);

    // Link to the footnote entry.
    let link = LinkElem::new(dest.into(), sup)
        .pack()
        .styled(HtmlElem::role.set(Some("doc-noteref".into())));

    // Indicates the presence of a default footnote rule to emit an error when
    // no footnote container is available.
    let marker = FootnoteMarker::new().pack().spanned(span);

    Ok(HElem::hole().clone() + link + marker)
};

/// This is inserted at the end of the body to display footnotes. In the future,
/// we can expose this to allow customizing where the footnotes appear. It could
/// also be exposed for paged export.
#[elem]
pub struct FootnoteContainer {}

impl FootnoteContainer {
    /// Get the globally shared footnote container element.
    pub fn shared() -> &'static Content {
        singleton!(Content, FootnoteContainer::new().pack())
    }

    /// Fails with an error if there are footnotes.
    pub fn unsupported_with_custom_dom(engine: &Engine) -> SourceResult<()> {
        let markers = engine.introspector.query(&FootnoteMarker::ELEM.select());
        if markers.is_empty() {
            return Ok(());
        }