Template format to align footnote text, with non-superscript numbers

I’m using pandoc & typst to do markdown to PDF. I’d like to format the footnote.entrys such that:

  1. The number is normal text (not superscript), followed by a ., then tab/indent, then first line of text.
  2. All text is left aligned together.

Similar to how Wikipedia does its references:

I’ve achieved #1 with the code below, but I’m unclear how to do #2 (alignment).

  show footnote.entry: it => {
    let loc = it.note.location()
    numbering(
      "1. ",
      ..counter(footnote).at(loc),
    )
    it.note.body
  }

You can use a grid to achieve that.

#set page(height: auto, width: 20em, margin: 1em)
#show footnote.entry: it => {
  let loc = it.note.location()
  grid(
    columns: (1em, 1fr),
    numbering("1: ", ..counter(footnote).at(loc)), it.note.body,
  )
}

Foot#footnote(lorem(15)),
note#footnote(lorem(28))

(set stroke: green + 0.5pt to debug)

2 Likes

Thanks. I implemented this as:

  show footnote.entry: it => {
    let loc = it.note.location()
    grid(
      columns: (1.5em, 1fr),
      align: (right, left),
      //stroke: green + 0.5pt, // uncomment to see grid
      // content:
      numbering("1. ", ..counter(footnote).at(loc)), // col 1
      it.note.body,                                  // col 2
    )
  }

Is there a way to auto-size the first column per-page, to align the dots?

It’s possible, but more complex…

#show footnote.entry: it => {
  let loc = it.note.location()

  let last-num = counter(footnote).at(
    query(footnote)
      // The current version use the same num-width for all pages.
      // If you want per-page num-width instead, uncomment the following line.
      // .filter(f => f.location().page() == loc.page())
      .last()
      .location(),
  )
  let num-width = measure(numbering("1. ", ..last-num)).width

  grid(
    columns: (num-width, 1fr),
    align: (right, left),
    numbering("1. ", ..counter(footnote).at(loc)), it.note.body,
  )
}
1 Like

Nice; thanks.

For my later reference, with tweaked wording:

  show footnote.entry: it => {
    let loc = it.note.location()

    // determine width for num column
    let last-num = counter(footnote).at(
      query(footnote)
        // Uncomment the `.filter` line for per-page num-width;
        //  otherwise we use the same num-width for all pages.
        //.filter(f => f.location().page() == loc.page())
        .last()
        .location(),
    )
    let num-width = measure(numbering("1. ", ..last-num)).width

    grid(
      columns: (num-width, 1fr),
      align: (right, left),
      //stroke: green + 0.5pt, // uncomment to see grid
      // content:
      numbering("1. ", ..counter(footnote).at(loc)), // col 1
      it.note.body,                                  // col 2
    )
  }
1 Like