3
votes

As title states, I'm using sphinx-doc and I really want to conditionally render static PNGs when the build output is latexpdf and animated GIFs when built for the web.

Ideally, it would be nice to be able to do this in the rst file itself somehow... semantically a:

if builder == html: .. image: blah blah elif builder == latexpdf: .. image: blah blah

2

2 Answers

7
votes

From the Sphinx documentation for images:

Sphinx extends the standard docutils behavior by allowing an asterisk for the extension:

.. image:: gnu.*

Sphinx then searches for all images matching the provided pattern and determines their type. Each builder then chooses the best image out of these candidates. For instance, if the file name gnu.* was given and two files gnu.pdf and gnu.png existed in the source tree, the LaTeX builder would choose the former, while the HTML builder would prefer the latter. Supported image types and choosing priority are defined at Available builders.

To customize the "best image" order for a given builder, edit your conf.py to override the StandaloneHTMLBuilder class with the supported_image_types order you prefer.

from sphinx.builders.html import StandaloneHTMLBuilder
StandaloneHTMLBuilder.supported_image_types = [
    'image/svg+xml',
    'image/gif',
    'image/png',
    'image/jpeg'
]
3
votes

In case it's useful for anyone else, I went with a variant of Steve Piercy's very helpful answer that attempts to future-proof the code and prevent mystery missing images. It uses the same structure, but appends any items that are in StandaloneHTMLBuilder.supported_image_types by default that aren't in the new set we're providing. I was considering if Sphinx started supporting something like HEIC images, or other new standards come out, this would allow them to be seamlessly integrated.

new_supported_image_types = [
    'image/svg+xml',
    'image/gif',
    'image/png',
    'image/jpeg'
]

# construct it this way so that if Sphinx adds default support for additional images, such
# as HEIC, then what we do is add any of those to the end. We start with the ones
# we want to support in this order, then subtract them from the defaults to identify
# any remaining items that we append to the end of the list

additional_default_supported_images = list(set(StandaloneHTMLBuilder.supported_image_types) - set(new_supported_image_types))
StandaloneHTMLBuilder.supported_image_types = new_supported_image_types + additional_default_supported_images