Skip to content

Commit a6f7964

Browse files
authored
Allow using macros in docstrings (#687)
According to @pawamoy: > `mkdocs-macros` and `mkdocstrings` work at different levels: `mkdocs-macros` at the plugin level (in something like the `on_page_markdown` hook) while `mkdocstrings` renders docstrings at the Markdown conversion level, so in-between `on_page_markdown` and `on_page_content`. That means `mkdocs-macros` never sees the docstrings. To fix this, we can implement a hack to plug both together in the `define_env()` function for `mkdocs-macros`. Eventually a `mkdocs-macros` *pluglet* might be implemented so that this hack is not necessary anymore. For more context see: * mkdocstrings/mkdocstrings#615
2 parents 036863a + fac06af commit a6f7964

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

docs/_scripts/macros.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"""This module defines macros for use in Markdown files."""
55

66
import pathlib
7+
from typing import Any
78

9+
import markdown as md
810
from markdown.extensions import toc
911
from mkdocs_macros import plugin as macros
1012

@@ -56,3 +58,30 @@ def glossary(term: str) -> str:
5658
glossary_path = pathlib.Path("intro/glossary.md")
5759
link_path = glossary_path.relative_to(current_path.parent)
5860
return f"[{term}]({link_path}#{_slugify(term)})"
61+
62+
# The code below is a temporary workaround to make `mkdocs-macros` work with
63+
# `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
64+
# https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
65+
66+
# get mkdocstrings' Python handler
67+
python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
68+
69+
# get the `update_env` method of the Python handler
70+
update_env = python_handler.update_env
71+
72+
# override the `update_env` method of the Python handler
73+
def patched_update_env(markdown: md.Markdown, config: dict[str, Any]) -> None:
74+
update_env(markdown, config)
75+
76+
# get the `convert_markdown` filter of the env
77+
convert_markdown = python_handler.env.filters["convert_markdown"]
78+
79+
# build a chimera made of macros+mkdocstrings
80+
def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
81+
return convert_markdown(env.render(markdown), *args, **kwargs)
82+
83+
# patch the filter
84+
python_handler.env.filters["convert_markdown"] = render_convert
85+
86+
# patch the method
87+
python_handler.update_env = patched_update_env

mkdocs.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ plugins:
8888
- docs/_scripts/mkdocstrings_autoapi.py
8989
- literate-nav:
9090
nav_file: SUMMARY.md
91-
- macros:
92-
module_name: docs/_scripts/macros
93-
on_undefined: strict
94-
on_error_fail: true
9591
- mike:
9692
canonical_version: latest
9793
- mkdocstrings:
@@ -119,6 +115,13 @@ plugins:
119115
- https://protobuf.readthedocs.io/en/latest/objects.inv
120116
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
121117
- https://watchfiles.helpmanual.io/objects.inv
118+
# Note this plugin must be loaded after mkdocstrings to be able to use macros
119+
# inside docstrings. See the comment in `docs/_scripts/macros.py` for more
120+
# details
121+
- macros:
122+
module_name: docs/_scripts/macros
123+
on_undefined: strict
124+
on_error_fail: true
122125
- search
123126

124127
# Preview controls

0 commit comments

Comments
 (0)