Skip to main content

Dead simple custom python functions with mkdocs

Project description

Logo
mkdocs-fun-plugin

Dead simple custom python functions with mkdocs

Usage 📖

Install the plugin in your project ...

pip install mkdocs-fun-plugin

... and add it to your mkdocs.yaml configuration ...

# mkdocs.yaml
plugins:
  - fun

... create a docs/fun.py file ...

# docs/fun.py
def hello() -> str:
    return "world"

... and start using your functions in your docs ...

<!-- docs/docs.md -->
This #!hello() comes from my function!

... becomes ...

This world comes from my function!

Configuration 🎛

You can customize the plugin behaviour with configuration:

# mkdocs.yaml
plugins:
  - fun:
      pattern: "#!(?P<func>[^\(]+)\((?P<params>[^\)]*)\)"  # Regex to match functions
      module: fun.py  # Python file that defines your functions
      disable_pattern: "<!--\s*fun:disable\s*-->"
      enable_pattern: "<!--\s*fun:enable\s*-->"

Examples 💡

References and links

# 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"}}'
<!-- docs/docs.md -->
Look at our internal #!ref(mcguffin) docs for more info. Also open up #!link(github).

... becomes ...

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

# 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()
    )
<!-- docs/docs.md -->
#!shell("echo hello | cowsay")

... becomes ...

_______
< hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

File contents

# 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()
<!-- docs/docs.md -->
#!func_def(fun.py, hello)

... becomes ...

def hello() -> str:
    return "world"

Disable plugin for a section

<!-- docs/docs.md -->
#!shell("echo hello | cowsay")
<!-- fun:disable -->
#!shell("echo there | cowsay")
<!-- fun:enable -->
#!shell("echo friend | cowsay")

... becomes ...

_______
< hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
<!-- fun:disable -->
#!shell("echo there | cowsay")
<!-- fun:enable -->
________
< friend >
 --------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mkdocs_fun_plugin-0.2.0.tar.gz (47.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mkdocs_fun_plugin-0.2.0-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file mkdocs_fun_plugin-0.2.0.tar.gz.

File metadata

  • Download URL: mkdocs_fun_plugin-0.2.0.tar.gz
  • Upload date:
  • Size: 47.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.18

File hashes

Hashes for mkdocs_fun_plugin-0.2.0.tar.gz
Algorithm Hash digest
SHA256 909c423003b34f3f31313631e4afc9dca452699a3575d54ad3a76261ed315dc7
MD5 3d914cfc9dd1322f3d75d8d9bf3b1ef5
BLAKE2b-256 2bf644aa1a6ca822fb8fc4d4c91ab85d735759d815c144581fa7132b079df9ce

See more details on using hashes here.

File details

Details for the file mkdocs_fun_plugin-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mkdocs_fun_plugin-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c64d469e51df3887633b478fc5011f48be8415cb7d9f6db8e83815c27452b415
MD5 25457aacf05fdd0339d92b6f8b3c0123
BLAKE2b-256 849836ec59d7047873ba00f59921b3b342635de18855b054c7d3757b0d0b11b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page