Skip to content

Commit 6bd9e91

Browse files
committed
fix: generate dynamic reference docs
1 parent 8b46941 commit 6bd9e91

File tree

5 files changed

+113
-35
lines changed

5 files changed

+113
-35
lines changed

.github/workflows/pages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
- name: Build documentation
3838
run: |
3939
source .venv/bin/activate
40-
mkdocs build
40+
python ./docs/gen_docs.py
4141
- name: Setup Pages
4242
uses: actions/configure-pages@v3
4343
- name: Upload artifact

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ venv.bak/
137137

138138
# mkdocs documentation
139139
site/
140+
docs/reference/
140141

141142
# mypy
142143
.mypy_cache/

docs/gen_docs.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"""Generate docs."""
2+
3+
# standard
4+
from yaml import safe_load, safe_dump
5+
from ast import parse, ImportFrom
6+
from shutil import copy, move, rmtree
7+
from typing import Dict, List
8+
from os.path import getsize
9+
from subprocess import run
10+
from pathlib import Path
11+
12+
13+
def _write_ref_content(source: Path, module_name: str, func_name: str):
14+
"""Write content."""
15+
with open(source, "at") as ref:
16+
ref.write(
17+
(f"# {module_name}\n\n" if getsize(source) == 0 else "")
18+
+ f"::: validators.{module_name}.{func_name}\n"
19+
)
20+
21+
22+
def generate_reference(source: Path, destination: Path):
23+
"""Generate reference."""
24+
nav_items: Dict[str, List[str]] = {"Code Reference": []}
25+
# clean destination
26+
if destination.exists() and destination.is_dir():
27+
rmtree(destination)
28+
destination.mkdir(exist_ok=True)
29+
# parse source
30+
v_ast = parse(source.read_text(), source)
31+
# generate reference content
32+
for namespace in (node for node in v_ast.body if isinstance(node, ImportFrom)):
33+
if not namespace.module:
34+
continue
35+
for alias in namespace.names:
36+
ref_module = destination / f"{namespace.module}.md"
37+
_write_ref_content(ref_module, namespace.module, alias.name)
38+
nav_items["Code Reference"].append(f"reference/{namespace.module}.md")
39+
return nav_items
40+
41+
42+
def update_mkdocs_config(source: Path, destination: Path):
43+
"""Temporary update to mkdocs config."""
44+
copy(source, destination)
45+
with open(source, "rt") as mkf:
46+
mkdocs_conf = safe_load(mkf)
47+
mkdocs_conf["nav"] += [nav_items]
48+
with open(source, "wt") as mkf:
49+
safe_dump(mkdocs_conf, mkf, sort_keys=False)
50+
51+
52+
if __name__ == "__main__":
53+
project_dir = Path(__file__).parent.parent
54+
# copy readme as docs index file
55+
copy(project_dir / "README.md", project_dir / "docs/index.md")
56+
nav_items = generate_reference(
57+
project_dir / "validators/__init__.py", project_dir / "docs/reference"
58+
)
59+
# copy mkdocs config
60+
update_mkdocs_config(project_dir / "mkdocs.yml", project_dir / "mkdocs.bak.yml")
61+
print(run(("mkdocs", "build"), capture_output=True).stderr.decode())
62+
# copy back mkdocs config
63+
move(project_dir / "mkdocs.bak.yml", project_dir / "mkdocs.yml")

docs/index.md

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
# Reference
2-
3-
::: validators.between
4-
5-
::: validators.btc_address
6-
7-
::: validators.card
8-
9-
::: validators.domain
10-
11-
::: validators.email
12-
13-
::: validators.hashes
14-
15-
::: validators.hostname
16-
17-
::: validators.iban
18-
19-
::: validators.ip_address
20-
21-
::: validators.length
22-
23-
::: validators.mac_address
24-
25-
::: validators.slug
26-
27-
::: validators.url
28-
29-
::: validators.uuid
30-
31-
---
32-
33-
::: validators.utils
1+
# validators - Python Data Validation for Humans™
2+
3+
[![Tests][tests-badge]][tests-link] [![Bandit][bandit-badge]][bandit-link] [![Version Status][vs-badge]][vs-link] [![Downloads][dw-badge]][dw-link]
4+
5+
Python has all kinds of data validation tools, but every one of them seems to
6+
require defining a schema or form. I wanted to create a simple validation
7+
library where validating a simple value does not require defining a form or a
8+
schema.
9+
10+
```python
11+
>>> import validators
12+
13+
>>> validators.email('[email protected]')
14+
True
15+
```
16+
17+
## Resources
18+
19+
- [Documentation](https://python-validators.github.io/)
20+
- [Issue Tracker](https://github.com/python-validators/validators/issues)
21+
- [Security](https://github.com/python-validators/validators/blob/master/SECURITY.md)
22+
- [Code](https://github.com/python-validators/validators/)
23+
24+
[//]: #(Links)
25+
26+
[bandit-badge]: https://github.com/python-validators/validators/actions/workflows/bandit.yml/badge.svg
27+
[bandit-link]: https://github.com/python-validators/validators/actions/workflows/bandit.yml
28+
[tests-badge]: https://github.com/python-validators/validators/actions/workflows/main.yml/badge.svg
29+
[tests-link]: https://github.com/python-validators/validators/actions/workflows/main.yml
30+
[vs-badge]: https://img.shields.io/pypi/v/validators.svg
31+
[vs-link]: https://pypi.python.org/pypi/validators/
32+
[dw-badge]: https://img.shields.io/pypi/dm/validators.svg
33+
[dw-link]: https://pypi.python.org/pypi/validators/

mkdocs.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,24 @@ watch: [README.md, validators/]
99

1010
nav:
1111
- Home: index.md
12-
- Code Reference: reference/
1312

1413
theme:
1514
name: material
15+
palette:
16+
- media: "(prefers-color-scheme: light)"
17+
scheme: default
18+
primary: white
19+
accent: teal
20+
toggle:
21+
icon: material/toggle-switch
22+
name: Switch to dark mode
23+
- media: "(prefers-color-scheme: dark)"
24+
scheme: slate
25+
primary: black
26+
accent: teal
27+
toggle:
28+
icon: material/toggle-switch-off-outline
29+
name: Switch to light mode
1630

1731
plugins:
1832
- search

0 commit comments

Comments
 (0)