Skip to content

Commit ac6f24a

Browse files
authored
Process HTML <img> tags in addition to markdown image markup ![](...) when embedding local images (#785)
1 parent fd74e2e commit ac6f24a

5 files changed

Lines changed: 91 additions & 61 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## Unreleased: pdoc next
66

77
- Fix handling of URL-escaped module names ([#787](https://github.com/mitmproxy/pdoc/pull/787), @iFreilicht)
8+
- Embed local images referenced in docstrings with an HTML image tag (`<img src="./image.png">`) in addition to Markdown (`![image](./image.png)`) ([#785](https://github.com/mitmproxy/pdoc/pull/785), @earshinov)
89

910
## 2024-12-12: pdoc 15.0.1
1011

pdoc/docstrings.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,28 @@ def convert(docstring: str, docformat: str, source_file: Path | None) -> str:
6363

6464

6565
def embed_images(docstring: str, source_file: Path) -> str:
66+
def local_image_to_data_uri(href: str) -> str:
67+
image_path = source_file.parent / href
68+
image_data = image_path.read_bytes()
69+
image_mime = mimetypes.guess_type(image_path)[0]
70+
image_data_b64 = base64.b64encode(image_data).decode()
71+
return f"data:{image_mime};base64,{image_data_b64}"
72+
6673
def embed_local_image(m: re.Match) -> str:
67-
image_path = source_file.parent / m["href"]
6874
try:
69-
image_data = image_path.read_bytes()
70-
image_mime = mimetypes.guess_type(image_path)[0]
75+
href = local_image_to_data_uri(m["href"])
7176
except Exception:
7277
return m[0]
7378
else:
74-
data = base64.b64encode(image_data).decode()
75-
return f"![{m['alt']}](data:{image_mime};base64,{data})"
76-
77-
return re.sub(
78-
r"!\[\s*(?P<alt>.*?)\s*]\(\s*(?P<href>.+?)\s*\)",
79-
embed_local_image,
80-
docstring,
81-
)
82-
# TODO: Could probably do more here, e.g. support rST or raw HTML replacements.
79+
return m["before"] + href + m["after"]
80+
81+
# TODO: Could probably do more here, e.g. support rST replacements.
82+
for regex in [
83+
r"(?P<before>!\[\s*.*?\s*]\(\s*)(?P<href>.+?)(?P<after>\s*\))",
84+
r"""(?P<before>src=['"])(?P<href>.+?)(?P<after>['"])""",
85+
]:
86+
docstring = re.sub(regex, embed_local_image, docstring)
87+
return docstring
8388

8489

8590
def google(docstring: str) -> str:

test/testdata/demo_long.html

Lines changed: 63 additions & 46 deletions
Large diffs are not rendered by default.

test/testdata/demo_long.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@
3939

4040
FOO_CONSTANT: int = 42
4141
"""
42-
A happy constant. ✨
42+
A happy constant. ✨
4343
pdoc documents constants with their type annotation and default value.
4444
"""
4545

4646
FOO_SINGLETON: "Foo"
4747
"""
4848
This variable is annotated with a type only, but not assigned to a value.
49-
We also haven't defined the associated type (`Foo`) yet,
49+
We also haven't defined the associated type (`Foo`) yet,
5050
so the type annotation in the code in the source code is actually a string literal:
5151
5252
```python
@@ -255,6 +255,12 @@ def embed_image():
255255
```
256256
257257
![pdoc logo](../../docs/logo.png)
258+
259+
```
260+
<img src="../docs/logo.png" alt="pdoc logo" width="150">
261+
```
262+
263+
<img src="../../docs/logo.png" alt="pdoc logo" width="150">
258264
"""
259265

260266

test/testdata/demo_long.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<module demo_long # # Test Module
22

33
This …
4-
<var FOO_CONSTANT: int = 42 # A happy constant. ✨ …>
4+
<var FOO_CONSTANT: int = 42 # A happy constant. ✨
5+
…>
56
<var FOO_SINGLETON: demo_long.Foo # This variable is ann…>
67
<var NO_DOCSTRING: int>
78
<function def a_simple_function(a: str) -> str: ... # This is a basic modu…>

0 commit comments

Comments
 (0)