% \begin{meta-comment} %% %% slowbox package -- skipping of slow boxes %% Copyright (c) 2003, 2020 Mark Wooding %% %% This file is part of the `mdwtools' LaTeX package collection. %% %% `mdwtools' is free software: you can redistribute it and/or modify it %% under the terms of the GNU General Public License as published by the %% Free Software Foundation; either version 2 of the License, or (at your %% option) any later version. %% %% `mdwtools' is distributed in the hope that it will be useful, but %% WITHOUT ANY WARRANTY; without even the implied warranty of %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %% General Public License for more details. %% %% You should have received a copy of the GNU General Public License %% along with `mdwtools'. If not, write to the Free Software Foundation, %% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. %% % \end{meta-comment} % % \begin{meta-comment} %<+package>\NeedsTeXFormat{LaTeX2e} %<+package>\ProvidesPackage{slowbox} %<+package> [2020/09/06 1.14.0 Skipping of slow boxes] % \end{meta-comment} % % \CheckSum{223} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} %% % % \begin{meta-comment} % %<*driver> \input{mdwtools} \PassOptionsToPackage{hide}{slowbox} \describespackage{slowbox} \newcommand\opt[1]{\textsf{#1}} \def\*{\hspace{0pt plus 0.1pt}\ignorespaces} \mdwdoc % % % \end{meta-comment} % %^^A------------------------------------------------------------------------- % \section{User guide} % % The problem is that some things, e.g., diagrams, can take a while to % typeset, and aren't particularly interesting as far as the global document % layout is concerned. Once you've got a diagram right, the only thing that % matters as far as general previewing is concerned is its size. % % The solution is \package{slowbox}. Put things you're usually not % interested in seeing in a \env{slowbox} environment. Then they get % replaced by a frame saying that there's meant to be something there, and % that's it. % % There are two modes, chosen by package options: \opt{show} and \opt{hide}. % The default is \opt{show} mode, because I had to pick one. In \opt{show} % mode, everything happens normally; in \opt{hide} mode, slow boxes are % replaced by frames. In order for the package to know the sizes of all of % your boxes, you must first run through once in \opt{show} mode. % Thereafter, all should be well. % % \DescribeEnv{slowbox} % In \opt{show} mode, the \env{slowbox} environment typesets its contents in % LR-mode (for \TeX nicians, restricted horizontal mode).\footnote{^^A % Vertical mode causes all sorts of pain, and makes things way too wide. % Horizontal mode seems a good `standard currency' for \LaTeX\ things like % diagrams.} ^^A % In \opt{hide} mode, the boxes are replaced by frames, and \TeX\ will skip % over the contents of the environment at high speed, ignoring it % completely. % % The \env{slowbox} environment needs an argument, a \emph{tag} which is used % to identify this box. This is needed because otherwise the package has no % way of deciding that you've inserted some new box and need to shunt % everything about. So the full syntax is % \syntax{"\\begin{slowbox}{""}" \ldots "\\end{slowbox}"}. % Tags can be any piece of text. If you include control sequences in the % tag, then they get expanded. That might be what you want. % % \DescribeEnv{slowbox$*$} % Adding new slow boxes is best done using the starred version of the % environment. Stuff in a \env{slowbox$*$} environment is always typset in % \opt{show} mode, regardless of the global mode setting. The right thing to % do is wrap your new stuff in a \env{slowbox$*$} while you're writing it. % Then remove the \env{$*$} and it will turn into a frame. The % \env{slowbox$*$} environment takes a tag name, just like \env{slowbox} % does. % % However, if \package{slowbox} sees a slow box \ it's not noticed % before, it always typesets the box contents, and saves the measurements for % later. % % \begin{demo}{Slow boxes} %\newcommand{\pic} % {\parbox[t]{20mm} % {Just pretend that there's a picture % here that would take aaaages to draw.}} %-- %\begin{slowbox*}{show} % \pic %\end{slowbox*} %-- %\begin{slowbox}{hide} % \pic %\end{slowbox} %-- % \end{demo} % % \DescribeMacro\slowboxbegin % \DescribeMacro\slowboxend % It's useful to define your own commands environments which create slow % boxes. Often, though, what happens is that you want to put some stuff % \emph{inside} the slow box, but that doesn't work properly. What you must % do instead is say something like %\begin{verbatim} % \newenvironment{splunt}[1] % {...\slowboxbegin{#1}{...\startsplunt...}} % {\slowboxend{...\finishsplunt...}...} %\end{verbatim} % That is, \syntax{"\\slowboxbegin{""}{""}"} starts a slow box, % beginning with \ if we're in \opt{show} mode; and % \syntax{"\\slowboxend{""}"} finishes it, ending with \. % % The |\slowboxbegin| command has a |*|-variant, which causes the box to be % typeset regardless of the current mode setting. % % \DescribeMacro\newslowboxenv % Plumbing all of this together is rather tedious, so there's also a % command for building slow box environments. Say % \syntax{"\\newslowboxenv{""}"\* "[""]"\*"[""]"\* % "{""}"\* "{""}"\* "{""}"\* % "{""}"}. This creates a new environment (just like with % |\newenvironment|, taking \ arguments, maybe with the first one % optional and defaulting to \). The contents are put in a slow box % with \ on the front and \ on the end. Before the box % is begun, \ is performed, and \ is done % afterwards. The environments so created have \env{$*$}-variants which % ignore the current mode, just like \env{slowbox$*$}. They also gather an % additional \ argument, which you don't have to bother with. % % \DescribeMacro\doslowbox % Finally, for commands, there's \syntax{"\\doslowbox{""}"\* % "{""}"}. This typesets \ in a slow box with the given tag. % There's a |*|-variant, of course. % % \DescribeMacro\slowboxshow % \DescribeMacro\slowboxhide % \DescribeMacro\ifslowboxshow % The declarations |\showboxshow| and |\slowboxhide| switch between the % \opt{show} and \opt{hide} modes. They obey standard scoping rules. % They're probably not very useful. They twiddle the |\ifslowboxshow| macro, % which is an old-fashioned Plain \TeX\ switch. If you're the sort of person % who uses \package{ifthen}, then you can test |\boolean{slowboxshow}|. % %^^A------------------------------------------------------------------------- % \implementation % % \section{Implementation of \package{slowbox}} % % \begin{macrocode} %<*package> % \end{macrocode} % % \subsection{The mode switch} % % \begin{macro}{\ifslowboxshow} % \begin{macro}{\slowboxshow} % \begin{macro}{\slowboxhide} % The |\if@slowboxshow| switch remembers which mode we're in. The % |\slowboxshow| and |\slowboxhide| macros flip the switch. It's really % easy. The |\relax|es are to annoy people who say |\global\showboxshow|. % \begin{macrocode} \def\slowboxshow{\relax\let\ifslowboxshow\iftrue} \def\slowboxhide{\relax\let\ifslowboxshow\iffalse} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Dependencies} % % The skipping-over-stuff-at-high-speed is done by my \package{sverb} % package. % \begin{macrocode} \RequirePackage{sverb} % \end{macrocode} % % \subsection{Options} % % Oh, this is obvious. % \begin{macrocode} \DeclareOption{show}{\slowboxshow} \DeclareOption{hide}{\slowboxhide} \ExecuteOptions{show} \ProcessOptions % \end{macrocode} % % \subsection{Remembering stuff} % % \begin{macro}{\sb@def} % Box dimensions are recorded in the |.aux| file using % \syntax{"\\sb@def{""}"\* "{""}"\* "{""}"\* % "{""}"}. This turns into a definition of a strange control % sequence. % \begin{macrocode} \def\sb@def#1#2#3#4% {\expandafter\gdef\csname sb@box:#1\endcsname{{#2}{#3}{#4}}} % \end{macrocode} % \end{macro} % % \subsection{The actual work} % % \begin{macro}{\sb@begin} % This is where most of the intelligence is. % \syntax{"\\sb@begin{""}{""}"} starts a slow box, putting % \ at the start if we're in \opt{show} mode. It doesn't ignore stuff % -- though it sets |\sb@ignore| to be |\relax| in \opt{show} mode and % |\ignore| in \opt{hide} mode. It also sets |\sb@end| correctly, so that % \syntax{"\\sb@end{""}"} ends the current box, putting \ in % it. % % Disappointingly, perhaps, this is in fact just a dispatcher to the right % implementation. % \begin{macrocode} \def\sb@begin{% \ifslowboxshow\expandafter\sb@begin@show% \else\expandafter\sb@begin@hide\fi% } % \end{macrocode} % \end{macro} % % \begin{macro}{\sb@begin@show} % Now we have the implementation for \opt{show} mode. This is sometimes % called directly, by |*|-variants. Needs to be |\long| because \ % might contain embedded vmode-material which could legitimately have |\par| % tokens in. % \begin{macrocode} \long\def\sb@begin@show#1#2{% \begingroup% \def\sb@end##1{% ##1% \color@endgroup% \egroup% \immediate\write\@auxout% {\string\sb@def{#1}{\the\wd\z@}{\the\ht\z@}{\the\dp\z@}}% \leavevmode\box\z@% \endgroup% }% \let\sb@ignore\relax% \setbox\z@\hbox\bgroup\color@begingroup#2% } % \end{macrocode} % \end{macro} % % \begin{macro}{\sb@begin@hide} % Now for something a bit stranger. If we're in \opt{hide} mode, we need to % find out whether we've saved information about this box before. We pass % the \emph{control sequence} containing the box dimensions to another % macro. Needs to be |\long| to collect the \ argument. % \begin{macrocode} \long\def\sb@begin@hide#1#2{% \begingroup% \def\sb@end##1{\endgroup}% \let\sb@ignore\ignore% \expandafter\sb@hidden\csname sb@box:#1\endcsname{#1}{#2}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\sb@hidden} % We're given the control token and the tag name. If the control sequence is % like |\relax| then |\csname| must have invented it and we should typeset it % anyway in order to measure it. Otherwise we put the right stuff in a % frame. Don't forget to write out the box dimensions to the new aux file! % \begin{macrocode} \def\sb@hidden#1#2#3{% \ifx#1\relax\def\next@{\endgroup\sb@begin@show{#2}{#3}}% \else\edef\next@{\noexpand\sb@hidden@i#1{#2}}\fi% \next@% } \def\sb@hidden@i#1#2#3#4{% \frameonly{#1}{#2}{#3}{Omitted \texttt{#4}}% \immediate\write\@auxout{\string\sb@def{#4}{#1}{#2}{#3}}% } % \end{macrocode} % \end{macro} % % \subsection{Stuff in frames} % % \begin{macro}{\frameonly} % \syntax{"\\frameonly{""}{""}{""}{""}"} % typesets \ in a frame with the given dimensions. This is a bit % tricky -- we want the \ in the middle of the box, but the box's % reference point is somewhere else. We start with a |\vcenter| of the right % height, and then nudge it into position later. % % In case the label is just too big, put shrinky glue all round. It'll look % horrible, but at least it won't mess everything up. % \begin{macrocode} \def\frameonly#1#2#3#4{% \dimen\tw@#2\advance\dimen\tw@#3\advance\dimen\tw@-.8\p@% \setbox\z@\hbox{$\vcenter{\hrule\@height\dimen\tw@\@depth\z@}$}% \dimen@#1% \advance\dimen@-.8\p@% \setbox\z@\vbox{% \hrule\vss% \hb@xt@\dimen@{% \vrule\@height\ht\z@\@depth\dp\z@\hss% \advance\dimen@-2em% \parbox\dimen@{\centering#4}% \hss\vrule}% \vss\hrule% }% \dimen@#3\advance\dimen@-\dp\z@% \setbox\z@\hbox{\lower\dimen@\box\z@}% \leavevmode\box\z@% } % \end{macrocode} % \end{macro} % % \subsection{User commands} % % \begin{macro}{\slowboxbegin} % \begin{macro}{\slowboxend} % This is just a matter of using the machinery we've built already. % \begin{macrocode} \def\slowboxbegin{\@ifstar{\sb@go\sb@begin}{\sb@go\sb@begin@show}} \long\def\sb@go#1#2#3{#1{#2}{#3}\sb@ignore} \def\slowboxend{\sb@end} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\doslowbox} % And this too. % \begin{macrocode} \def\doslowbox{\@ifstar{\sb@do\sb@begin}{\sb@do\sb@begin@show}} \long\def\sb@do#1#2#3{#1{#2}{#3}\sb@end} % \end{macrocode} % \end{macro} % % \begin{macro}{\newslowboxenv} % Something a bit more interesting now. Gathering the optional arguments for % |\newenvironment| is a bit tedious, but we do it anyway. Picking up the % arguments for the environment is a bit tricky -- they come in the wrong % order, unfortunately. % \begin{macrocode} \def\newslowboxenv#1{\@ifnextchar[{\sb@nenv@i{#1}}{\sb@nenv@do{#1}{}}} \def\sb@nenv@i#1[#2]{% \@ifnextchar[{\sb@nenv@ii{#1}{[{#2}]}}{\sb@nenv@do{#1}{[{#2}]}}% } \def\sb@nenv@ii#1#2[#3]{\sb@nenv@do{#1}{#2[{#2}]}} \long\def\sb@nenv@do#1#2#3#4#5#6{% \newenvironment{#1}#2{#3\sb@env\sb@begin{#4}}{\sb@end{#5}#6}% \newenvironment{#1*}#2{#3\sb@env\sb@begin@show{#4}}{\sb@end{#5}#6}% } \def\sb@env#1#2#3{#1{#3}{#2}\sb@ignore} % \end{macrocode} % \end{macro} % % \begin{environment}{slowbox} % And the \env{slowbox} is built using the above equipment. % \begin{macrocode} \newslowboxenv{slowbox}{}{}{}{} % \end{macrocode} % \end{environment} % % \begin{macrocode} % % \end{macrocode} % % \Finale \endinput