Ofey Chan, aka 'ofey404'

Pretending a subtitle is out there...



终端幻灯片程序的价值,以及一个设计

在『玩具』以外,终端幻灯片程序的价值在于,嵌入代码 / Shell Script / 任何系统操作的灵活性。甚至幻灯片本身就是一个脚本,在工作实际发生的那台机器上、那个目录下进行演示。

太长不看版:

没有一个我试用的终端幻灯片程序达到了我心目中的效果,它们本来可以做得更加简洁、小巧而普适。因此我做了一个设计:

这个设计的最大工作量,大概来自于一个『在终端模拟器中运行的终端模拟器』,参考zellij.dev,工作量应当在一万行以下。

终端幻灯片程序有价值吗?

看到 github 上有朋友星了 maaslalani/slides 这个基于终端的幻灯片程序,我也找了几个玩了一下。

这些程序的特点:

那么这类基于终端的幻灯片程序,除了『酷玩具』这一点以外,有没有独特的使用价值呢?

我认为有两点:

  1. 在演示中方便地做『任何通过终端能够做到的事』(基本上等于任何事)。也就是嵌入代码/Shell Script/任何系统操作的灵活性,甚至幻灯片本身就是一个脚本。
  2. 最大限度无视硬件限制,在工作发生的那台机器上、那个目录下进行演示。

回顾一下现存的演示工具:

基于终端的幻灯片程序,肯定是不能做到和全功能的幻灯片一样,支持多种多样的富文本、多媒体材料的,甚至连绘图都有很多困难。这是 TUI 的局限。

在试用的时候,我对这些终端幻灯片程序有过这样一个想象:一边在终端里做工作,一边配上讲解的文字,最后把整个过程录下来成为幻灯片。

这比 Jupyter Notebook 走得更靠近机器一步——Jupyter Notebook 限定嵌入某个语言的代码,而终端幻灯片工具可以使用任何你想要的工具,在任何一台机器上进行演示,甚至就是工作发生的那台机器,只要有一个字符界面。

遗憾的是,没有一个试用的程序在嵌入代码的灵活性上达到了我心目中的要求。maaslalani/slides 似乎不支持交互式命令行。d0c-s4vage/lookatme 似乎是把每一张幻灯片上的代码段放到单独的交互式命令行中执行,无法像 Jupyter Notebook 上一样为所有幻灯片维护一个统一的上下文。

在我心目中,『基于终端的幻灯片工具』可以做得更加简洁、小巧而普适。

因此我设计了一个终端幻灯片工具,并且看了一些材料验证可行性。如果暑假有空,我就把它做出来。

这个设计的简洁性,让它的代码量不会很大。zellij.dev,一个 Rust 实现的 tmux,代码量大约是 3 万行,我计划在它的十分之一代码量之内实现功能。

下面介绍我的设计。

设计

程序是单一的可执行文件,暂且称之为 shellpre

幻灯片文件

幻灯片文件是带有结构化注释的代码文件。以 bash 为例子:

#!/usr/bin/env shellpre

# ## Slide Page 1
# - Point 1
# - Point 2
#
# Some text
echo "Embedded in page 1"
# ---

# ## Slide Page 2
# - Unordered list
# - Unordered list
#
# Text
echo "Page 2"
# ---

代码中最外层的注释会被 shellpre 按照 Markdown 的语法进行解析。

代码可以是任何支持解释执行的语言。

shellpre 所做的事:

界面

界面使用类似 extrawurst/gitui 的设计,如果用 rust 编写的话,也可以直接使用 gitui 的包。

 ┌─────────────────────────────────────────────────────────┐
 │   |Shortcut indicators...|     |     |                  │
 │   ┌────────────────────────────────────────────────┐    │
 │   │                                                │    │
 │   │  # Slide Title                                 │    │
 │   │                                                │    │
 │   │  - Point 1                                     │    │
 │   │                                                │    │
 │   │  - Point 2                                     │    │
 │   │                                                │    │
 │   │                                                │    │
 │   │  Some text                                     │    │
 │   │                                                │    │
 │   │  ```                                           │    │
 │   │  echo "Embedded in page 1"                     │    │
 │   │  ```                                           │    │
 │   │                                                │    │
 │   └────────────────────────────────────────────────┘    │
 │                                                         │
 │   ┌────────────────────────────────────────────────┐    │
 │   │  $ echo "Embedded in page 1"                   │    │
 │   │  Embedded in page 1                            │    │
 │   │                                                │    │
 │   │  $ # Type some new command                     │    │
 │   │                                                │    │
 │   └────────────────────────────────────────────────┘    │
 │                                           Page 1/2      │
 └─────────────────────────────────────────────────────────┘

演讲时,把每一页所嵌入的代码发送到页面下方的终端,演讲者可以选择运行或者不运行它,或者自动运行每一页嵌入的代码,就像 Jupyter Notebook 一样。

使用者同样也可以聚焦到下半部分的终端,然后做他想做的任何事情,比如 cat 一些数据文件看一看,或者用 vim 编辑一些文件,或者其他有助于演示的命令。

下半部分的终端,在聚焦的时候应该可以接收尽可能多的键,最好和 tmux 一样,只有一个前缀键可以用于退出聚焦。这样就可以把它当作一个完整的终端模拟器来使用,在里面使用 vim 等工具。这实际上就是写一个在终端模拟器中运行的终端模拟器。

为了估计工作量,我参考了 zellij.dev,一个 Rust 实现的 tmux,代码量大约是 3 万行。希望能在它 1/3 的规模内完成这个终端模拟器。

导出

导出和分享是幻灯片的自然需要。我们可以简单地把注释和代码块换个位置,把幻灯片输出成 Markdown 格式的文本。之后就有 pandoc 等 Markdown 幻灯片工具来帮我们完成导出了。

模块结构

我现在还没有着手开始写代码。目前确定的事情是,需要写一个类似 tmux 的终端模拟器。这大概会是一个不错的玩具。

模块结构大概会是这样:

   ┌──────────────────┐
   │                  │
   │      Input       │
   │                  │
   └───────┬──────────┘
           │
           │
   ┌───────▼──────────┐
   │Keystroke Handler │
   │                  │
   │UI, window manager│
   └───────┬──────────┘
           │
           ├────────────────────────┐
           │                        │
   ┌───────▼──────────┐     ┌───────▼────────┐
   │                  │     │                │
   │Terminal Emulator │     │  Slide Render  │
   │                  │     │                │
   └───────┬──────────┘     └────────────────┘
           │
           │
   ┌───────▼──────────┐
   │                  │
   │Shell(bash, zsh)  │
   │                  │
   └──────────────────┘
July 19, 2021

[Back to top]

* Style sheet refers to Dr. Brian Robert Callahan