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
  1. The for loop iterates over a space-separated list of values.
  2. The loop body runs once per item, with $planet bound to the current value.
  3. done closes 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.02

Control arrow keys and navigation

Use literal: false to send special keys like arrows, tab, and escape sequences. Space-separated words on one line are sent as individual keystrokes.

```{term}
echo "first command"
echo "second command"
up up enter #! literal: false, delay: 0.3
```
echo "first command"
first command

echo "second command"
second command

echo "first command"
first command

Set 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