For simulating terminal output you will have to maintain a line buffer. In the example below I am using the sequence data type of LaTeX3 for this purpose. A minipage of given width and number of lines height is used to mimick the terminal window. If the number of lines in the buffer goes past the height of the minipage, the top line in the buffer is removed.
EDIT:
New command \clearbuf
clears the line buffer. Recommended use before first \scroll
in an animateinline
environment and to simulate clear
(screen) shell command.
EDIT 2:
This new version allows for ''multiline'' text as argument to \scroll
. However, line breaks must be explicitly denoted in the argument using a marker string. The default is §§
which is rarely seen on terminals. But any user defined sequence of letters is possible. User defined marker strings must be passed as optional first argument, enclosed between [
and ]
to \scroll
.
EDIT 3:
Note that macros within the text argument of \scroll
are expanded before being added to the line buffer. The reason is to make macros which are called more than once but change their content between calls to \scroll
, such as the line numbers \i
in the example, work correctly.
Use \noexpand
if you want to defer expansion of macros to the time when the whole line buffer is typeset. This is useful for escaping special characters or for text formatting macros (colour, typeface). See the updated example.
\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}
The main problem with your code is the syntax of the \onslide
commands. You should be writing
\onslide<3->{....}
where ...
is the material to which this declaration applies, e.g.
\onslide<3->{\tau_{n} (CB) &= 0 \\}
instead of \onslide<3->\tau_{n} (CB) &= 0 \\
. That will fix up much of your problem with the display. Then the \pause
after the alignment should be given the next slide number, in this case 7
, by writing
\pause[7]
instead of just \pause
. With these changes each element on your slide will be revealed in order.
\documentclass{beamer}
\begin{document}
\begin{frame}
Let $i\neq j$. Choose
$\{e_1,\dots,e_i,\dots,e_j,\dots,e_n\} \subset \mathbb{C}^n$ to be
set of pair-wise orthogonal unit vectors (i.e.,
$\langle e_k,e_l \rangle = \delta_{kl}$).
\pause
Replace $e_j$ with $ze_i$, where $|z| = 1$, so that
$\{e_1,\dots,e_i,\dots,ze_i,\dots,e_n\}$.
\pause
Note that $B = I + B_0$. Hence,
\begin{align*}
\onslide<3->{\tau_{n} (CB) &= 0 \\}
\onslide<4->{\tau_n(CI) + \tau(CB_0) &= 0 \\}
\onslide<5->{a_{ij} \overline{z} + \overline{a}_{ij} z &= 0 \\}
\onslide<6->{Re(a_{ij} \overline{z}) &= 0}
\end{align*}
\pause[7]
If $z = 1$, then $Re(a_{ij}) = 0$.
\pause
If $z = -i$, then $Re(a_{ij} i) = -Im(a_{ij}) = 0$.
Therefore, $a_{ij} = 0$.
\end{frame}
\end{document}
Best Answer
I will give a solution with LaTeX3 Programming Layer: