Markdown Runbook Extractor

Paste a Markdown runbook and get one runnable script — every fenced code block becomes a named, numbered step, with pasted `$` prompts stripped and command output dropped. Also exports an ordered task checklist or structured JSON. Runs entirely in your browser, no upload, no sign-up.

Try:
Runnable script

What this tool does

A runbook is a how-to document whose steps are fenced code blocks: install this, migrate that, restart the service. Paste one and this tool tangles it — it pulls out every executable block, names it, numbers it, and joins the whole thing into one script you can actually run, with an ordered task list in the header. It runs entirely in your browser with WebAssembly: nothing is uploaded, it works offline, and there's no sign-up.

The extractor:

Options

OptionWhat it does
Code blocks to extractauto (default) picks the language family with the most blocks. Or force shell (bash/sh/zsh/console/shell-session), python (python/py/pycon), powershell (powershell/pwsh/ps1), javascript (js/node), or any — every fence that carries a language tag. Untagged fences are never steps.
Outputscript (default) — one runnable script whose header lists the ordered tasks. tasks — a Markdown checklist. json{language, count, runnable, steps:[…]} with each step's code, tags and source line.
Tag filterComma-separated. A block is kept if it carries any listed tag; prefix with - to exclude (deploy,-slow). Empty keeps everything.
Strip $ promptsOn by default. Turn it off to keep a transcript verbatim.
Add ==> progress linesOn by default. Emits echo "==> [2/5] Run migrations" (or print / Write-Host) before each step.
Abort-on-error headerOn by default. set -euo pipefail for shell, $ErrorActionPreference = 'Stop' for PowerShell. No-op for Python and JavaScript, which already abort on an unhandled error.
Comment out skip-tagged blocksOn by default. Turn it off to make them runnable.

Worked example

Given this runbook:

# Deploy the API

## Install dependencies

```console
$ npm ci
added 42 packages
```

## Run migrations

```bash name=migrate
./manage.py migrate
```

## Rollback (do not run)

```bash skip
./manage.py migrate --rollback
```

the default script output is:

#!/usr/bin/env bash
# Runbook: 2 runnable task(s) of 3 extracted from Markdown.
# Tasks:
#   1. Install dependencies
#   2. migrate
#   3. Rollback (do not run)  [skipped: tagged skip]

set -euo pipefail

# --- 1/3 · Install dependencies (console, line 5) ---
echo "==> [1/3] Install dependencies"
npm ci

# --- 2/3 · migrate (bash, line 12) ---
echo "==> [2/3] migrate"
./manage.py migrate

# --- 3/3 · Rollback (do not run) (bash, line 18) — SKIPPED, tagged skip ---
# ./manage.py migrate --rollback

Note what happened: the $ prompt is gone, added 42 packages (command output, not a command) was dropped, step 1 took its name from the heading and step 2 from name=migrate, and the rollback block is commented out because it carries the skip tag.

Switch Output to tasks for the same runbook and you get a checklist:

# Runbook tasks (2 runnable of 3)

- [ ] 1. Install dependencies — `console`, 1 line, line 5
- [ ] 2. migrate — `bash`, 1 line, line 12
- [ ] 3. ~~Rollback (do not run)~~ — `bash`, 1 line, line 18, tags: skip — skipped, tagged skip

Limits & edge cases

FAQ

Is it free and private?

Yes. Extraction runs locally in your browser with WebAssembly — your runbook never leaves your device, and the page keeps working offline once it has loaded. There's no account and nothing is uploaded.

How do I name a step?

Put the name in the fence's info string. All of these work: ```bash "Install deps", ```bash name=install-deps, ```bash title="Install deps", ```bash id=install, and the Pandoc/Entangled attribute form ```{.bash #install-deps}. If you don't name a block, the tool uses a bold label directly above it, then the nearest heading, then step-N.

Why did my command output end up missing?

That's Strip $ prompts doing its job. In a block where at least one line starts with a prompt ($ , % , , PS C:\>, >>> ), the un-prompted lines are treated as the command's output and dropped, and the prompts themselves are removed — which is exactly what turns a copied README session into runnable commands. Turn the option off to keep the transcript verbatim.

How do I stop a dangerous snippet from ending up in the script?

Tag its fence: ```bash skip (or no-run, noexec, ignore, example, output). Tagged blocks still appear in the task list and in the script — but commented out, with a SKIPPED marker — so nothing is silently lost and nothing runs by accident. Alternatively, filter them out entirely with a - tag filter.

Can I extract only part of a runbook?

Yes, two ways. Tag your fences (```bash#deploy, ```bash deploy slow, or ```{.bash .deploy}) and put those tags in the Tag filterdeploy,-slow keeps deploy steps and drops slow ones. Or switch Code blocks to extract to a single language so only, say, the Python blocks come through.

Does it work for Python, PowerShell or Node runbooks?

Yes. Set Code blocks to extract (or leave it on auto, which picks whichever family has the most blocks). Each family gets the right script shape: a #!/usr/bin/env python3 or node shebang, $ErrorActionPreference = 'Stop' for PowerShell, and progress lines rendered as print, console.log or Write-Host rather than echo. Python >>> doctest prompts are stripped too.

What's the JSON output for?

Automation. It returns {language, count, runnable, steps:[…]} where each step carries its index, name, language, source line, tags, skipped flag, line count and raw code — enough to drive your own runner, generate a ticket per step, or diff a runbook between two revisions.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool markdown-runbook-extractor '# Deploy the API

## Install dependencies

```console
$ npm ci
added 42 packages
```

## Run migrations

```bash name=migrate
./manage.py migrate
```'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/markdown-runbook-extractor/?markdown=%23%20Deploy%20the%20API%0A%0A%23%23%20Install%20dependencies%0A%0A%60%60%60console%0A%24%20npm%20ci%0Aadded%2042%20packages%0A%60%60%60%0A%0A%23%23%20Run%20migrations%0A%0A%60%60%60bash%20name%3Dmigrate%0A.%2Fmanage.py%20migrate%0A%60%60%60&language=auto&output=script&tags=deploy%2C-slow&strip_prompts=true&echo_steps=true&fail_fast=true&skip_marked=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.