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.0%] Tasks: 42, 112 thr, 115 kthr; 1 runnin
    1[                            0.0%] Load average: 0.64 0.61 0.27 
    2[|||                         9.1%] Uptime: 00:04:09
    3[                            0.0%]
  Mem[||||||||||||||||||   1.03G/15.6G]
  Swp[                        0K/3.00G]

  [Main] [I/O]
    PID USER       PRI  NI  VIRT   RES   SHR S  CPU%▽MEM%   TIME+  Command      
    899 root        20   0 1994M 47936 31056 S   9.5  0.3  0:00.02 /usr/bin/cont
   4929 runner      20   0  8352  4916  3936 R   9.5  0.0  0:00.11 htop
      1 root        20   0 22876 14340  9880 S   0.0  0.1  0:02.17 /sbin/init
    155 root        19  -1 75076 16440 15164 S   0.0  0.1  0:00.18 /usr/lib/syst
    221 root        RT   0  298M 43676  8760 S   0.0  0.3  0:00.01 /sbin/multipa
    226 root        20   0 25956  8032  5220 S   0.0  0.0  0:00.11 /usr/lib/syst
    228 root        20   0  298M 43676  8760 S   0.0  0.3  0:00.00 /sbin/multipa
    229 root        RT   0  298M 43676  8760 S   0.0  0.3  0:00.00 /sbin/multipa
    230 root        RT   0  298M 43676  8760 S   0.0  0.3  0:00.00 /sbin/multipa
    231 root        RT   0  298M 43676  8760 S   0.0  0.3  0:00.00 /sbin/multipa
    232 root        RT   0  298M 43676  8760 S   0.0  0.3  0:00.00 /sbin/multipa
    233 root        RT   0  298M 43676  8760 S   0.0  0.3  0:00.00 /sbin/multipa
    309 root        20   0  3848  2972  2052 S   0.0  0.0  0:00.04 /usr/lib/linu
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}
MESSAGE="Hello from quarto-term"
COUNT=3
```

```{term}
for i in $(seq 1 $COUNT); do
  echo "$MESSAGE (#$i)"
done
```
MESSAGE="Hello from quarto-term"

COUNT=3
for i in $(seq 1 $COUNT); do
  echo "$MESSAGE (#$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.

Customize the marker style with callout-values and callout-format. By default, markers render as <1>, <2>, etc. Change callout-values to a string (each character becomes one marker) or a list of strings, and callout-format to control the surrounding text ({} is the placeholder):

for planet in Mercury Venus Earth Mars; do (a)
  echo "- $planet" (b)
done (c)
- Mercury
- Venus
- Earth
- Mars
echo "first" [start]
first

echo "second"
second

echo "third"
third [end]

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

See the Recording page for how to record sessions to .cast files and embed an interactive player.

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

Show only the output

Use echo: false to hide commands and prompts, showing only the terminal output:

```{term}
#| echo: false
echo "You only see the output"
```
You only see the output

Show only the commands

Use output: false to hide the output and show only the typed commands with prompts:

```{term}
#| output: false
echo "The output of this is hidden"
date
```
echo "The output of this is hidden"
date

Show the trailing prompt

By default the final prompt after a command is hidden. Use keep-last-prompt: true to include it, which is useful when showing that a command returned to a ready state:

```{term}
#| keep-last-prompt: true
echo "done"
```
echo "done"
done

Render a static code block without execution

Use eval: false to show a {term} block as a static code example without executing it. Useful for showing syntax that can’t run in your environment:

```{term}
#| eval: false
ssh production-server "systemctl restart myapp"
```
ssh production-server "systemctl restart myapp"

Pass environment variables

Use env at the document level to inject variables into the shell session without showing setup commands:

---
extensions:
  term:
    env:
      GREETING: "Hello from env"
      APP_VERSION: "2.0.1"
---

```{term}
echo "$GREETING (v$APP_VERSION)"
```

Produces:

echo "$GREETING (v$APP_VERSION)"
Hello from env (v2.0.1)

Validate output with assertions

Use assert to verify that expected content appears in the output. The render fails if the pattern is not found, which is useful for CI to catch documentation drift:

```{term}
echo "version 3.2.1" #! assert: "3.2.1"
```
echo "version 3.2.1"
version 3.2.1

Use a custom line marker

Change the line option marker from the default #! to something else when #! conflicts with your shell syntax:

```{term}
#| marker: "//"
sleep 5 // expect-prompt: false
ctrl-c // literal: false
```
sleep 5
^C