List of figures

The glossary above makes the mechanism easy to follow, at the cost of being a little toy — two terms, one line each. Here’s a version closer to what you’d actually paste into a real project: a “List of Figures” companion, several entries deep, spanning a page break, each citing the real page its figure landed on.

#import "../../lib.typ": *

// A fuller example than the glossary above -- closer to something you
// might actually copy into a real project: a "List of Figures"
// companion, generated instead of hand-maintained, citing the real page
// each figure landed on. Numbers figures in anchor order (1, 2, 3, ...)
// rather than reading Typst's own figure counter -- simpler, and exact
// here since fig() is the only thing creating figures in this document;
// a project mixing fig() with bare figure() calls would want
// counter(figure).at(..) instead.

#let fig(caption, body) = {
  let content = figure(body, caption: caption)
  anchor("demo-figure", (caption: caption))
  content
}

#let render-list-of-figures() = context {
  let hits = anchors("demo-figure")
  for (i, h) in hits.enumerate() [
    *Figure #(i + 1).* #h.value.caption --- p. #h.location().page()
    #linebreak()
  ]
}

#let list-of-figures = satellite("list-of-figures", render: () => render-list-of-figures())

#show: bundle.with(
  template: body => {
    set page(width: 16.6cm, height: auto, margin: 12pt)
    set text(size: 10.5pt)
    body
  },
  documents: (list-of-figures,),
)

= Methods

#fig([Study flow diagram.], rect(width: 3cm, height: 1.5cm, align(center + horizon)[Flow]))

#lorem(90)
#pagebreak()

= Results

#fig([Primary outcome over time.], rect(width: 3cm, height: 1.5cm, align(center + horizon)[Chart A]))

#fig([Subgroup analysis.], rect(width: 3cm, height: 1.5cm, align(center + horizon)[Chart B]))

manuscript.pdf — three ordinary figures across two pages, nothing about them different from any other Typst document:

page 1
page 2

list-of-figures.pdf, from the same compile:

fig() numbers its own entries by the order anchor() calls arrive in, rather than reading Typst’s built-in counter(figure) — simpler, and exactly right as long as fig() is the only thing creating figures in the document (a project mixing fig() with bare figure() calls would want counter(figure).at(hit.location()) instead, the same real-counter trick strip-labels uses above). Either way, the page numbers are never guessed or hand-typed — they come from location().page() on the anchor Typst itself placed, in the very compile that produced manuscript.pdf.

← The anchor primitivesatellite and bundle →