How can I generate a list of image (paths) from command line?

I’ve previously done a pretty brute-force grep-and-sed to generate a list of images a document uses (for use in a dependency graph generator for a build system), but this has failed in all kinds of wonderful scenarios. While looking for a way to make this more robust I recently discovered that there’s a query subcommand in the typst command. And by the looks if it, I should be able to generate a list of all images in a document using it.

If I run typst query mytest.typst figure, I get a json blob with what looks like mostly what I’m looking for, apart from that there are not mentions of the image files. If I instead use image instead of figure I get:

error: image is not locatable

I’m wondering if this is the way it should be done, and if it is – why is it failing?

I suspect the reason could be because I’m including my images in a rather unconventional way:

#let img = image("s-to-ts.svg")
#figure(
  scaled-image(img, DIA_SCALE),
  caption: [Blah, blah, blah],
) <s-to-ts>

This is basically a way to be able to scale all images (made in Dia) in a simple unified way – but is it interfering with manner in which images must be included in order for them to be query:able, or is there some other issue?

In general it is, but for performance reasons not all elements carry the necessary information to be queried.

The easiest way around this is to query metadata instead of the images directly. For example, you could define your own function for this:

#let my-image(path, ..args) = {
  image(path, ..args)
  [#metadata(path)<image>]
}

or, more automated by doing this by a show rule:

#show image: it => {
  it
  [#metadata(it.source)<image>]
}

There is a general caveat: the paths you get will be relative to the source file they appear in, but you won’t know what file that is. For example, depending on whether an image appears in main.typ or chapters/intro.typ, the query will give you image.jpg or ../image.jpg; you’ll need to figure that out on your own. One option could be to consistently use absolute paths, like /image.jpg.

3 Likes