- Executing Code
- Supported Directive parameters
- Examples
- Output block management
- Multiple execution Behaviour
- Troubleshooting
The code subcommand allows you to execute code blocks in markdown
files and automatically capture their output. This is useful for creating
executable documentation, tutorials, or notebooks.
Basic usage:
md code < document.mdHow it works:
- Code blocks with
md-codedirectives are executed automatically - Output is automatically captured and inserted into the document
- Regular code blocks without directives are left untouched
- All content is preserved exactly as-is
Basic directive syntax:
Code blocks are marked with HTML comments using the <!-- md-code: --> marker immediately after the code fence.
```python
print("Hello, world!")
```
<!-- md-code: id="hello"; bin="python3" -->Important notes:
- Each code block must have a unique
id - The
binparameter is required - it specifies what command to run - Regular code blocks without
md-codedirectives are completely ignored - Both stdout and stderr are captured in the output
- The tool is idempotent - running it multiple times updates the same output blocks assuming code is deterministic
- Use
fenceparameter to customize the fence style of output blocks - Use
syntaxparameter to add syntax highlighting to output blocks
id="unique-id"(required) - Unique identifier for the code blockbin="command"(required) - The command to run (e.g.,"python3","node","bash")timeout=N(optional) - Timeout in seconds (default: 30)fence="..."(optional) - Custom fence for output block (e.g.,"~~~","````") - defaults to input block's fencesyntax="..."(optional) - Syntax highlighting language for output block (e.g.,"json","text") - defaults to no syntax
Input:
```python
x = 10
y = 20
print(f"The sum is {x + y}")
```
<!-- md-code: id="sum"; bin="python3" -->Output:
```python
x = 10
y = 20
print(f"The sum is {x + y}")
```
<!-- md-code: id="sum"; bin="python3" -->
Output:
```
The sum is 30
```
<!-- md-code-output: id="sum" -->```python
import time
time.sleep(2)
print("Done!")
```
<!-- md-code: id="slow"; bin="python3"; timeout=1 -->Output:
Error: Code execution timed out after 1 seconds
```bash
echo "hello world"
```
<!-- md-code: id="bash-hello"; bin="bash" -->Output:
```bash
echo "hello world"
```
<!-- md-code: id="bash-hello"; bin="bash" -->
Output:
```
hello world
```
<!-- md-code-output: id="bash-hello" -->```python
print("unbuffered output")
```
<!-- md-code: id="unbuf"; bin="python3 -u" -->Output:
```python
print("unbuffered output")
```
<!-- md-code: id="unbuf"; bin="python3 -u" -->
Output:
```
unbuffered output
```
<!-- md-code-output: id="unbuf" -->```python
print("Using tildes for output")
```
<!-- md-code: id="custom"; bin="python3"; fence="~~~~" -->Output:
```python
print("Using tildes for output")
```
<!-- md-code: id="custom"; bin="python3"; fence="~~~~" -->
Output:Using tildes for output
<!-- md-code-output: id="custom" -->
~~~
<!-- md-code-output: id="custom-fence" -->
### Custom syntax highlighting
~~~markdown
```python
import json
print(json.dumps({"status": "success", "value": 42}))
```
<!-- md-code: id="json"; bin="python3"; syntax="json" -->
~~~
<!-- md-code: id="custom-syntax"; bin="md code"; syntax="markdown" -->
Output:
~~~markdown
```python
import json
print(json.dumps({"status": "success", "value": 42}))
```
<!-- md-code: id="json"; bin="python3"; syntax="json" -->
Output:
```json
{"status": "success", "value": 42}
```
<!-- md-code-output: id="json" -->
~~~
<!-- md-code-output: id="custom-syntax" -->
## Output block management
- Output blocks are automatically created after code blocks when they produce output
- If you run the command again, existing output blocks are updated
- Empty output (no stdout/stderr) does not create an output block
- Output blocks are marked with `<!-- md-code-output: id="..." -->` for tracking
## Multiple execution Behaviour
You can have multiple code blocks in the same document, each with unique IDs:
~~~markdown
```python
print("First block")
```
<!-- md-code: id="first"; bin="python3" -->
```python
print("Second block")
```
<!-- md-code: id="second"; bin="python3" -->
~~~
<!-- md-code: id="multi-code-blocks"; bin="md code"; syntax="markdown" -->
Output:
~~~markdown
```python
print("First block")
```
<!-- md-code: id="first"; bin="python3" -->
Output:
```
First block
```
<!-- md-code-output: id="first" -->
```python
print("Second block")
```
<!-- md-code: id="second"; bin="python3" -->
Output:
```
Second block
```
<!-- md-code-output: id="second" -->
~~~
<!-- md-code-output: id="multi-code-blocks" -->
## Troubleshooting
### Code blocks not executing
Make sure your code block directive includes all required fields:
1. **Unique `id` attribute** - Each code block must have a distinct ID
2. **`bin` attribute** - Specifies the interpreter/command to run
3. **Directive placement** - The comment must immediately follow the code fence
**Correct example:**
~~~markdown
```python
print("hello")
```
<!-- md-code: id="hello"; bin="python3" -->
~~~
**Common mistakes:**
~~~markdown
# Missing bin attribute
<!-- md-code: id="hello" -->
# Missing id attribute
<!-- md-code: bin="python3" -->
# Directive not immediately after code block
```python
print("hello")
```
Some text here
<!-- md-code: id="hello"; bin="python3" -->
~~~
### Timeout errors
If your code takes too long to execute, you'll see:
```
Error: Code execution timed out after 30 seconds
```
**Solutions:**
- Add a custom timeout: `<!-- md-code: id="slow"; bin="python3"; timeout=60 -->`
- Default timeout is 30 seconds
- Maximum timeout is configurable in your code
### Command not found
If you see errors like `sh: python3: not found`, the interpreter isn't in your PATH.
**Solutions:**
- Use full path to interpreter: `bin="/usr/bin/python3"`
- Verify the command exists: `which python3`
- Check your shell environment
### Output not updating
If running `md code` doesn't update your output:
**Check that:**
1. You're actually running the command: `cat file.md | md code > output.md`
2. The code block has changed since last run
3. The output is being written to the file (not just viewed)
4. Output blocks are marked with `<!-- md-code-output: id="..." -->`
**The tool is idempotent** - running it multiple times on the same input produces the same output.
### No output block created
Output blocks are only created when there's output to capture.
**Reasons for no output:**
- Code produces no stdout/stderr
- Code executed successfully but silently
- Only want output? Add a print statement!
### Duplicate ID errors
Each code block must have a unique ID within the document.
**Error:** `Duplicate code block ID: 'example'`
**Solution:** Rename one of the IDs:
```
<!-- md-code: id="example-1"; bin="python3" -->
<!-- md-code: id="example-2"; bin="python3" -->
```
### Custom fence not working
When using custom fences, make sure:
- The fence parameter uses the correct syntax: `fence="~~~~"`
- The fence is longer than any fence used in the code itself
- Both opening and closing fences match
### Syntax highlighting issues
If syntax highlighting isn't working in output blocks:
- Use the `syntax` parameter: `syntax="json"`
- The syntax name must be supported by your markdown viewer
- Common values: `json`, `text`, `python`, `bash`, `xml`