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

Settings Reference

Setting Default Description
idle_time_limit 3.0 Maximum seconds for any idle gap
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-right, bottom-left, bottom-right.

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:
  idle_time_limit: 1.5
  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 other tools? Import them:

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

# From VHS (.tape files)
great-docs termshow import-tape demo.tape 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.
  • Use idle_time_limit — Caps long pauses so viewers aren’t 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