Recipes
Common patterns for documenting terminal workflows. Each recipe is self-contained; copy the fenced block into your own .qmd file.
Interrupt a long-running process
Send Ctrl-C to cancel a command that doesn’t terminate on its own. The key is expect-prompt: false on the blocking command (since it won’t return a prompt) and literal: false on the control key (so it’s interpreted as a keystroke, not typed literally).
```{term}
sleep 100 #! expect-prompt: false
ctrl-c #! literal: false, delay: 0.5
```sleep 100
^C
Capture a fullscreen TUI
Render the full terminal screen (not just scrollback output) for apps like htop, vim, or less. The trick is to type the command in one cell without pressing Enter, then send Enter in a separate fullscreen: true cell with a hold to capture the screen while the app is displayed.
```{term}
htop #! enter: false, hold: 0.5
```
```{term}
#| fullscreen: true
#| timeout: 4
enter #! literal: false, hold: 3.0
```
```{term}
#| include: false
q #! literal: false
```htop
0[| 0.7%] Tasks: 42, 112 thr, 118 kthr; 1 runnin
1[| 0.7%] Load average: 0.48 0.44 0.19
2[ 0.0%] Uptime: 00:13:23
3[ 0.0%]
Mem[||||||||||||| 965M/15.6G]
Swp[ 0K/3.00G]
[Main] [I/O]
PID USER PRI NI VIRT RES SHR S CPU%▽MEM% TIME+ Command
5153 runner 20 0 8356 4712 3728 R 0.7 0.0 0:00.04 htop
1 root 20 0 22848 14404 9848 S 0.0 0.1 0:02.95 /sbin/init
155 root 19 -1 113M 18144 16844 S 0.0 0.1 0:00.52 /usr/lib/syst
218 root RT 0 298M 43708 8760 S 0.0 0.3 0:00.03 /sbin/multipa
226 root 20 0 25980 8000 5184 S 0.0 0.0 0:00.20 /usr/lib/syst
227 root 20 0 298M 43708 8760 S 0.0 0.3 0:00.00 /sbin/multipa
228 root RT 0 298M 43708 8760 S 0.0 0.3 0:00.00 /sbin/multipa
229 root RT 0 298M 43708 8760 S 0.0 0.3 0:00.00 /sbin/multipa
230 root RT 0 298M 43708 8760 S 0.0 0.3 0:00.00 /sbin/multipa
231 root RT 0 298M 43708 8760 S 0.0 0.3 0:00.03 /sbin/multipa
233 root RT 0 298M 43708 8760 S 0.0 0.3 0:00.00 /sbin/multipa
394 root 20 0 3848 2908 1988 S 0.0 0.0 0:00.22 /usr/lib/linu
525 systemd-re 20 0 21476 13236 11020 S 0.0 0.1 0:00.12 /usr/lib/syst
F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit
Drive an interactive prompt
Respond to a program that asks questions. Use expect-prompt: false on lines that produce a question (not a shell prompt), and provide the answer on the next line.
```{term}
read "name?What is your name? " #! expect-prompt: false
World #! expect-prompt: true
echo "Hello, $name"
```read "name?What is your name? "
What is your name? World
echo "Hello, $name"
Hello, World
Persist state across cells
Each cell runs in the same shell session. Variables and shell state carry over from one cell to the next. This is the key difference from static code blocks.
```{term}
GREETING="Hello from quarto-term"
COUNT=3
```
```{term}
for i in $(seq 1 $COUNT); do
echo "$GREETING (#$i)"
done
```GREETING="Hello from quarto-term"
COUNT=3
for i in $(seq 1 $COUNT); do
echo "$GREETING (#$i)"
done
Hello from quarto-term (#1)
Hello from quarto-term (#2)
Hello from quarto-term (#3)
Truncate verbose output
When a command produces many lines but only the shape matters, use truncate to collapse a range into a summary. Readers see that output existed without scrolling past it.
```{term}
#| truncate: [3:-3]
seq 1 20
```seq 1 20
1
[17 lines truncated]
19
20
The range 3:-3 keeps the first two and last two lines, replacing everything between with a “[N lines truncated]” message. You can also use regex patterns or multiple ranges.
Annotate code with callouts
Add numbered markers to specific lines. This is particularly useful for technical books (e.g., O’Reilly style) where you reference lines by number in the surrounding prose.
The callout option takes line indices (1-based, referring to the rendered output which includes both commands and their output). Use it to highlight specific parts of a script:
```{term}
#| callout: [1, 2, 3]
for planet in Mercury Venus Earth Mars; do
echo "- $planet"
done
```for planet in Mercury Venus Earth Mars; do <1>
echo "- $planet" <2>
done <3>
- Mercury
- Venus
- Earth
- Mars
- The
forloop iterates over a space-separated list of values. - The loop body runs once per item, with
$planetbound to the current value. donecloses the loop; the shell waits until here before executing.
Hide setup, show result
Use include: false to run commands that prepare state without showing them in the document. Readers only see the interesting part.
```{term}
#| include: false
mkdir -p /tmp/demo-project
echo '{"name": "my-app", "version": "2.1.0"}' > /tmp/demo-project/package.json
echo 'console.log("hello")' > /tmp/demo-project/index.js
```
```{term}
ls /tmp/demo-project/
cat /tmp/demo-project/package.json | python3 -m json.tool
```ls /tmp/demo-project/
index.js package.json
cat /tmp/demo-project/package.json | python3 -m json.tool
{
"name": "my-app",
"version": "2.1.0"
}
Remove noise from output
Strip specific lines that clutter the output: warnings, empty lines, or headers you don’t want. Unlike truncate, removed lines disappear entirely with no placeholder.
```{term}
#| remove: ["^$"]
echo "first"
echo ""
echo "second"
echo ""
echo "third"
```echo "first"
first
echo ""
echo "second"
second
echo ""
echo "third"
third
Record a session for playback
Record the terminal session to an asciicast (.cast) or termshow (.termshow) file alongside the rendered document. This is useful for embedding animated replays on a webpage or sharing a demo without requiring the reader to re-run anything.
---
extensions:
term:
record: "demo.cast"
typing: true
---
```{term}
echo "This session is being recorded"
```The record option accepts a single path or a list for multiple formats:
extensions:
term:
record:
- "demo.cast"
- "demo.termshow"The .cast format is playable with asciinema. The .termshow format works with the termshow player. Combine with typing: true to make the recording look natural.
Simulate realistic typing
Add human-like typing cadence so commands appear one keystroke at a time. This is primarily useful when recording sessions for playback; the rendered HTML output is identical whether typing is enabled or not.
Set typing: true for defaults, or configure speed (characters per minute) and error-rate (probability of a typo per character, corrected with backspace):
```{term}
#| typing: true
echo "This looks like a human typed it"
```echo "This looks like a human typed it"
This looks like a human typed it
At the document level, you can configure both parameters:
extensions:
term:
typing:
speed: 100
error-rate: 0.02Set cell-level defaults
When multiple lines in a cell share the same options (e.g., all non-literal), set them once at the cell level with #| instead of repeating #! on every line. Individual lines can still override.
```{term}
#| literal: false
#| delay: 0.2
echo "typed normally" #! literal: true
up
enter
```echo "typed normally"
typed normally
echo "typed normally"
typed normally
Override timeout for a slow command
A single slow command doesn’t require raising the document-wide timeout. Set it per-line with #! to handle just that one command.
```{term}
echo "fast"
sleep 2 && echo "done" #! timeout: 5.0
echo "back to normal"
```echo "fast"
fast
sleep 2 && echo "done"
done
echo "back to normal"
back to normal