Dinject is a Python package and CLI tool for executing code blocks in Markdown documents then injecting the results.
This example creates a Markdown document with a code block and an injection site, then performs the injection:
from dinject import inject
from io import StringIO
markdown = """This is a demonstration of Dinject.
```bash
python --version
```
<!--dinject-->
"""
writer = StringIO()
inject(markdown, writer)
print(writer.getvalue())
In the output, the injection site has been replaced by the execution result:
This is a demonstration of Dinject.
```bash
python --version
```
<!--dinject as=markdown fence=backticks host=shell range=start-->
```text
Python 3.10.0
```
<!--dinject range=end-->
Fun fact! The documentation you're reading right now was generated by Edition which uses Dinject under the hood. The example output above was generated and injected by Dinject executing the code block preceding it.
Dinject requires Python 3.8 or later.
Install Dinject via pip:
pip install dinject
The most basic injection site is simply:
<!--dinject-->
To fence the injection with tildes instead of backticks (for example, if you're embedding Markdown within Markdown) then set the fence
attribute:
<!--dinject fence=tildes-->
To inject the result as HTML instead of Markdown (for example, to render the colours and other styles in the command's output) then set the as
attribute:
<!--dinject as=html-->
To have the code executed in a pseudo terminal rather than a sub shell (for example, if the command emits formatted output only in non-interactive shells) then set the host
attribute:
<!--dinject host=terminal-->
Run dinject
and pass paths to Markdown documents to update:
dinject README.md docs/example.md
The inject()
function takes:
- A reader, which can be a text stream or a string.
- A text stream writer.
- An optional parser.
A customised Parser
can be passed into inject()
to tweak some runtime configuration.
The keyword
describes the injection site keyword. This is "dinject" by default. If you wanted to injection sites to be marked up by, say, <!--foo-->
then set the keyword to "foo".
Dinject executes Bash code blocks via /usr/bin/env bash -c CODE
.
This will require a Linux-like operating system or operating system layer.
Dinject executes Bash code blocks via python -c CODE
.
The first Python interpreter available in your path will be used; this includes your virtual environment if you're in one. Dinject will rely on that interpreter/virtual environment to perform the imports.
Text blocks will be passed-through unchanged.
To contribute a bug report, enhancement or feature request, please raise an issue at github.com/cariad/dinject/issues.
If you want to contribute a code change, please raise an issue first so we can chat about the direction you want to take.
Dinject is released at github.com/cariad/dinject under the MIT Licence.
See LICENSE for more information.
Hello! 👋 I'm Cariad Eccleston and I'm a freelance DevOps and backend engineer. My contact details are available on my personal wiki at cariad.earth.
Please consider supporting my open source projects by sponsoring me on GitHub.
- Epic ❤️ to John Gruber for developing the original Markdown specification.
- Markdown parsing by Comprehemd.
- Pseudo terminal support by NaughTTY.
- HTML conversion of command output by thtml.
- This documentation was pressed by Edition.