pdoc icon indicating copy to clipboard operation
pdoc copied to clipboard

Support embedding local images (through reST directives)

Open StellarStorm opened this issue 3 years ago • 3 comments

Problem Description

First of all, it's great to see this package being developed again! I've only just begun converting my docstrings into external documentation and this looks like it will be a great fit for what I need!

"A picture is worth a thousand words" and this is sometimes especially true for documentation! Well-written documentation should always be the standard of course, and I'm very glad this project makes it easier to read docs in a browser rather than having to always read the code docstrings themselves. Sometimes, though, being able to include an image for a difficult operation or concept would make a world of difference.

For instance, my research focuses on a subfield of deep learning. Having a way to display small images/graphs of before and after a function is run on an array (or something similar) would go a long way into making certain difficult operations easier to conceptualize for myself and others.

Proposal

It would be great if this project added a way to include images into the output HTML files. One way to do this might be to use the reST directive .. image:: which could easily be added to the bottom of a docstring. That way, the docstring itself is minimally disrupted, but when viewing the generated external documentation, images could be easily seen.

Additionally, an extra bonus would be if this supported the google doc style instead of only restructured text. I mention this because including markdown files mentions using the __docformat__ = "restructuredtext", and I assume if adding images were to be supported, it might be done in a similar way. Unfortunately our code follows the Google doc style and setting __docformat__ = "restructuredtext" messes up the rendering.

Alternatives

I've considered using small Markdown snippets like

![image](/path/to/image.png)

and then including them in a docstring via

.. include:: snippet.md

However, this only displays the text content of the markdown file and not the included image.

Additional context

This is something that pdoc3 says they support through the reST .. image:: directive so hopefully it wouldn't be too much trouble to also integrate it here. I haven't tried using this feature from that package, but their documentation does say it is an option.

This looks similar to #272, however, I'm only concerned with being able to include images in the static HTML files, not display any warnings or caution symbols. Additionally, I believe (or hope! 😁 ) that this is within the scope of the project as markdown does support image display, while it didn't have native admonition support.

StellarStorm avatar Jul 15 '21 16:07 StellarStorm

Hey there!

Thanks for the extensive write-up. I think images in the docstrings is a reasonable feature request. Some thoughts on this:

  1. ![image](/path/to/image.png) should already work fine for absolute URLs or public resources like ![logo](https://pdoc.dev/logo.svg), but pdoc does not detect relative URLs to images and does not copy them over. So it's a bit limited in practice.
  2. I don't really want to open the can of worms where we copy images into pdoc's target directory, adjust the paths, and so on. That's a never-ending source of bugs. What we could do instead (with reasonable effort) is to detect local paths, and then embed all images directly into the page. How do you feel about that? It clearly is a tradeoff, but may be the most practical alternative here.
  3. I think we can take reST out of the discussion here. I'm happy for someone to contribute a .. image:: -> ![]() converter, but that's somewhat adjacent to the actual issue here.

mhils avatar Jul 15 '21 17:07 mhils

Hey @mhils Thanks!

For 1, it may be some issue on my end. I'll check and get back on this. 2 sounds great! Ditto for 3 -> I agree that limiting to reST isn't so important.

I don't know much about HTML/CSS or I'd try to implement this myself! But I'm happy y'all will consider this.

Cheers!

StellarStorm avatar Jul 15 '21 17:07 StellarStorm

Hi, @StellarStorm: Were you able to fix the issue. I am giving the absolute path (eg. image) and still I only see the text. @mhils: Is the convertor (.. image:: -> ) available. If not could you kindly help me with the issue.

Only the public URLs image works for me

vivek87799 avatar Aug 31 '22 07:08 vivek87799

One (maybe slightly crazy) way to embed images without caring where they're located (and thereby circumventing any pdoc-related issues), but still works, is to simply use raw HTML with a base64 encoded image, like:

<img src="data:image/png;base64,[BASE64_OF_IMAGE]">

You can actually automate this if you are using Python's built-in doctest module in the following way:

  1. run python3 -m doctest [FILE] on each file in your module. Make sure that your examples save the image somewhere on disk (to get the current dir, something like pathlib.Path(__file__).parent works)
  2. somewhere in the docs, have <img src="$TOKEN">, where $TOKEN (literal) is just a placeholder for the image (can be anything really, as long as it's unique)
  3. replace the token with its base64 equivalent; something like sed -i 's?\$TOKEN?'"$(base64 -w 0 ${PATH_TO_IMAGE})"'?g' [FILE] works for me
  4. run python3 -m pdoc [MODULE] to build the docs of the module

I'm running a customized version of the above in my CI and the results are satisfactory.

There are some downsides to embedding the image though:

  • the base64 encoded version of the image is usually larger than the original
  • as the image is "inlined", it must be downloaded immediately, and therefore can't be lazy-loaded (via loading="lazy" attribute)
  • (if using the default pdoc template) the images are actually downloaded twice: once in the source code (in "View Source"), and once when actually rendered. This also means the "View Source" section is a bit more difficult to navigate

so the main tradeoff is bandwidth (though the HTML is usually compressed so the downloaded result is still of reasonable size).

JCGoran avatar Nov 11 '22 10:11 JCGoran