#mdbook #run-command #preprocessor #command-output #ocirun

bin+lib mdbook-ocirun

mdbook preprocessor to run arbitrary commands and code snippets inside containers

3 unstable releases

0.2.1 Jun 25, 2024
0.2.0 Oct 7, 2023
0.1.0 Oct 4, 2023

#351 in Text processing

MIT license

36KB
761 lines

Workflow Status Crates.io crates.io

mdbook-ocirun

This is a preprocessor for the rust-lang mdbook project. This allows to run arbitrary commands and code snippets inside containers and include the output of them within the markdown file.

Getting started

cargo install mdbook-ocirun

You also have to activate the preprocessor, put this in your book.toml file:

[preprocessor.ocirun]

Running arbitrary commands

Let's say we have these two files:

Markdown file: file.md

# Title

<!-- ocirun alpine seq 1 10 -->

<!-- ocirun python python script.py -->

Python file: script.py

def main():
    print("## Generated subtitle")
    print("  This comes from the script.py file")
    print("  Since I'm in a scripting language,")
    print("  I can compute whatever I want")

if __name__ == "__main__":
    main()

The preprocessor will call seq then python3, and will produce the resulting file:

# Title

1
2
3
4
5
6
7
8
9
10

## Generated subtitle
  This comes from the script.py file
  Since I'm in a scripting language,
  I can compute whatever I want


Details

When the pattern <!-- ocirun <image> $1 -->\n or <!-- ocirun <image> $1 --> is encountered, the command $1 will be run using the container like this: docker run <image> $1. Also the working directory is the directory where the pattern was found (not root). The command invoked must take no inputs (stdin is not used), but a list of command lines arguments and must produce output in stdout, stderr is ignored.

Examples

The following is valid:


<!-- ocirun python python generate_table.py -->

```rust
<!-- ocirun alpine cat program.rs -->
```

```diff
<!-- ocirun alpine diff a.rs b.rs -->
```

```console
<!-- ocirun alpine ls -l . -->
```

## Example of inline use inside a table

````markdown
Item | Price | # In stock
---|---|---
Juicy Apples | <!-- ocirun node node price.mjs apples --> | *<!-- ocirun node node quantity.mjs apples  -->*
Bananas | *<!-- ocirun node node price.mjs bananas -->* | <!-- ocirun node node quantity.mjs bananas -->

Which gets rendered as:

Item | Price | # In stock
---|---|---
Juicy Apples | 1.99 | *7*
Bananas | *1.89* | 5234

Some more examples are implemented, and are used as regression tests. You can find them here. At the moment of writing, there are examples using:

  • Shell
  • Bash script
  • Batch script
  • Python3
  • Node
  • Rust

Running Code Snippets

First you have to config how to run your snippets, here one example for python:

[[preprocessor.ocirun.langs]]
name = "python"
image = "python"
command = ["python", "source"]

So when we found a snippet like:

```python,ocirun
print('Hello World')
```

We will append the output:

```console,success
Hello World
```

The final result should be something like this:

print('Hello World')
Hello World

Contributors

I would like to thank @FauconFan for his work on mdbook-cmdrun that was my start for this project.

Current version: 0.2.0
License: MIT

Dependencies

~12–23MB
~339K SLoC