Skip to content

Commit 4a97755

Browse files
authored
docs: Make recipe work with MkDocs -f option
1 parent b3edf89 commit 4a97755

File tree

1 file changed

+81
-62
lines changed

1 file changed

+81
-62
lines changed

docs/recipes.md

Lines changed: 81 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ Let say you have a project called `project`.
1717
This project has a lot of source files, or modules,
1818
which live in the `src` folder:
1919

20-
```
21-
📁 repo
22-
└─╴📁 src
23-
└─╴📁 project
24-
├─╴📄 lorem
25-
├─╴📄 ipsum
26-
├─╴📄 dolor
27-
├─╴📄 sit
28-
└─╴📄 amet
20+
```tree
21+
repo/
22+
src/
23+
project/
24+
lorem
25+
ipsum
26+
dolor
27+
sit
28+
amet
2929
```
3030

3131
Without an automatic process, you will have to manually
@@ -49,87 +49,102 @@ and configure it like so:
4949

5050
```yaml title="mkdocs.yml"
5151
plugins:
52-
- search # (1)
52+
- search # (1)!
5353
- gen-files:
5454
scripts:
55-
- docs/gen_ref_pages.py # (2)
55+
- scripts/gen_ref_pages.py # (2)!
5656
- mkdocstrings
5757
```
5858
5959
1. Don't forget to load the `search` plugin when redefining the `plugins` item.
6060
2. The magic happens here, see below how it works.
6161

6262
mkdocs-gen-files is able to run Python scripts at build time.
63-
The Python script that we will execute lives in the docs folder,
63+
The Python script that we will execute lives in a scripts folder,
6464
and is named `gen_ref_pages.py`, like "generate code reference pages".
6565

66-
```python title="docs/gen_ref_pages.py"
66+
```tree
67+
repo/
68+
docs/
69+
index.md
70+
scripts/
71+
gen_ref_pages.py
72+
src/
73+
project/
74+
mkdocs.yml
75+
```
76+
77+
```python title="scripts/gen_ref_pages.py"
6778
"""Generate the code reference pages."""
6879
6980
from pathlib import Path
7081
7182
import mkdocs_gen_files
7283
73-
for path in sorted(Path("src").rglob("*.py")): # (1)
74-
module_path = path.relative_to("src").with_suffix("") # (2)
75-
doc_path = path.relative_to("src").with_suffix(".md") # (3)
76-
full_doc_path = Path("reference", doc_path) # (4)
84+
src = Path(__file__).parent.parent / "src" # (1)!
85+
86+
for path in sorted(src.rglob("*.py")): # (2)!
87+
module_path = path.relative_to(src).with_suffix("") # (3)!
88+
doc_path = path.relative_to(src).with_suffix(".md") # (4)!
89+
full_doc_path = Path("reference", doc_path) # (5)!
7790
7891
parts = list(module_path.parts)
7992
80-
if parts[-1] == "__init__": # (5)
93+
if parts[-1] == "__init__": # (6)!
8194
parts = parts[:-1]
8295
elif parts[-1] == "__main__":
8396
continue
8497
85-
with mkdocs_gen_files.open(full_doc_path, "w") as fd: # (6)
86-
identifier = ".".join(parts) # (7)
87-
print("::: " + identifier, file=fd) # (8)
98+
with mkdocs_gen_files.open(full_doc_path, "w") as fd: # (7)!
99+
identifier = ".".join(parts) # (8)!
100+
print("::: " + identifier, file=fd) # (9)!
88101
89-
mkdocs_gen_files.set_edit_path(full_doc_path, path) # (9)
102+
mkdocs_gen_files.set_edit_path(full_doc_path, path) # (10)!
90103
```
91104

92-
1. Here we recursively list all `.py` files, but you can adapt the code to list
105+
1. It's important to build a path relative to the script itself,
106+
to make it possible to build the docs with MkDocs'
107+
[`-f` option](https://www.mkdocs.org/user-guide/cli/#mkdocs-build).
108+
2. Here we recursively list all `.py` files, but you can adapt the code to list
93109
files with other extensions of course, supporting other languages than Python.
94-
2. The module path will look like `project/lorem`.
110+
3. The module path will look like `project/lorem`.
95111
It will be used to build the *mkdocstrings* autodoc identifier.
96-
3. This is the relative path to the Markdown page.
97-
4. This is the absolute path to the Markdown page. Here we put all reference pages
98-
into a `reference` folder.
99-
5. This part is only relevant for Python modules. We skip `__main__` modules and
112+
4. This is the partial path of the Markdown page for the module.
113+
5. This is the full path of the Markdown page within the docs.
114+
Here we put all reference pages into a `reference` folder.
115+
6. This part is only relevant for Python modules. We skip `__main__` modules and
100116
remove `__init__` from the module parts as it's implicit during imports.
101-
6. Magic! Add the file to MkDocs pages, without actually writing it in the docs folder.
102-
7. Build the autodoc identifier. Here we document Python modules, so the identifier
117+
7. Magic! Add the file to MkDocs pages, without actually writing it in the docs folder.
118+
8. Build the autodoc identifier. Here we document Python modules, so the identifier
103119
is a dot-separated path, like `project.lorem`.
104-
8. Actually write to the magic file.
105-
9. We can even set the `edit_uri` on the pages.
120+
9. Actually write to the magic file.
121+
10. We can even set the `edit_uri` on the pages.
106122

107123
> NOTE:
108124
> It is important to look out for correct edit page behaviour when using generated pages.
109125
> For example, if we have `edit_uri` set to `blob/master/docs/` and the following
110126
> file structure:
111127
>
112-
> ```
113-
> 📁 repo
114-
> ├─ 📄 mkdocs.yml
115-
> │
116-
> ├─ 📁 docs
117-
> │ ├─╴📄 index.md
118-
> │ └─╴📄 gen_ref_pages.py
119-
> │
120-
> └─╴📁 src
121-
> └─╴📁 project
122-
> ├─╴📄 lorem.py
123-
> ├─╴📄 ipsum.py
124-
> ├─╴📄 dolor.py
125-
> ├─╴📄 sit.py
126-
> └─╴📄 amet.py
128+
> ```tree
129+
> repo/
130+
> mkdocs.yml
131+
> docs/
132+
> index.md
133+
> scripts/
134+
> gen_ref_pages.py
135+
> src/
136+
> project/
137+
> lorem.py
138+
> ipsum.py
139+
> dolor.py
140+
> sit.py
141+
> amet.py
127142
> ```
128143
>
129144
> Then we will have to change our `set_edit_path` call to:
130145
>
131146
> ```python
132-
> mkdocs_gen_files.set_edit_path(full_doc_path, Path("../") / path) # (1)
147+
> mkdocs_gen_files.set_edit_path(full_doc_path, Path("../") / path) # (1)!
133148
> ```
134149
>
135150
> 1. Path can be used to traverse the structure in any way you may need, but
@@ -180,15 +195,15 @@ plugins:
180195
- search
181196
- gen-files:
182197
scripts:
183-
- docs/gen_ref_pages.py
198+
- scripts/gen_ref_pages.py
184199
- literate-nav:
185200
nav_file: SUMMARY.md
186201
- mkdocstrings
187202
```
188203

189204
Then, the previous script is updated like so:
190205

191-
```python title="docs/gen_ref_pages.py" hl_lines="7 21 29 30"
206+
```python title="scripts/gen_ref_pages.py" hl_lines="7 23 31 32"
192207
"""Generate the code reference pages and navigation."""
193208
194209
from pathlib import Path
@@ -197,9 +212,11 @@ import mkdocs_gen_files
197212
198213
nav = mkdocs_gen_files.Nav()
199214
200-
for path in sorted(Path("src").rglob("*.py")):
201-
module_path = path.relative_to("src").with_suffix("")
202-
doc_path = path.relative_to("src").with_suffix(".md")
215+
src = Path(__file__).parent.parent / "src"
216+
217+
for path in sorted(src.rglob("*.py")):
218+
module_path = path.relative_to(src).with_suffix("")
219+
doc_path = path.relative_to(src).with_suffix(".md")
203220
full_doc_path = Path("reference", doc_path)
204221
205222
parts = tuple(module_path.parts)
@@ -209,16 +226,16 @@ for path in sorted(Path("src").rglob("*.py")):
209226
elif parts[-1] == "__main__":
210227
continue
211228
212-
nav[parts] = doc_path.as_posix() # (1)
229+
nav[parts] = doc_path.as_posix() # (1)!
213230
214231
with mkdocs_gen_files.open(full_doc_path, "w") as fd:
215232
ident = ".".join(parts)
216233
fd.write(f"::: {ident}")
217234
218235
mkdocs_gen_files.set_edit_path(full_doc_path, path)
219236
220-
with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file: # (2)
221-
nav_file.writelines(nav.build_literate_nav()) # (3)
237+
with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file: # (2)!
238+
nav_file.writelines(nav.build_literate_nav()) # (3)!
222239
```
223240

224241
1. Progressively build the navigation object.
@@ -232,7 +249,7 @@ and replace it with a single line!
232249
nav:
233250
# rest of the navigation...
234251
# defer to gen-files + literate-nav
235-
- Code Reference: reference/ # (1)
252+
- Code Reference: reference/ # (1)!
236253
# rest of the navigation...
237254
```
238255

@@ -259,7 +276,7 @@ Well, this is possible thanks to a third plugin:
259276

260277
Update the script like this:
261278

262-
```python title="docs/gen_ref_pages.py" hl_lines="18 19"
279+
```python title="scripts/gen_ref_pages.py" hl_lines="20 21"
263280
"""Generate the code reference pages and navigation."""
264281
265282
from pathlib import Path
@@ -268,9 +285,11 @@ import mkdocs_gen_files
268285
269286
nav = mkdocs_gen_files.Nav()
270287
271-
for path in sorted(Path("src").rglob("*.py")):
272-
module_path = path.relative_to("src").with_suffix("")
273-
doc_path = path.relative_to("src").with_suffix(".md")
288+
src = Path(__file__).parent.parent / "src"
289+
290+
for path in sorted(src.rglob("*.py")):
291+
module_path = path.relative_to(src).with_suffix("")
292+
doc_path = path.relative_to(src).with_suffix(".md")
274293
full_doc_path = Path("reference", doc_path)
275294
276295
parts = tuple(module_path.parts)
@@ -301,7 +320,7 @@ plugins:
301320
- search
302321
- gen-files:
303322
scripts:
304-
- docs/gen_ref_pages.py
323+
- scripts/gen_ref_pages.py
305324
- literate-nav:
306325
nav_file: SUMMARY.md
307326
- section-index

0 commit comments

Comments
 (0)