diff --git a/crates/typst-layout/src/flow/compose.rs b/crates/typst-layout/src/flow/compose.rs index 343b47833..9650a7bc1 100644 --- a/crates/typst-layout/src/flow/compose.rs +++ b/crates/typst-layout/src/flow/compose.rs @@ -470,7 +470,20 @@ impl<'a, 'b> Composer<'a, 'b, '_, '_> { // Lay out nested footnotes. for (_, note) in nested { - self.footnote(note, regions, flow_need, migratable)?; + match self.footnote(note, regions, flow_need, migratable) { + // This footnote was already processed or queued. + Ok(_) => {} + // Footnotes always request a relayout when processed for the + // first time, so we ignore a relayout request since we're + // about to do so afterwards. Without this check, the first + // inner footnote interrupts processing of the following ones. + Err(Stop::Relayout(_)) => {} + // Either of + // - A `Stop::Finish` indicating that the frame's origin element + // should migrate to uphold the footnote invariant. + // - A fatal error. + err => return err, + } } // Since we laid out a footnote, we need a relayout. diff --git a/tests/ref/issue-5256-multiple-footnotes-in-footnote.png b/tests/ref/issue-5256-multiple-footnotes-in-footnote.png new file mode 100644 index 000000000..f9c173351 Binary files /dev/null and b/tests/ref/issue-5256-multiple-footnotes-in-footnote.png differ diff --git a/tests/suite/layout/flow/footnote.typ b/tests/suite/layout/flow/footnote.typ index 636023516..b549fbcab 100644 --- a/tests/suite/layout/flow/footnote.typ +++ b/tests/suite/layout/flow/footnote.typ @@ -291,3 +291,7 @@ A #footnote(numbering: "*")[B], C @fn, D @fn, E @fn. // Test whether an empty footnote would cause infinite loop #show footnote.entry: it => {} #lorem(3) #footnote[A footnote] + +--- issue-5256-multiple-footnotes-in-footnote --- +// Test whether all footnotes inside another footnote are listed. +#footnote[#footnote[A]#footnote[B]#footnote[C]]