Skip to content

Commit ad3d7be

Browse files
Support embedding local images (#460)
* support embedding local images * [autofix.ci] apply automated fixes Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 01f3db9 commit ad3d7be

File tree

6 files changed

+124
-34
lines changed

6 files changed

+124
-34
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased: pdoc next
44

5+
- Docstrings can now include local images which will be embedded into the page, e.g. `![image](./image.png)`.
6+
([#282](https://github.com/mitmproxy/pdoc/issues/282), @mhils)
57
- Fix a bug in parsing Google-style docstrings with extraneous whitespace.
68
([#459](https://github.com/mitmproxy/pdoc/pull/459), @vsajip, @mhils)
79
- `pdoc.doc.Doc.members` now includes variables without type annotation and docstring.

docs/logo.png

14 KB
Loading

pdoc/docstrings.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
"""
1313
from __future__ import annotations
1414

15+
import base64
1516
import inspect
17+
import mimetypes
18+
import os
1619
import re
1720
import warnings
1821
from pathlib import Path
@@ -38,9 +41,32 @@ def convert(docstring: str, docformat: str, source_file: Path | None) -> str:
3841
if "numpy" in docformat:
3942
docstring = numpy(docstring)
4043

44+
if source_file is not None and os.environ.get("PDOC_EMBED_IMAGES") != "0":
45+
docstring = embed_images(docstring, source_file)
46+
4147
return docstring
4248

4349

50+
def embed_images(docstring: str, source_file: Path) -> str:
51+
def embed_local_image(m: re.Match) -> str:
52+
image_path = source_file.parent / m["href"]
53+
try:
54+
image_data = image_path.read_bytes()
55+
image_mime = mimetypes.guess_type(image_path)[0]
56+
except Exception:
57+
return m[0]
58+
else:
59+
data = base64.b64encode(image_data).decode()
60+
return f"![{m['alt']}](data:{image_mime};base64,{data})"
61+
62+
return re.sub(
63+
r"!\[\s*(?P<alt>.*?)\s*]\(\s*(?P<href>.+?)\s*\)",
64+
embed_local_image,
65+
docstring,
66+
)
67+
# TODO: Could probably do more here, e.g. support rST or raw HTML replacements.
68+
69+
4470
def google(docstring: str) -> str:
4571
"""Convert Google-style docstring sections into Markdown."""
4672
return re.sub(

test/testdata/demo_long.html

Lines changed: 83 additions & 34 deletions
Large diffs are not rendered by default.

test/testdata/demo_long.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,18 @@ class EnumDemo(enum.Enum):
245245
BLUE = enum.auto()
246246

247247

248+
def embed_image():
249+
"""
250+
This docstring includes an embedded image:
251+
252+
```
253+
![pdoc logo](../docs/logo.png)
254+
```
255+
256+
![pdoc logo](../../docs/logo.png)
257+
"""
258+
259+
248260
def admonitions():
249261
"""
250262
pdoc also supports basic reStructuredText admonitions:

test/testdata/demo_long.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,5 @@ This …
8888
<var BLUE = <EnumDemo.BLUE: 3>>
8989
<var name # inherited from enum.Enum.name, The name of the Enum…>
9090
<var value # inherited from enum.Enum.value, The value of the Enu…>>
91+
<function def embed_image(): ... # This docstring inclu…>
9192
<function def admonitions(): ... # pdoc also supports b…>>

0 commit comments

Comments
 (0)