A Markdown toolchain for literate programming and to make your documents executable.
Table of Contents
See the examples file to learn how to configure various evaluators to
- 🖼 generate graphs,
- 🌍 do HTTP requests,
- 🤖 and run scripts.
We'll 'execute' the code block in test.txt that shells out to date (around line 7, with 1-based counting), using the config.json that instructs md-babel how to interpret sh code blocks.
Clone the repository;
$ git clone https://github.com/md-babel/swift-markdown-babel.git
$ cd swift-markdown-babel
-
From source: Use
swift runto compile from source and then use the program.[!NOTE]
Why2>/dev/null? Because 'quiet' Swift still produces output, but routes it to standard error.swift run --quiet md-babel exec --file test.txt --line 7 --column 1 --config config.json 2>/dev/null
-
From pre-built binary: Download a tagged release, then run
md-babeldirectly (without the "swift run --quiet" part)../md-babel exec --file test.txt --line 7 --column 1 --config config.json
The result will contain metadata that specifies the affected range in the document, but the interesting part is this:
{
...,
"replacementString" : "```sh\ndate\n```\n\n<!--Result:-->\n```\nFri Apr 11 13:00:28 CEST 2025```",
"result" : "Fri Apr 11 13:00:28 CEST 2025"
}-
Editor applications can use
"replacementString"to modify the document directly, turning Markdown documents into executable notebooks.Check out the md-babel GitHub organization's repositories to see whether your favorite editor has an integration!
-
Other applications can use the plain output from
"result".
The md-babel program implements the schema so that you can run your code from the command-line (very cumbersome) or an editor plugin (very convenient).
In any case, all calls are routed through md-babel as your executable Markdown hub.
Usage: md-babel execute [--file <file>] [--filename <filename>] --line <line> --column <column> [--dir </path/to/project>] [--config <config>] [--no-load-user-config]
-
Grab the the code block from
<file>(or standard input) at/around<line>:<column>(starting at 1, not 0, to meet CommonMark standards), -
execute it in its context,
-
and produce a md-babel:execute-block:response-formatted JSON to stdandard output.
Client editors can then process the resulting JSON response to insert the result of the code block. See for a reference implementation in Emacs or the Visual Studio Code plugin.
Other options:
-
The
--filenameargument can be used (by editors) to enforce either provide a filename even though standard input is used, or to shadow the filename part from<file>. Shadowing can be useful to strip filenames from date-time strings or other metadata first, and extract the human-readable part. Image generators use this in their output file name patterns. -
The
--no-load-user-configflag determines whether the global configuration file should be used. If you toggle this but then don't pass a--configfile path to use instead, no code block evaluators will be known. -
The optional
--configargument loads a configuration file that is merged with the user's global configuration by default. If you combine this with--no-load-user-config, only the config file you pass here will be used. -
The optional
--dircan be used to resolve relative build product paths from code blocks, including images. Editors set this to the project or workspace directory to put assets in a common folder. The default (unset) uses temporary directories.The effective evaluator configuration should not use absolute output
"directory"keys for relative paths to work. Leaving the"directory"key out completely will put images in the project root; using relative directives like"directory": "./assets"will put them in a shared subdirectory. -
The
--no-relative-pathsflag forces e.g. image literals to always use absolute paths. By default, relative paths will be preferred. Relative paths are based on the--dirargument, if present, falling back to the dirname of--file, if present. Without both, paths are resolved against the default temporary directory.
Examples for image output and the literal inserted into your document:
-
Given arguments : --file /home/you/test.md and evaluator directory : "./assets" Then creates image at path : /tmp/assets/image.png and literal output :  -
Given arguments : --file /home/you/test.md --dir /home/you and evaluator directory : "./assets" Then creates image at path : /home/you/assets/image.png and literal output :  -
Given arguments : --file /home/you/test.md --dir /home/you --no-relative-paths and evaluator directory : "./assets" Then creates image at path : /home/you/assets/image.png and literal output : 
Usage: md-babel config dump [--no-load-user-config] [--config <config>]
Pretty-prints the JSON configuration as found in your global configuration file, merged with <config> (if you pass that).
- Location:
~/.config/md-babel/config.json - Precedence: Loaded first. Skip with
--no-load-user-config.
Pass overrides to md-babel execute with the --config option.
Client applications can define their own block handlers this way.
The configuration file consists of key--object pairs.
The key is the code block language, and the object contains an absolute "path" to the program to run.
You can pass "defaultArguments" to influence how the program is executed.
See the md-babel:config schema for details.
Here's a simple example for shell scripts and Python:
{
"evaluators": {
"codeBlock" : {
"sh": {
"path": "/usr/bin/env",
"defaultArguments": ["sh"]
},
"bash": {
"path": "/usr/bin/env",
"defaultArguments": ["bash"]
},
"python": {
"path": "/usr/bin/env",
"defaultArguments": ["python3"]
}
}
}
}If you can rely on /usr/bin/env, like with hash-bangs, you can set and forget it.
(With pyenv, rbenv, asdf, ... your mileage may vary!)
See the examples file to learn how to configure various evaluators.
Usage: md-babel select [--file <file>] --line <line> --column <column>
From <file>, with the point at <line>:<column> (starting at 1, not 0, to meet CommonMark standards), produces a md-babel:select-block:response-formatted JSON to stdandard output.
Client editors can process this to inspect md-babel components.