diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 13:22:53 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 13:23:23 -0300 |
| commit | fa39a4998ccf547004f5b209c395e4868b319c00 (patch) | |
| tree | 79e62a282dedf9a1c95279ef6c03536fe6f8fb00 | |
| parent | 16422d0f4c60ae90081163bf78b12d365ebb45ed (diff) | |
| download | pardes-fa39a4998ccf547004f5b209c395e4868b319c00.tar.gz pardes-fa39a4998ccf547004f5b209c395e4868b319c00.zip | |
The hero clip opens its output pane when make is clicked; the image clip shows the Mandelbrot set and a seahorse-valley zoom, no Petscii; the landing lists the PDF and image clips first
record_demos.py: text-is-the-interface starts on README and main.c
alone, and the middle-click on make brings up the output pane before the
right-click puts main.c on line 12. image-pane draws two PNGs, the
classic view and a zoom into the seahorse valley; ls lists them, a
right-click opens the set, Del closes it and a right-click opens the
zoom. clips.toml and CLIPS run pdf-navigation, image-pane, pdf-tint-fit,
then the hero, terminals, scripting and diff-review.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | docs/site/media/captions.txt | 6 | ||||
| -rw-r--r-- | docs/site/media/clips.toml | 28 | ||||
| -rw-r--r-- | docs/site/media/image-pane.mp4 | bin | 182755 -> 294819 bytes | |||
| -rw-r--r-- | docs/site/media/image-pane.png | bin | 189612 -> 199517 bytes | |||
| -rw-r--r-- | docs/site/media/image-pane.webm | bin | 223710 -> 433434 bytes | |||
| -rw-r--r-- | docs/site/media/text-is-the-interface.mp4 | bin | 208679 -> 276620 bytes | |||
| -rw-r--r-- | docs/site/media/text-is-the-interface.png | bin | 84827 -> 84823 bytes | |||
| -rw-r--r-- | docs/site/media/text-is-the-interface.webm | bin | 279200 -> 353359 bytes | |||
| -rw-r--r-- | test/record_demos.py | 82 |
9 files changed, 64 insertions, 52 deletions
diff --git a/docs/site/media/captions.txt b/docs/site/media/captions.txt index 73ad850c..47245043 100644 --- a/docs/site/media/captions.txt +++ b/docs/site/media/captions.txt @@ -1,7 +1,7 @@ +pdf-navigation: A 2,515-page PDF: page, jump to CPUID, search, step hits. +image-pane: Right-click an image's name, even in a shell, to open it. +pdf-tint-fit: PdfTint tints the page, PdfFit fits it, a page address jumps. text-is-the-interface: Middle-click runs a word; right-click an error opens its line. terminals-are-panes: A terminal is a pane: Ctrl-b, then move over its output. scripting-over-9p: A script drives the session through its virtual filesystem (9P). diff-review: Right-click a diff line to open that line of the file. -pdf-navigation: A 2,515-page PDF: page, jump to CPUID, search, step hits. -pdf-tint-fit: PdfTint tints the page, PdfFit fits it, a page address jumps. -image-pane: Right-click a picture's name to open it; Petscii redraws it. diff --git a/docs/site/media/clips.toml b/docs/site/media/clips.toml index 3ce07fa3..f630930c 100644 --- a/docs/site/media/clips.toml +++ b/docs/site/media/clips.toml @@ -5,36 +5,36 @@ # no video, so the site builds before a recording exists. [[clip]] -name = "text-is-the-interface" -caption = "Middle-click runs a word; right-click an error opens its line." +name = "pdf-navigation" +caption = "A 2,515-page PDF: page, jump to CPUID, search, step hits." ready = true [[clip]] -name = "terminals-are-panes" -caption = "A terminal is a pane: Ctrl-b, then move over its output." +name = "image-pane" +caption = "Right-click an image's name, even in a shell, to open it." ready = true [[clip]] -name = "scripting-over-9p" -caption = "A script drives the session through its virtual filesystem (9P)." +name = "pdf-tint-fit" +caption = "PdfTint tints the page, PdfFit fits it, a page address jumps." ready = true [[clip]] -name = "diff-review" -caption = "Right-click a diff line to open that line of the file." +name = "text-is-the-interface" +caption = "Middle-click runs a word; right-click an error opens its line." ready = true [[clip]] -name = "pdf-navigation" -caption = "A 2,515-page PDF: page, jump to CPUID, search, step hits." +name = "terminals-are-panes" +caption = "A terminal is a pane: Ctrl-b, then move over its output." ready = true [[clip]] -name = "pdf-tint-fit" -caption = "PdfTint tints the page, PdfFit fits it, a page address jumps." +name = "scripting-over-9p" +caption = "A script drives the session through its virtual filesystem (9P)." ready = true [[clip]] -name = "image-pane" -caption = "Right-click a picture's name to open it; Petscii redraws it." +name = "diff-review" +caption = "Right-click a diff line to open that line of the file." ready = true diff --git a/docs/site/media/image-pane.mp4 b/docs/site/media/image-pane.mp4 Binary files differindex de60b945..9fb1a0e9 100644 --- a/docs/site/media/image-pane.mp4 +++ b/docs/site/media/image-pane.mp4 diff --git a/docs/site/media/image-pane.png b/docs/site/media/image-pane.png Binary files differindex 3f77e2ac..94eb7b50 100644 --- a/docs/site/media/image-pane.png +++ b/docs/site/media/image-pane.png diff --git a/docs/site/media/image-pane.webm b/docs/site/media/image-pane.webm Binary files differindex 46de130b..764be10c 100644 --- a/docs/site/media/image-pane.webm +++ b/docs/site/media/image-pane.webm diff --git a/docs/site/media/text-is-the-interface.mp4 b/docs/site/media/text-is-the-interface.mp4 Binary files differindex 253d1f39..35a3086c 100644 --- a/docs/site/media/text-is-the-interface.mp4 +++ b/docs/site/media/text-is-the-interface.mp4 diff --git a/docs/site/media/text-is-the-interface.png b/docs/site/media/text-is-the-interface.png Binary files differindex b0d40b15..95a508c5 100644 --- a/docs/site/media/text-is-the-interface.png +++ b/docs/site/media/text-is-the-interface.png diff --git a/docs/site/media/text-is-the-interface.webm b/docs/site/media/text-is-the-interface.webm Binary files differindex 07cf62e6..8a8baa89 100644 --- a/docs/site/media/text-is-the-interface.webm +++ b/docs/site/media/text-is-the-interface.webm diff --git a/test/record_demos.py b/test/record_demos.py index 71bf1055..9256e81e 100644 --- a/test/record_demos.py +++ b/test/record_demos.py @@ -485,26 +485,32 @@ def encode(lossless, name, poster, crf_webm=30, crf_mp4=20): # the clips def hero_setup(s): - """README, main.c under it and an output pane under that, all on - screen from the first frame: the output pane is a finished `clear`, - which `make` will reuse.""" + """README and main.c under it; `make` in the README's tag.""" s.write('/pane/1/look', f'{PROJECT}/src/main.c\n') s.wait(lambda: len(s.panes()) == 2, 'main.c') - s.write('/pane/1/exec', 'clear\n') - s.wait(lambda: any(kind == 'cmd' and 'exit' in s.tag(n) for n, kind in s.panes().items()), 'the output pane') s.write('/pane/1/tag', ' make') s.mouse('motion', 0, *s.cell_px(36, 9)) +def pane_rows(s, name, rows=6): + """The first `rows` screen rows under the tag that starts with `name`.""" + screen = s.screen() + top = next(i for i, line in enumerate(screen) if line[3:].startswith(name)) + return screen[top + 1:top + 1 + rows] + + def text_is_the_interface(s): - """B2 on `make` in a tag runs it; B3 on the error opens main.c there.""" - output = next(n for n, kind in s.panes().items() if kind == 'cmd') + """B2 on `make` in a tag opens its output pane; B3 on the error there + puts main.c on line 12.""" s.pointer = s.cell_px(36, 9) - s.shot(1.2) + s.shot(1.4) col, row = s.find('make', 0) - s.click(2, *s.tag_px(col + 1, row), done=lambda: '(make) exit' in s.tag(output), what='make') + s.click(2, *s.tag_px(col + 1, row), + done=lambda: any(kind == 'cmd' and '(make) exit' in s.tag(n) for n, kind in s.panes().items()), + what='make', after=1.2) col, row = s.find('src/main.c:12:5', 0) - s.click(3, *s.cell_px(col + 4, row), done=lambda: any(line.startswith(' 12 ') for line in s.screen()[6:12]), + s.click(3, *s.cell_px(col + 4, row), + done=lambda: any(line.startswith(' 12 ') for line in pane_rows(s, f'{PROJECT}/src/main.c')), what='main.c at line 12', after=2.8) s.shots[-1]['poster'] = True @@ -593,24 +599,29 @@ def diff_review(s): s.shots[-1]['poster'] = True -def mandelbrot(path, width=1200, height=800): - """The classic view of the Mandelbrot set, smoothly coloured.""" +def mandelbrot(path, center=(-0.75, 0.0), span=3.2, limit=200, width=1200, height=800, bands=40): + """The Mandelbrot set around `center`, `span` wide, smoothly coloured: + a deep blue through white to gold, the inside black. `bands` is the + escape count one sweep of the palette takes (a deep zoom cycles it).""" import numpy as np - x = np.linspace(-2.35, 0.85, width) - y = np.linspace(-1.0667, 1.0667, height) + x = np.linspace(center[0] - span / 2, center[0] + span / 2, width) + half = span * height / width / 2 + y = np.linspace(center[1] + half, center[1] - half, height) c = x[None, :] + 1j * y[:, None] z = np.zeros_like(c) count = np.zeros(c.shape) alive = np.ones(c.shape, bool) - limit = 200 for n in range(limit): z[alive] = z[alive] ** 2 + c[alive] escaped = alive & (np.abs(z) > 4) # The smooth (normalised) iteration count, so the bands blend. count[escaped] = n + 1 - np.log2(np.log2(np.abs(z[escaped]))) alive &= ~escaped - t = np.sqrt(np.clip(count / 40, 0, 1)) - # A deep blue through gold to white, the inside black. + if limit > 2 * bands: + t = (count / bands) % 1 # a zoom: the palette repeats down the spirals + t = np.where(t < .5, t * 2, (1 - t) * 2) + else: + t = np.sqrt(np.clip(count / bands, 0, 1)) stops = np.array([[0, 7, 100], [32, 107, 203], [237, 255, 255], [255, 170, 0], [80, 2, 0]], float) pos = np.linspace(0, 1, len(stops)) rgb = np.stack([np.interp(t, pos, stops[:, k]) for k in range(3)], axis=-1) @@ -619,30 +630,31 @@ def mandelbrot(path, width=1200, height=800): def image_setup(s): - """A lone terminal at the project, which holds a picture.""" + """A lone terminal at the project, which holds two pictures: the + Mandelbrot set and a zoom into its seahorse valley.""" mandelbrot(PROJECT / 'mandelbrot.png') + mandelbrot(PROJECT / 'seahorse.png', center=(-0.7453, 0.1127), span=0.012, limit=600, bands=60) shell_setup(s) s.write('/pane/1/exec', 'Del\n') s.wait(lambda: list(s.panes()) == [2], 'the README to close') def image_pane(s): - """ls in a shell; B3 on the PNG's name opens it in a pane.""" + """ls in a shell; B3 on each PNG's name opens it in a pane.""" s.pointer = s.cell_px(40, 8) s.shot(1.0) s.type('ls', lambda typed: at_prompt(s, typed)()) s.keys('\r') - s.wait(lambda: any('mandelbrot.png' in line for line in s.terminal_rows()), 'ls') + s.wait(lambda: any('seahorse.png' in line for line in s.terminal_rows()), 'ls') s.shot(.9) col, row = s.find('mandelbrot.png', 0) - s.click(3, *s.cell_px(col + 5, row), done=lambda: len(s.panes()) == 2, what='the picture', after=2.2) + s.click(3, *s.cell_px(col + 4, row), done=lambda: len(s.panes()) == 2, what='the set', after=2.4) s.shots[-1]['poster'] = True + # Del gives its rows back, so the zoom opens as large. image = next(n for n, kind in s.panes().items() if kind == 'image') - # Petscii, a word typed into the picture's tag, redraws it as a C64's - # character art would. - s.write(f'/pane/{image}/tag', ' Petscii') - s.click(2, *s.tag_word(image, 'Petscii'), done=lambda: 'petscii:on' in s.tag(image), what='petscii', - after=2.6) + s.click(2, *s.tag_word(image, 'Del'), done=lambda: len(s.panes()) == 1, what='Del', after=.6) + col, row = s.find('seahorse.png', 0) + s.click(3, *s.cell_px(col + 4, row), done=lambda: len(s.panes()) == 2, what='the zoom', after=3.0) # The Intel 64 and IA-32 SDM, vol. 2 (2,515 pages), opened where it is. @@ -827,6 +839,15 @@ def record_themes(binary, work): CLIPS = { + 'pdf-navigation': dict( + setup=pdf_setup, run=pdf_navigation, args=pdf_args, + caption='A 2,515-page PDF: page, jump to CPUID, search, step hits.'), + 'image-pane': dict( + setup=image_setup, run=image_pane, args=[PROJECT / 'README'], + caption="Right-click an image's name, even in a shell, to open it."), + 'pdf-tint-fit': dict( + setup=pdf_tint_setup, run=pdf_tint_fit, args=pdf_args, + caption='PdfTint tints the page, PdfFit fits it, a page address jumps.'), 'text-is-the-interface': dict( setup=hero_setup, run=text_is_the_interface, args=[PROJECT / 'README'], caption='Middle-click runs a word; right-click an error opens its line.'), @@ -839,15 +860,6 @@ CLIPS = { 'diff-review': dict( setup=diff_setup, run=diff_review, args=[PROJECT / 'README'], caption='Right-click a diff line to open that line of the file.'), - 'pdf-navigation': dict( - setup=pdf_setup, run=pdf_navigation, args=pdf_args, - caption='A 2,515-page PDF: page, jump to CPUID, search, step hits.'), - 'pdf-tint-fit': dict( - setup=pdf_tint_setup, run=pdf_tint_fit, args=pdf_args, - caption='PdfTint tints the page, PdfFit fits it, a page address jumps.'), - 'image-pane': dict( - setup=image_setup, run=image_pane, args=[PROJECT / 'README'], - caption="Right-click a picture's name to open it; Petscii redraws it."), } |
