Skip to content

Commit 4e8c550

Browse files
committed
refactor: Update code base for mkdocstrings 0.28
See mkdocstrings/mkdocstrings#727.
1 parent ad6f4ef commit 4e8c550

File tree

10 files changed

+443
-90
lines changed

10 files changed

+443
-90
lines changed

docs/configuration.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Configuration
2+
3+
This page lists the available configuration options and what they achieve.
4+
5+
[](){#setting-options}
6+
## `options`
7+
8+
You can specify a few configuration options under the `options` key:
9+
10+
```yaml title="mkdocs.yml"
11+
plugins:
12+
- mkdocstrings:
13+
handlers:
14+
shell:
15+
options:
16+
# some configuration
17+
```
18+
19+
[](){#option-extra}
20+
### `extra`
21+
22+
- **:octicons-package-24: Type [`dict`][] :material-equal: `{}`{ title="default value" }**
23+
24+
The `extra` option lets you inject additional variables into the Jinja context used when rendering templates. You can then use this extra context in your [overridden templates](https://mkdocstrings.github.io/usage/theming/#templates).
25+
26+
Local `extra` options will be merged into the global `extra` option:
27+
28+
```yaml title="in mkdocs.yml (global configuration)"
29+
plugins:
30+
- mkdocstrings:
31+
handlers:
32+
shell:
33+
options:
34+
extra:
35+
hello: world
36+
```
37+
38+
```md title="in docs/some_page.md (local configuration)"
39+
::: your_package.your_module.your_func
40+
handler: shell
41+
options:
42+
extra:
43+
foo: bar
44+
```
45+
46+
...will inject both `hello` and `foo` into the Jinja context when rendering `your_package.your_module.your_func`.
47+
48+
[](){#option-heading_level}
49+
### `heading_level`
50+
51+
- **:octicons-package-24: Type [`int`][] :material-equal: `2`{ title="default value" }**
52+
53+
The initial heading level to use.
54+
55+
When injecting documentation for an object,
56+
the object itself and its members are rendered.
57+
For each layer of objects, we increase the heading level by 1.
58+
59+
The initial heading level will be used for the first layer.
60+
If you set it to 3, then headings will start with `<h3>`.
61+
62+
If the [heading for the root object][show_root_heading] is not shown,
63+
then the initial heading level is used for its members.
64+
65+
```yaml title="in mkdocs.yml (global configuration)"
66+
plugins:
67+
- mkdocstrings:
68+
handlers:
69+
shell:
70+
options:
71+
heading_level: 2
72+
```
73+
74+
```md title="or in docs/some_page.md (local configuration)"
75+
::: path.to.module
76+
handler: shell
77+
options:
78+
heading_level: 3
79+
```
80+
81+
/// admonition | Preview
82+
type: preview
83+
84+
//// tab | With level 3 and root heading
85+
<h3><code>module</code> (3)</h3>
86+
<p>Docstring of the module.</p>
87+
<h4><code>ClassA</code> (4)</h4>
88+
<p>Docstring of class A.</p>
89+
<h4><code>ClassB</code> (4)</h4>
90+
<p>Docstring of class B.</p>
91+
<h5><code>method_1</code> (5)</h5>
92+
<p>Docstring of the method.</p>
93+
////
94+
95+
//// tab | With level 3, without root heading
96+
<p>Docstring of the module.</p>
97+
<h3><code>ClassA</code> (3)</h3>
98+
<p>Docstring of class A.</p>
99+
<h3><code>ClassB</code> (3)</h3>
100+
<p>Docstring of class B.</p>
101+
<h4><code>method_1</code> (4)</h4>
102+
<p>Docstring of the method.</p>
103+
////
104+
///
105+
106+
[](){#option-show_root_heading}
107+
### `show_root_heading`
108+
109+
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
110+
111+
Show the heading of the object at the root of the documentation tree
112+
(i.e. the object referenced by the identifier after `:::`).
113+
114+
While this option defaults to false for backwards compatibility, we recommend setting it to true. Note that the heading of the root object can be a level 1 heading (the first on the page):
115+
116+
```md
117+
# ::: path.to.object
118+
```
119+
120+
```yaml title="in mkdocs.yml (global configuration)"
121+
plugins:
122+
- mkdocstrings:
123+
handlers:
124+
shell:
125+
options:
126+
show_root_heading: false
127+
```
128+
129+
```md title="or in docs/some_page.md (local configuration)"
130+
::: path.to.Class
131+
handler: shell
132+
options:
133+
show_root_heading: true
134+
```
135+
136+
[](){#option-show_root_toc_entry}
137+
### `show_root_toc_entry`
138+
139+
- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }**
140+
<!-- - **:octicons-project-template-24: Template :material-null:** (N/A) -->
141+
142+
If the root heading is not shown, at least add a ToC entry for it.
143+
144+
If you inject documentation for an object in the middle of a page,
145+
after long paragraphs, and without showing the [root heading][show_root_heading],
146+
then you will not be able to link to this particular object
147+
as it won't have a permalink and will be "lost" in the middle of text.
148+
In that case, it is useful to add a hidden anchor to the document,
149+
which will also appear in the table of contents.
150+
151+
In other cases, you might want to disable the entry to avoid polluting the ToC.
152+
It is not possible to show the root heading *and* hide the ToC entry.
153+
154+
```yaml title="in mkdocs.yml (global configuration)"
155+
plugins:
156+
- mkdocstrings:
157+
handlers:
158+
shell:
159+
options:
160+
show_root_heading: false
161+
show_root_toc_entry: true
162+
```
163+
164+
```md title="or in docs/some_page.md (local configuration)"
165+
## Some heading
166+
167+
Lots of text.
168+
169+
::: path.to.object
170+
handler: shell
171+
options:
172+
show_root_heading: false
173+
show_root_toc_entry: false
174+
175+
## Other heading.
176+
177+
More text.
178+
```
179+
180+
/// admonition | Preview
181+
type: preview
182+
183+
//// tab | With ToC entry
184+
**Table of contents**<br>
185+
[Some heading](#permalink-to-some-heading){ title="#permalink-to-some-heading" }<br>
186+
[`object`](#permalink-to-object){ title="#permalink-to-object" }<br>
187+
[Other heading](#permalink-to-other-heading){ title="#permalink-to-other-heading" }
188+
////
189+
190+
//// tab | Without ToC entry
191+
**Table of contents**<br>
192+
[Some heading](#permalink-to-some-heading){ title="#permalink-to-some-heading" }<br>
193+
[Other heading](#permalink-to-other-heading){ title="#permalink-to-other-heading" }
194+
////
195+
///

docs/css/material.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,25 @@
22
.md-main__inner {
33
margin-bottom: 1.5rem;
44
}
5+
6+
/* Custom admonition: preview */
7+
:root {
8+
--md-admonition-icon--preview: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.5 12a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z"/><path d="M12 3.5c3.432 0 6.124 1.534 8.054 3.241 1.926 1.703 3.132 3.61 3.616 4.46a1.6 1.6 0 0 1 0 1.598c-.484.85-1.69 2.757-3.616 4.461-1.929 1.706-4.622 3.24-8.054 3.24-3.432 0-6.124-1.534-8.054-3.24C2.02 15.558.814 13.65.33 12.8a1.6 1.6 0 0 1 0-1.598c.484-.85 1.69-2.757 3.616-4.462C5.875 5.034 8.568 3.5 12 3.5ZM1.633 11.945a.115.115 0 0 0-.017.055c.001.02.006.039.017.056.441.774 1.551 2.527 3.307 4.08C6.691 17.685 9.045 19 12 19c2.955 0 5.31-1.315 7.06-2.864 1.756-1.553 2.866-3.306 3.307-4.08a.111.111 0 0 0 .017-.056.111.111 0 0 0-.017-.056c-.441-.773-1.551-2.527-3.307-4.08C17.309 6.315 14.955 5 12 5 9.045 5 6.69 6.314 4.94 7.865c-1.756 1.552-2.866 3.306-3.307 4.08Z"/></svg>');
9+
}
10+
11+
.md-typeset .admonition.preview,
12+
.md-typeset details.preview {
13+
border-color: rgb(220, 139, 240);
14+
}
15+
16+
.md-typeset .preview>.admonition-title,
17+
.md-typeset .preview>summary {
18+
background-color: rgba(142, 43, 155, 0.1);
19+
}
20+
21+
.md-typeset .preview>.admonition-title::before,
22+
.md-typeset .preview>summary::before {
23+
background-color: rgb(220, 139, 240);
24+
-webkit-mask-image: var(--md-admonition-icon--preview);
25+
mask-image: var(--md-admonition-icon--preview);
26+
}

duties.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def check_types(ctx: Context) -> None:
8989
ctx.run(
9090
tools.mypy(*PY_SRC_LIST, config_file="config/mypy.ini"),
9191
title=pyprefix("Type-checking"),
92+
# TODO: Update when Pydantic supports 3.14.
93+
nofail=sys.version_info >= (3, 14),
9294
)
9395

9496

mkdocs.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ validation:
1313
absolute_links: warn
1414
unrecognized_links: warn
1515

16+
hooks:
17+
- scripts/mkdocs_hooks.py
18+
1619
nav:
1720
- Home:
1821
- Overview: index.md
22+
- Configuration: configuration.md
1923
- Changelog: changelog.md
2024
- Credits: credits.md
2125
- License: license.md
@@ -87,6 +91,9 @@ markdown_extensions:
8791
- admonition
8892
- callouts
8993
- footnotes
94+
- pymdownx.blocks.admonition
95+
- pymdownx.blocks.tab:
96+
alternate_style: true
9097
- pymdownx.emoji:
9198
emoji_index: !!python/name:material.extensions.emoji.twemoji
9299
emoji_generator: !!python/name:material.extensions.emoji.to_svg
@@ -107,6 +114,7 @@ markdown_extensions:
107114

108115
plugins:
109116
- search
117+
- autorefs
110118
- markdown-exec
111119
- gen-files:
112120
scripts:

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ classifiers = [
2929
"Typing :: Typed",
3030
]
3131
dependencies = [
32-
"mkdocstrings>=0.18",
32+
"mkdocstrings>=0.28",
3333
"shellman>=1.0.0",
3434
]
3535

@@ -106,4 +106,5 @@ dev = [
106106
"mkdocstrings[python]>=0.25",
107107
# YORE: EOL 3.10: Remove line.
108108
"tomli>=2.0; python_version < '3.11'",
109+
"pydantic>=2.10",
109110
]

scripts/mkdocs_hooks.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Generate a JSON schema of the Python handler configuration."""
2+
3+
import json
4+
from dataclasses import fields
5+
from os.path import join
6+
from typing import Any
7+
8+
from mkdocs.config.defaults import MkDocsConfig
9+
from mkdocs.plugins import get_plugin_logger
10+
11+
from mkdocstrings_handlers.shell.config import ShellInputConfig, ShellInputOptions
12+
13+
# TODO: Update when Pydantic supports Python 3.14 (sources and duties as well).
14+
try:
15+
from pydantic import TypeAdapter
16+
except ImportError:
17+
TypeAdapter = None # type: ignore[assignment,misc]
18+
19+
20+
logger = get_plugin_logger(__name__)
21+
22+
23+
def on_post_build(config: MkDocsConfig, **kwargs: Any) -> None: # noqa: ARG001
24+
"""Write `schema.json` to the site directory."""
25+
if TypeAdapter is None:
26+
logger.info("Pydantic is not installed, skipping JSON schema generation")
27+
return
28+
adapter = TypeAdapter(ShellInputConfig)
29+
schema = adapter.json_schema()
30+
schema["$schema"] = "https://json-schema.org/draft-07/schema"
31+
with open(join(config.site_dir, "schema.json"), "w") as file:
32+
json.dump(schema, file, indent=2)
33+
logger.debug("Generated JSON schema")
34+
35+
autorefs = config["plugins"]["autorefs"]
36+
for field in fields(ShellInputConfig):
37+
if f"setting-{field.name}" not in autorefs._primary_url_map:
38+
logger.warning(f"Handler setting `{field.name}` is not documented")
39+
for field in fields(ShellInputOptions):
40+
if f"option-{field.name}" not in autorefs._primary_url_map:
41+
logger.warning(f"Configuration option `{field.name}` is not documented")

0 commit comments

Comments
 (0)