Beamer 动画:如何模拟终端输入和输出

Beamer 动画:如何模拟终端输入和输出

我正在准备一些 Unix 培训材料,我想显示一些垂直滚动的命令文本,就像模拟终端中的文本输入一样。我的想法是将框架分成两列,左列显示要输入的命令,右列显示解释。

我还没有看完滚动文本的第一部分(垂直字幕文本)。我试过动画包,它只会覆盖之前的文本。这是我尝试的

\documentclass{beamer}
\usepackage{tikz}
\usepackage{animate}
\begin{document}
  \begin{frame}
    \frametitle{MD5SUM}
     \begin{animateinline}[autoplay,loop]{1}
      cat a
      \newframe
      cat b
      \newframe
      md5sum a
     \end{animateinline}
   \end{frame}
 \end{document}

现在 beamer 有这些覆盖规范,但我认为它们都不适合滚动文本。我不想每次都按回车键来显示下一个命令,只想以指定的速率播放命令序列。

另外,有没有更好的方法来实现这一点?所有动画都将是文本,可能没有图像。

更新:有了 Alexander 的回答,我尝试将它与 Beamer 一起使用,结果好坏参半。

我准备了一个最小示例,其中前一个 animateinline 文本将穿过下一张幻灯片。有人能告诉我,到底发生了什么,我哪里错了吗?

 \documentclass{beamer}
  \usepackage{beamerthemeWarsaw}
  \usepackage{animate}
  \usepackage{expl3}
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %command for simulating terminal in/output
  %\scroll{<width as TeX dim>}{<number of lines>}{terminal text line}
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  \ExplSyntaxOn
  \seq_new:N\g_linebuffer_seq
  \newcommand\scroll[3]{
    \ttfamily
    \seq_gput_right:Nx\g_linebuffer_seq{#3}
    \int_compare:nT{\seq_length:N\g_linebuffer_seq>#2}{
    \seq_gpop_left:NN\g_linebuffer_seq\dummy
    }
    \fbox{\begin{minipage}[t][#2\baselineskip]{#1}
    \seq_map_inline:Nn\g_linebuffer_seq{\mbox{##1}\\}
    \end{minipage}}
    }
  \ExplSyntaxOff

\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Random records}
  How do you randomly select, say 1000 records from a large file?  Use
  the \verb|shuf| command
  \begin{animateinline}[autoplay,loop]{1}
    \scroll{0.8\linewidth}{10}{ cat a}%
    \newframe
     \scroll{0.8\linewidth}{10}{clear}
    \end{animateinline}
%
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Checking for Duplicate Files}
  How do you quickly check whether 2 files are the same? Use the
  \verb|md5sum| command.
  \begin{animateinline}[autoplay,loop]{1}
    \scroll{0.8\linewidth}{8}{\# echo 1 2 3 > a}
    \newframe
    \scroll{0.8\linewidth}{8}{clear}
  \end{animateinline}
\end{frame}
\end{document}

答案1

为了模拟终端输出,您必须维护一个行缓冲区。在下面的示例中,我为此使用了 LaTeX3 的序列数据类型。使用给定宽度和行数高度的迷你页面来模拟终端窗口。如果缓冲区中的行数超出迷你页面的高度,则将删除缓冲区中的顶部行。

编辑: 新命令清除行缓冲区。建议在环境中\clearbuf首先使用并模拟(屏幕)shell 命令。\scrollanimateinlineclear

编辑2: 此新版本允许将“多行”文本作为 的参数\scroll。但是,必须使用标记字符串在参数中明确表示换行符。默认值为 ,§§这在终端上很少见。但任何用户定义的字母序列都是可能的。用户定义的标记字符串必须作为可选的第一个参数传递,括在[]之间\scroll

编辑3: 请注意,的文本参数中的宏\scroll在添加到行缓冲区之前会被展开。这样做的原因是为了让那些被多次调用但在调用之间更改其内容的宏(例如示例中的\scroll行号)正常工作。\i

\noexpand如果您想将宏的扩展推迟到排版整个行缓冲区时使用。这对于转义特殊字符或文本格式化宏(颜色、字体)很有用。请参阅更新的示例。

\documentclass[dvisvgm]{article}
\pagestyle{empty}

\usepackage{courier}
\usepackage{animate}  
\usepackage{expl3}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
%commands for simulating terminal in/output  
%\scroll[<line separator string>]{<width as TeX dim>} 
%                             {<number of lines>}{terminal text line}  
%\clearbuf  %clears line buffer  
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
\ExplSyntaxOn
\seq_new:N\g_linebuffer_seq
\seq_new:N\g_inputline_seq
\newcommand\scroll[4][§§]{
  \seq_set_split:Nnn\g_inputline_seq{#1}{#4}
  \seq_map_inline:Nn\g_inputline_seq{
    \seq_gput_right:Nx\g_linebuffer_seq{##1}
    \int_compare:nT{\seq_count:N\g_linebuffer_seq>#3}{
      \seq_gpop_left:NN\g_linebuffer_seq\dummy
    }
  }
  \fbox{\begin{minipage}[t][#3\baselineskip]{#2}
    \ttfamily
    \seq_map_inline:Nn\g_linebuffer_seq{\mbox{##1}\\}
  \end{minipage}}
}
\newcommand\clearbuf{\seq_gclear:N\g_linebuffer_seq}
\ExplSyntaxOff

\begin{document}  

  \begin{animateinline}[controls,loop]{1}  
      \scroll{0.9\linewidth}{8}{cat a}  
    \newframe 
      \scroll{0.9\linewidth}{8}{cat b} 
    \newframe 
      \scroll{0.9\linewidth}{8}{John§§Linda§§Albert§§Francis}  
    \newframe 
      \scroll{0.9\linewidth}{8}{ln -s a empty.txt}
    \newframe 
      \scroll{0.9\linewidth}{8}{md5sum empty.txt}
    \newframe
      \scroll{0.9\linewidth}{8}{d41d8cd98f00b204e9800998ecf8427e  empty.txt}
    \newframe 
      \scroll{0.9\linewidth}{8}{md5sum b}
    \newframe
      \scroll{0.9\linewidth}{8}{88a1d2cf7920275378bebdf438bae941  b}
    \newframe 
      \scroll{0.9\linewidth}{8}{clear}\clearbuf  
    \newframe 
      \scroll{0.9\linewidth}{8}{}\clearbuf
    \newframe  
    \multiframe{10}{i=1+1}{
       \scroll{0.9\linewidth}{8}{\noexpand\# Line \i}
    }  
    \newframe 
      \scroll{0.9\linewidth}{8}{clear}\clearbuf  
    \newframe 
      \scroll{0.9\linewidth}{8}{}\clearbuf
  \end{animateinline}  

  \begin{animateinline}[controls,loop]{1}  
      \clearbuf\scroll{0.9\linewidth}{8}{cd /usr/bin}
    \newframe  
      \scroll{0.9\linewidth}{8}{echo \noexpand\$PWD} 
    \newframe 
      \scroll{0.9\linewidth}{8}{/usr/bin}
    \newframe
      \scroll{0.9\linewidth}{8}{ls -l md5sum} 
    \newframe 
      \scroll{0.9\linewidth}{8}{% 
        -rwxr-xr-x 1 root root 30172 Dec 14 2010
        \noexpand\bfseries\noexpand\color{red}md5sum
      } 
    \newframe
      \scroll{0.9\linewidth}{8}{clear}\clearbuf
    \newframe 
      \scroll{0.9\linewidth}{8}{}\clearbuf
  \end{animateinline}  

\end{document}

相关内容