☰ GDG /
Docstrings (001–005)
#001 gdtest_minimal #003 gdtest_sphinx #002 gdtest_google #004 gdtest_nodocs #005 gdtest_mixed_docs
Layouts (006–013)
#007 gdtest_python_layout #006 gdtest_src_layout #008 gdtest_lib_layout #009 gdtest_hatch #010 gdtest_setuptools_find #011 gdtest_setup_cfg #012 gdtest_setup_py #013 gdtest_auto_discover
Exports (014–017)
#014 gdtest_no_all #016 gdtest_config_exclude #015 gdtest_all_concat #017 gdtest_auto_exclude
Object Types (018–027)
#018 gdtest_small_class #020 gdtest_dataclasses #019 gdtest_big_class #021 gdtest_enums #022 gdtest_typed_containers #023 gdtest_protocols #024 gdtest_descriptors #026 gdtest_nested_class #025 gdtest_dunders #027 gdtest_constants
Directives (028–032)
#028 gdtest_seealso #029 gdtest_nodoc #030 gdtest_user_guide_auto #031 gdtest_user_guide_sections #032 gdtest_user_guide_subdirs
User Guide (033–038)
#033 gdtest_user_guide_explicit #034 gdtest_user_guide_custom_dir
#037 gdtest_index_qmd FAIL
#036 gdtest_readme_rst #035 gdtest_user_guide_hyphen #038 gdtest_index_md
Landing Pages (039–043)
#041 gdtest_index_frontmatter FAIL
#039 gdtest_no_readme #040 gdtest_index_wins #043 gdtest_github_contrib #042 gdtest_full_extras
Extras & Config (044–050)
#044 gdtest_cli_click #045 gdtest_cli_nested #047 gdtest_explicit_ref #046 gdtest_cli_typer #049 gdtest_name_mismatch #048 gdtest_kitchen_sink #050 gdtest_src_big_class
Cross-Dimension (051–065)
#051 gdtest_google_big_class #052 gdtest_user_guide_cli #053 gdtest_explicit_big_class #054 gdtest_src_no_all #056 gdtest_google_seealso #055 gdtest_extras_guide #057 gdtest_setup_cfg_src #058 gdtest_exclude_cli #059 gdtest_src_explicit_ref #060 gdtest_async_funcs #061 gdtest_generators #063 gdtest_abstract_props #062 gdtest_overloads #064 gdtest_multi_inherit #065 gdtest_slots_class
API Patterns (066–077)
#066 gdtest_frozen_dc #067 gdtest_generics #068 gdtest_context_mgr #069 gdtest_decorators #071 gdtest_reexports #070 gdtest_exceptions #073 gdtest_deep_nesting #072 gdtest_many_exports #074 gdtest_long_docs #075 gdtest_many_guides #077 gdtest_flit #076 gdtest_many_big_classes
Scale & Stress (078–082)
#078 gdtest_pdm #079 gdtest_namespace #080 gdtest_monorepo #081 gdtest_multi_module #082 gdtest_src_legacy
Build Systems (083–088)
#083 gdtest_empty_module #084 gdtest_all_private #085 gdtest_duplicate_all #086 gdtest_badge_readme #087 gdtest_math_docs #088 gdtest_mixed_guide_ext
Edge Cases (089–095)
#089 gdtest_unicode_docs #090 gdtest_config_all_on #091 gdtest_config_display #092 gdtest_config_minimal #093 gdtest_config_parser #094 gdtest_config_extra_keys #095 gdtest_github_icon
Config Matrix (096–100)
#096 gdtest_source_branch #097 gdtest_source_path #098 gdtest_source_title #099 gdtest_source_disabled #100 gdtest_sidebar_disabled
Config Options (101–125)
#101 gdtest_sidebar_min_items #103 gdtest_cli_name #104 gdtest_dynamic_false #102 gdtest_sidebar_float #105 gdtest_parser_google #106 gdtest_parser_sphinx #107 gdtest_display_name #108 gdtest_funding #109 gdtest_authors_multi #110 gdtest_no_darkmode #111 gdtest_exclude_list #112 gdtest_jupyter_kernel #113 gdtest_config_sections #114 gdtest_config_ug_string #115 gdtest_config_ug_list #116 gdtest_config_changelog #117 gdtest_config_reference #118 gdtest_config_combo_a
#122 gdtest_config_combo_e FAIL
#119 gdtest_config_combo_b #120 gdtest_config_combo_c #121 gdtest_config_combo_d #123 gdtest_config_combo_f #124 gdtest_attribution_on #125 gdtest_attribution_off
Docstring Richness (126–150)
#126 gdtest_rst_versionadded #127 gdtest_rst_deprecated #128 gdtest_rst_note #129 gdtest_rst_warning #130 gdtest_rst_tip #131 gdtest_rst_caution #132 gdtest_rst_danger #133 gdtest_rst_important #134 gdtest_rst_mixed_dirs #135 gdtest_directives #136 gdtest_sphinx_func_role #137 gdtest_sphinx_class_role #138 gdtest_sphinx_exc_role #139 gdtest_sphinx_meth_role #140 gdtest_sphinx_mixed_roles #141 gdtest_numpy_rich #142 gdtest_google_rich #143 gdtest_sphinx_rich #144 gdtest_docstring_examples #145 gdtest_examples_rst_repro #146 gdtest_docstring_notes #147 gdtest_docstring_warnings #148 gdtest_docstring_references #149 gdtest_docstring_seealso #150 gdtest_docstring_math
UG Variations (151–165)
#151 gdtest_docstring_tables #152 gdtest_docstring_combo #153 gdtest_ug_auto #154 gdtest_ug_numbered #155 gdtest_ug_sections_fm #156 gdtest_ug_subdirs #157 gdtest_ug_custom_dir #158 gdtest_ug_deep_nest #159 gdtest_ug_mixed_ext #161 gdtest_ug_explicit_order #160 gdtest_ug_many_pages #162 gdtest_ug_single_page #163 gdtest_ug_no_frontmatter
#164 gdtest_ug_with_code FAIL
#165 gdtest_ug_with_images
Custom Sections (166–175)
#166 gdtest_ug_hyphen_dir #167 gdtest_ug_combo #168 gdtest_sec_examples #169 gdtest_sec_tutorials #170 gdtest_sec_recipes #171 gdtest_sec_blog #172 gdtest_sec_faq #173 gdtest_sec_multi #174 gdtest_sec_navbar_after #175 gdtest_sec_with_ug
Reference Config (176–185)
#176 gdtest_sec_with_ref #177 gdtest_sec_deep #178 gdtest_sec_index_opt #181 gdtest_custom_passthrough_navbar #180 gdtest_sec_sidebar_single #179 gdtest_sec_index_hero #182 gdtest_custom_raw_navbar_after #185 gdtest_custom_basename_output #183 gdtest_custom_mixed_modes #184 gdtest_custom_nested_combo
Site Theming (186–195)
#186 gdtest_custom_nested_output #187 gdtest_custom_missing_dir_combo #189 gdtest_ref_members_false #188 gdtest_ref_explicit #190 gdtest_ref_mixed #191 gdtest_ref_reorder #193 gdtest_ref_single_section #192 gdtest_ref_sectioned #194 gdtest_ref_module_expand #195 gdtest_ref_big_class
Stress Tests (196–200)
#196 gdtest_ref_multi_big #197 gdtest_ref_title #198 gdtest_theme_cosmo #199 gdtest_theme_lumen #200 gdtest_theme_cerulean #201 gdtest_toc_disabled #202 gdtest_toc_depth #203 gdtest_toc_title #204 gdtest_site_combo #205 gdtest_display_badges #206 gdtest_display_authors #207 gdtest_display_funding #208 gdtest_stress_all_config #209 gdtest_stress_all_docstr #210 gdtest_stress_all_ug #211 gdtest_stress_all_sections #213 gdtest_src_google_seealso #212 gdtest_stress_everything #214 gdtest_hatch_nodoc #215 gdtest_pdm_big_class #216 gdtest_flit_enums #217 gdtest_namespace_ug #218 gdtest_ug_subdir_numbered #219 gdtest_homepage_ug #221 gdtest_logo #222 gdtest_hero_basic #223 gdtest_hero_readme_badges #224 gdtest_hero_disabled #220 gdtest_long_names #225 gdtest_hero_custom #226 gdtest_hero_wordmark #227 gdtest_hero_no_logo #228 gdtest_hero_explicit_badges #229 gdtest_hero_index_qmd #230 gdtest_hero_auto_logo #231 gdtest_md_disabled #232 gdtest_md_no_widget #233 gdtest_announce_simple #234 gdtest_announce_dict #235 gdtest_announce_disabled #236 gdtest_gradient_sky #237 gdtest_gradient_peach #238 gdtest_gradient_prism #239 gdtest_gradient_lilac #240 gdtest_gradient_slate #241 gdtest_gradient_honey #242 gdtest_gradient_dusk #243 gdtest_gradient_mint #244 gdtest_gradient_navbar #245 gdtest_gradient_both #246 gdtest_gradient_mixed #247 gdtest_gradient_no_dismiss #248 gdtest_header_text #249 gdtest_header_list #250 gdtest_header_file #252 gdtest_navbar_color_light #251 gdtest_navbar_color #253 gdtest_navbar_color_dark #254 gdtest_navbar_color_same #255 gdtest_navbar_color_split #256 gdtest_kitchen_sink_q #257 gdtest_stress_everything_q #258 gdtest_seealso_desc #259 gdtest_numpy_seealso_desc #260 gdtest_interlinks #261 gdtest_autolink #262 gdtest_skill_default #263 gdtest_skill_curated #265 gdtest_skill_disabled #264 gdtest_skill_config #266 gdtest_skill_rich #267 gdtest_skill_combo
#269 gdtest_i18n_french FAIL
#268 gdtest_skill_complex
#270 gdtest_i18n_japanese FAIL
#272 gdtest_code_cells FAIL
#271 gdtest_i18n_arabic FAIL
#274 gdtest_page_tags #276 gdtest_tag_location #275 gdtest_page_status #273 gdtest_nav_icons
#279 gdtest_gt_tables FAIL
#280 gdtest_scale_to_fit FAIL
#281 gdtest_scale_min_scale FAIL
#278 gdtest_homepage_ug_subdirs #277 gdtest_icon_shortcode #282 gdtest_homepage_wide #283 gdtest_code_span_headings #286 gdtest_namespace_src #284 gdtest_sec_blog_user_index #285 gdtest_sec_dir_titles #287 gdtest_auto_include #288 gdtest_no_auto_exclude
#289 gdtest_tbl_preview FAIL
#290 gdtest_tbl_shortcode
#291 gdtest_tbl_explorer FAIL
#292 gdtest_hr_shortcode #293 gdtest_accent_color #294 gdtest_keys_shortcode #295 gdtest_inline_methods #296 gdtest_inline_always #297 gdtest_inline_never #299 gdtest_ref_inherited_explicit #300 gdtest_ref_include_inherited #298 gdtest_inline_threshold
#301 gdtest_mock_code FAIL
#305 gdtest_hero_no_name #304 gdtest_lightbox #302 gdtest_details_shortcode #303 gdtest_termshow #306 gdtest_sec_nested_tags #307 gdtest_sec_xref_subdirs #309 gdtest_bibliography_csl #308 gdtest_bibliography #311 gdtest_go_cli #310 gdtest_custom_css #312 gdtest_ug_dark_assets #313 gdtest_code_include #314 gdtest_ug_mixed_subdir_order #315 gdtest_type_aliases #317 gdtest_marimo #316 gdtest_complete_docstrings #318 gdtest_no_breadcrumbs #321 gdtest_ref_section_order #319 gdtest_mcp #320 gdtest_d2_diagrams
307/321 built ⏱ 1m 5s 🧪 8/24

Termshow Guide

Overview

The termshow is Great Docs’ built-in terminal recording player. It renders pre-recorded terminal sessions as interactive, frame-accurate SVG animations directly in your documentation pages — no JavaScript framework dependencies, no external services.

Key capabilities:

  • Frame-accurate SVG rendering of terminal output
  • Chapter-based navigation with labeled markers
  • Contextual annotations that appear at specific timestamps
  • Keyboard shortcuts for power users
  • Adjustable playback speed (0.5× to 3×)
  • Works offline and with file:// protocol (all data embedded inline)
  • Responsive layout that scales to any viewport width
  • Light/dark theme support (follows the site theme)

Live Demo

Here’s a recording of real Great Docs CLI commands — scan, lint, and term render — running against this very package:

Terminal recording: great-docs-cli

The Recording Format

Termshow uses a two-file system for each recording:

The .termshow File

This is the raw terminal recording in NDJSON format. Each line is a JSON array with [delay, event_type, data]:

{"version": 1, "format": "termshow", "term": {"cols": 80, "rows": 20}}
[0.5, "o", "$ "]
[0.1, "o", "echo hello"]
[0.6, "o", "\r\nhello\r\n"]
[1.0, "m", "Command executed"]

Event types:

Type Meaning
"o" Output — terminal data written to stdout
"i" Input — user keystrokes (for display purposes)
"m" Marker — internal marker used for chapter sync

The header line sets terminal dimensions and metadata.

The .termshow.yml Script File

This companion file defines chapters, annotations, timing adjustments, and visual settings:

source: demos/my-recording.termshow

settings:
  window_chrome: colorful   # Window decoration style
  theme: monokai            # Terminal color scheme
  font_size: 14             # Font size in pixels

chapters:
  - at: 0.0
    label: Introduction
  - at: 5.0
    label: Configuration
  - at: 12.0
    label: Running Tests

annotations:
  - at: 1.0
    duration: 3.0
    text: This installs all required dependencies
    position: top-right
    style: callout
  - at: 6.0
    duration: 2.5
    text: Configuration is auto-detected
    position: bottom-right
    style: subtle

cuts:
  - from: 8.0
    to: 11.0
    type: ellipsis   # Shows '…' for the cut section

snippets:
  - at: 0.0
    duration: 5.0
    text: pip install my-package
    label: Install
  - at: 12.0
    duration: 4.0
    match: "\\$ (.+)"   # Regex: captures command after $ prompt
    label: Run

Snippets

Snippets add a copy button to the player that appears during a time range. Readers can click it to copy text to their clipboard without manual retyping.

Literal Text

Use text when you know the exact string to copy:

snippets:
  - at: 0.5
    duration: 7.0
    text: pip install my-tool
    label: Install

Regex Match

Use match to extract text dynamically from the terminal buffer:

snippets:
  - at: 0.5
    duration: 7.0
    match: "\\$ (.+)"
    label: Copy Command

The regex runs against the visible terminal text when the reader clicks the copy button. If it has a capture group, group 1 is copied; otherwise the full match is used. This is useful when the terminal shows a typed command and you want to extract it without hardcoding.

Snippet Fields

Field Default Description
at (required) Time in seconds when the button appears
duration 5.0 How long the button stays visible
text "" Literal text copied on click
match "" Regex matched against visible terminal text
label "Copy" Button label shown alongside the copy icon

At least one of text or match must be provided. If both are set, match takes priority (with text as fallback).

Settings Reference

Setting Default Description
window_chrome colorful Window decoration: colorful, plain, none
theme (auto) Terminal color scheme
font_size 14 Font size in rendered SVG (px)
line_height 1.2 Line height multiplier
padding 12 Inner padding of the terminal area (px)

Annotation Styles

Annotations appear as overlays on the terminal at specified times. Three styles are available:

Style Appearance
callout Semi-opaque dark card with accent border
subtle Lighter, smaller text — less intrusive
highlight Amber-tinted with warm border — draws attention

Positions: top-left, top, top-right, left, right, bottom-left, bottom, bottom-right.

Widths: small (25%), medium (50%, default), large (75%).

Embedding in Pages

Use the termshow Quarto shortcode in any .qmd file:

## Basic usage



## With chapter pausing



## Autoplay with custom speed

Shortcode Options

Option Default Description
file (required) Path to .termshow file (without extension)
autoplay false Start playing automatically on page load
loop false Loop playback when reaching the end
speed 1 Initial playback speed multiplier
pause_on_chapters false Auto-pause at each chapter boundary
controls true Show the control bar
theme auto Player theme: auto, dark, or light

Player Controls

The player provides a full set of interactive controls:

Control Bar

From left to right:

  1. Play/Pause button — Toggles playback. Shows ↺ (replay) at the end.
  2. Current time — Elapsed time counter.
  3. Timeline scrub bar — Click anywhere to seek. Chapter markers appear as gold ticks with wider hit targets for easy clicking.
  4. Remaining time — Counts down to zero during playback.
  5. Speed button — Cycles through 0.5×, 1×, 1.5×, 2×, 3×.

Chapter Bar

A thin overlay at the top of the player shows the name of the current chapter, updating as playback progresses.

Center Overlay

A semi-transparent button in the center of the viewport:

  • Before playback — Shows ▶ as a call-to-action.
  • After playback ends — Shows ↺ to indicate replay. Clicking returns the player to its initial state (frame 0, ready to play).
  • During chapter pauses — Hidden, so the terminal content remains fully visible.

Keyboard Shortcuts

Click the player viewport first to give it focus, then use:

Key Action
Space Play / Pause (or reset from ended state)
Seek forward 5 seconds
Seek backward 5 seconds
. Jump to next chapter
, Jump to previous chapter

Workflow

The full termshow workflow from recording to rendered page:

1. Record          great-docs termshow record demos/my-demo.termshow
2. Edit script     Create/edit demos/my-demo.termshow.yml
3. Preview         great-docs termshow play demos/my-demo.termshow
4. Embed           Add  to your .qmd
5. Build           great-docs build (renders SVG frames automatically)

Step 1: Record

great-docs termshow record demos/install-guide.termshow

This launches a recording session. Everything you type and see in the terminal is captured with precise timing. Press Ctrl+D or type exit to end the recording.

Step 2: Create the Script

Create demos/install-guide.termshow.yml alongside the recording. Define chapters at logical breakpoints in your workflow, and add annotations to explain what’s happening:

source: demos/install-guide.termshow

settings:
  window_chrome: colorful

chapters:
  - at: 0.0
    label: Setup
  - at: 8.0
    label: Install
  - at: 15.0
    label: Verify

annotations:
  - at: 1.0
    duration: 3.0
    text: Start by activating the virtual environment
    position: top-right
    style: callout

Step 3: Preview

great-docs termshow play demos/install-guide.termshow

This plays the recording in your terminal so you can verify timing and check that chapter boundaries feel natural.

Step 4: Embed

Add the shortcode to any user guide or documentation page:

Step 5: Build

great-docs build

During the build, Great Docs:

  1. Finds all .termshow files in your project
  2. Renders each recording into a series of SVG keyframes
  3. Generates a manifest.json with timing, chapters, and annotations
  4. The Lua shortcode filter embeds the manifest and all SVG frames inline in the HTML — no runtime fetches needed

Importing Existing Recordings

Already have terminal recordings from asciinema? Import them:

# From asciinema (.cast files)
great-docs termshow import-cast recording.cast demos/my-demo

The import preserves timing and terminal dimensions. You’ll still want to create a .termshow.yml script to add chapters and annotations.

Tips & Best Practices

  • Keep recordings short — 15–30 seconds is ideal. Split longer workflows into multiple recordings. waiting through your thinking time.
  • Place chapters at logical transitions — Each chapter should represent one distinct step in the workflow.
  • Use pause_on_chapters for tutorials — Gives readers time to absorb each step before the next one plays.
  • Annotations are brief — One sentence max. They complement the terminal output, not replace it.
  • Test at different speeds — Make sure annotations are still readable at 1.5× and 2× speed.
  • 80 columns, 20 rows works well for most CLI recordings. Use 60 columns for narrower TUI demos.

Architecture

Under the hood, termshow works in two phases:

Build time (Python + Lua):

  1. core.py discovers .termshow files and calls the renderer
  2. The renderer parses the NDJSON recording + YAML script
  3. It produces SVG keyframes at each visual change point
  4. A manifest.json captures timing, chapters, and annotation data
  5. The Lua shortcode embeds everything inline as <script> JSON blocks

Page load (JavaScript):

  1. termshow.js finds .gd-termshow containers
  2. Reads inline manifest and SVG frame data from <script> elements
  3. Builds the player UI (viewport, controls, chapter bar, overlays)
  4. On play: advances time via requestAnimationFrame, swaps SVG frames at the correct timestamps

This architecture means:

  • Zero network requests at runtime
  • Works with file:// protocol (offline docs)
  • No CORS or fetch issues
  • SVGs scale perfectly at any zoom level