diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index ab7b895..017b97e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -41,7 +41,7 @@ jobs: python-version: "3.x" - name: Install dependencies - run: pip install zensical + run: pip install zensical markdown-exec - name: Build documentation run: zensical build --strict diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0150b68..185e40d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -40,7 +40,7 @@ jobs: python-version: "3.x" - name: Install dependencies - run: pip install zensical + run: pip install zensical markdown-exec - name: Build documentation run: zensical build --clean --strict diff --git a/docs/setup/extensions/markdown-exec.md b/docs/setup/extensions/markdown-exec.md new file mode 100644 index 0000000..9652d58 --- /dev/null +++ b/docs/setup/extensions/markdown-exec.md @@ -0,0 +1,125 @@ +--- +icon: lucide/cog +tags: + - Extensions +status: new +--- + +# Markdown Exec + +[Markdown Exec] executes code blocks in your Markdown files at build time and renders their output in place of the code, instead of just displaying it. It supports Python, shell (`bash`, `sh`, `console`), Pyodide, and directory trees (`tree`), and can render results as Markdown or raw HTML. + +[Markdown Exec]: https://pawamoy.github.io/markdown-exec/ + +!!! warning "Executes arbitrary code at build time" + + Markdown Exec runs the code in your fenced code blocks when the site is + built. Only enable it for content you trust, and treat it the same way you + would treat any other build script with access to your project. + +## Installation + +Markdown Exec is not included with Zensical by default, so it needs to be installed separately. + +=== "with `pip`" + + ```sh + pip install "markdown-exec[ansi]" + ``` + +=== "with `uv`" + + ```sh + uv add "markdown-exec[ansi]" + ``` + +The `ansi` extra adds the pieces needed to render ANSI colors in HTML code blocks, which is useful for shell output. + +## Configuration + +Markdown Exec relies on the [SuperFences] extension, which is [enabled by default] in Zensical. Configure Markdown Exec as a plugin: + +[SuperFences]: python-markdown-extensions.md#superfences +[enabled by default]: about.md#default-configuration + + +=== "`zensical.toml`" + + ```toml + [project.plugins.markdown-exec] + ``` + +=== "`mkdocs.yml`" + + ```yaml + plugins: + - markdown-exec + ``` + +Enabling it via the plugin, rather than by hand-listing custom fences under `pymdownx.superfences`, is the recommended path: it registers a fence for every supported language and takes care of adding any extra CSS or JS assets a fence needs, such as the ANSI stylesheet. + +## Usage + +Add the `exec="on"` option to a fenced code block to run it and render its output instead of the source: + +````markdown +```python exec="on" +print("Hello Markdown!") +``` +```` + +The `exec` option is true for any value except `0`, `no`, `off`, and `false` (case insensitive). To run every code block of a given language without adding `exec="on"` to each one, set the `MARKDOWN_EXEC_AUTO` environment variable before building the site: + +```sh +MARKDOWN_EXEC_AUTO=python,bash +``` + +By default, printed output is treated as Markdown and rendered accordingly. Set `html="on"` if the code already produces HTML that should be injected as is. + +### Showing the source alongside the result + +To render both the code and its output, add the `source` option: + +````markdown +```python exec="on" source="above" +print("I'm the result!") +``` +```` + +Accepted values are `above`, `below`, `tabbed-left`, `tabbed-right`, `block`, and `console`. The tabbed and block styles depend on the [Tabbed] and [Markdown in HTML] extensions, both of which are on by default in Zensical. + +[Tabbed]: python-markdown-extensions.md#tabbed +[Markdown in HTML]: python-markdown.md#markdown-in-html + +### Interactive code blocks + +Markdown Exec can generate interactive Python code blocks that can be edited and executed by the readers of your documentation. These code blocks are not executed at build time: they run on your reader's devices, client-side. The editing capabilities are provided thanks to the [Ace] editor. The Python code runs on the client device thanks to [Pyodide]. + +[Ace]: https://ace.c9.io/ +[Pyodide]: https://pyodide.org/en/stable/ + +To create such interactive Python code blocks, create `pyodide` fences: + +````md +```pyodide +print("Hello world!") +``` +```` + +This example will generate the following interactive code block. Try editing the code, then running it with ++ctrl+enter++ or by clicking "Run" in the top-right corner. + +```pyodide +print("Hello world!") +``` + +The first time a code block is executed on a just-loaded page, Pyodide is initialized, taking some time; next executions are faster. + +### Further options + +Markdown Exec has additional options for naming and prefixing generated HTML ids, persisting state between blocks with `session`, changing the console width or working directory, and more. The full list, with examples, is in the upstream documentation: + +- [Options summary](https://pawamoy.github.io/markdown-exec/usage/#options-summary) +- [Pyodide usage](https://pawamoy.github.io/markdown-exec/usage/pyodide/) +- [Python usage](https://pawamoy.github.io/markdown-exec/usage/python/) +- [Shell usage](https://pawamoy.github.io/markdown-exec/usage/shell/) +- [Gallery of examples](https://pawamoy.github.io/markdown-exec/gallery/) diff --git a/mkdocs.yml b/mkdocs.yml index a0fea44..9743493 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -86,6 +86,7 @@ extra_css: plugins: - search - tags + - markdown-exec # Additional configuration extra: @@ -208,6 +209,7 @@ nav: - About extensions: setup/extensions/about.md - GLightbox: setup/extensions/glightbox.md - Macros: setup/extensions/macros.md + - Markdown Exec: setup/extensions/markdown-exec.md - mkdocstrings: setup/extensions/mkdocstrings.md - Python Markdown: setup/extensions/python-markdown.md - Python Markdown Extensions: setup/extensions/python-markdown-extensions.md