https://github.com/gbbirkisson/mkdocs-fun-plugin
Dead simple custom python functions with mkdocs
https://github.com/gbbirkisson/mkdocs-fun-plugin
Last synced: about 1 year ago
JSON representation
Dead simple custom python functions with mkdocs
- Host: GitHub
- URL: https://github.com/gbbirkisson/mkdocs-fun-plugin
- Owner: gbbirkisson
- Created: 2025-04-24T11:55:44.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-05T07:02:11.000Z (about 1 year ago)
- Last Synced: 2025-05-05T08:22:08.551Z (about 1 year ago)
- Language: Python
- Homepage: https://pypi.org/project/mkdocs-fun-plugin
- Size: 66.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
Dead simple custom python functions with mkdocs
* [Usage 📖](#usage-)
* [Configuration 🎛](#configuration-)
* [Examples 💡](#examples-)
* [References and links](#references-and-links)
* [Shell](#shell)
* [File contents](#file-contents)
## Usage 📖
Install the plugin in your project ...
```bash
pip install mkdocs-fun-plugin
```
... and add it to your `mkdocs.yaml` configuration ...
```yaml
# mkdocs.yaml
plugins:
- fun
```
... create a `docs/fun.py` file ...
```python
# docs/fun.py
def hello() -> str:
return "world"
```
... and start using your functions in your docs ...
```markdown
This #!hello() comes from my function!
```
... becomes ...
```markdown
This world comes from my function!
```
## Configuration 🎛
You can customize the plugin behaviour with configuration:
```yaml
# mkdocs.yaml
plugins:
- fun:
pattern: "#!(?P[^\(]+)\((?P[^\)]*)\)" # Regex to match functions
module: fun.py # Python file that defines your functions
```
## Examples 💡
### References and links
```python
# docs/fun.py
def ref(key: str) -> str:
"""
Bookkeeping and standardized format of references in the docs
"""
r = {
"mcguffin": ("McGuffin", "/refs/mcguffin.md"),
}.get(key)
assert r, f"No ref for '{key}' found"
return f"[`{r[0]}`]({r[1]})"
def link(key: str) -> str:
"""
Bookkeeping and standardized format of external links in the docs
"""
l = {
"github": (":fontawesome-brands-github: Github", "https://www.github.com"),
}.get(key)
assert l, f"No link for '{key}' found"
return f'[{l[0]}]({l[1]}){{:target="_blank"}}'
```
```markdown
Look at our internal #!ref(mcguffin) docs for more info. Also open up #!link(github).
```
... becomes ...
```markdown
Look at our internal [`McGuffin`](/refs/mcguffin.md) docs for more info. Also open up [:fontawesome-brands-github: Github](https://www.github.com){:target="_blank"}.
```
### Shell
```python
# docs/fun.py
@functools.cache
def shell(cmd: str) -> str:
"""
Run arbitrary commands and return stdout
"""
return (
subprocess.run(
cmd,
shell=True,
check=True,
capture_output=True,
)
.stdout.decode()
.strip()
)
```
```markdown
#!shell("echo hello | cowsay")
```
... becomes ...
```markdown
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
```
### File contents
```python
# docs/fun.py
def func_def(file: str, name: str) -> str:
"""
Reads 'file' and returns the definition of function 'name'
"""
with (pathlib.Path(__file__).parent / file).open() as f:
content = f.read()
# Find function definition including decorators
pattern = rf"(@.*\n)*def {name}\s*\([^)]*\)[^:]*:"
match = re.search(pattern, content, re.MULTILINE)
assert match, f"Function '{name}' not found in '{file}'"
# Find where function starts and ends
start_pos = match.start()
lines = content.splitlines()
start_line = content[:start_pos].count("\n")
# Find function body by tracking indentation
function_lines = [lines[start_line]]
indent = (
re.match(r"(\s*)", lines[start_line + 1]).group(1)
if start_line + 1 < len(lines)
else ""
)
# Collect and return
for i in range(start_line + 1, len(lines)):
line = lines[i]
if line.strip() and not line.startswith(indent):
break
function_lines.append(line)
return "\n".join(function_lines).strip()
```
```markdown
#!func_def(fun.py, hello)
```
... becomes ...
```markdown
def hello() -> str:
return "world"
```