How can I repair a figure caption set using a multiline content block with leading and trailing whitespace?

I’ve read a few posts on this, including this issue posted by @Andrew, but I’m still unclear on the best way to fix it (aside from avoiding it, which isn’t an option for now).

In short, I’m working with a Quarto-typst template and through a combination of their lua filters and our Julia code, our figure captions in the intermediate .typ file look like this:

#figure(
  box(width: 1in,height: 1in, fill: blue),
  caption: [
    #lorem(15)
  ]
)

The newlines inside [ ] result in additional whitespace being prepended to the outline entry for the figure.

It’s less of an issue for short captions, but it’s definitely noticeable for longer captions, which are common for our reports. I was able to resolve the issue using a combination of content-to-string conversion and show figure rule:

#let stringify(content) = {
    if content.has("text") {
        if type(content.text) == str {
            content.text
        } else {
            stringify(content.text)
        }
    } else if content.has("children") {
        content.children.map(stringify).join("")
    } else if content.has("body") {
        stringify(content.body)
    } else if content == [ ] {
        ""
    }
}

#show figure: it => {
  if it.kind == "mod-figure" {return it}
  figure(
    it.body,
    caption: stringify(it.caption.body),
    kind: "mod-figure",
    supplement: [Figure]
  )
}

My question is whether there’s a better way to handle this?

You can use a zero-length weak space to remove the unwanted space. For example we can modify the default entry format

#show outline.entry: it => link(
  it.element.location(),
  it.indented(it.prefix(), it.inner()),
)

and add the weak spacing before the inner part:

#show outline.entry: it => link(
  it.element.location(),
  it.indented(it.prefix(), h(0pt, weak: true) + it.inner()),
)

#outline(target: figure)

#figure(
  box(width: 1in,height: 1in, fill: blue),
  caption: [ #lorem(15) ]
)

2 Likes

Thanks sijo, that works well and with a lot less code. :slightly_smiling_face:

1 Like

You mean the spaces are added upstream, so you can’t fix the root problem? Until they fix it themselves, or something.

You mean the spaces are added upstream, so you can’t fix the root problem?

Yeah. When you add a figure to Quarto,

---
format:
    typst:
        keep-typ: true
---

![A Figure](myplot.svg)

the default output looks like this:

#figure([
#box(image("myplot.svg"))
], caption: figure.caption(
position: bottom, 
[
A Figure
]), 
kind: "quarto-float-fig", 
supplement: "Figure", 
)

That’s sad. Better report it, if not already.