slowbox.dtx: Reword `\newslowboxenv' description for better line breaks.
[mdwtools] / slowbox.dtx
CommitLineData
281c40ee 1% \begin{meta-comment}
2%
43039ee9 3% $Id: slowbox.dtx,v 1.2 2003/09/06 13:08:16 mdw Exp $
281c40ee 4%
5% Cop-out for slow things
6%
7% (c) 2003 Mark Wooding
8%
281c40ee 9% \end{meta-comment}
10%
11% \begin{meta-comment} <general public licence>
12%%
13%% slowbox package -- skipping of slow boxes
14%% Copyright (c) 2003 Mark Wooding
15%%
16%% This program is free software; you can redistribute it and/or modify
17%% it under the terms of the GNU General Public License as published by
18%% the Free Software Foundation; either version 2 of the License, or
19%% (at your option) any later version.
e8e9e5d8 20%%
281c40ee 21%% This program is distributed in the hope that it will be useful,
22%% but WITHOUT ANY WARRANTY; without even the implied warranty of
23%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24%% GNU General Public License for more details.
e8e9e5d8 25%%
281c40ee 26%% You should have received a copy of the GNU General Public License
27%% along with this program; if not, write to the Free Software Foundation,
28%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29% \end{meta-comment}
30%
31% \begin{meta-comment} <Package preambles>
32%<+package>\NeedsTeXFormat{LaTeX2e}
33%<+package>\ProvidesPackage{slowbox}
34%<+package> [2003/08/27 1.0 skipping of slow boxes]
35% \end{meta-comment}
36%
43039ee9 37% \CheckSum{222}
281c40ee 38%% \CharacterTable
39%% {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
40%% 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
41%% Digits \0\1\2\3\4\5\6\7\8\9
42%% Exclamation \! Double quote \" Hash (number) \#
43%% Dollar \$ Percent \% Ampersand \&
44%% Acute accent \' Left paren \( Right paren \)
45%% Asterisk \* Plus \+ Comma \,
46%% Minus \- Point \. Solidus \/
47%% Colon \: Semicolon \; Less than \<
48%% Equals \= Greater than \> Question mark \?
49%% Commercial at \@ Left bracket \[ Backslash \\
50%% Right bracket \] Circumflex \^ Underscore \_
51%% Grave accent \` Left brace \{ Vertical bar \|
52%% Right brace \} Tilde \~}
53%%
54%
55% \begin{meta-comment}
56%
57%<*driver>
58\input{mdwtools}
59\describespackage{slowbox}
60\newcommand\opt[1]{\textsf{#1}}
281c40ee 61\def\*{\hspace{0pt plus 0.1pt}\ignorespaces}
62\mdwdoc
63%</driver>
64%
65% \end{meta-comment}
66%
67%^^A-------------------------------------------------------------------------
68% \section{User guide}
69%
70% The problem is that some things, e.g., diagrams, can take a while to
71% typeset, and aren't particularly interesting as far as the global document
72% layout is concerned. Once you've got a diagram right, the only thing that
73% matters as far as general previewing is concerned is its size.
74%
75% The solution is \package{slowbox}. Put things you're usually not
76% interested in seeing in a \env{slowbox} environment. Then they get
77% replaced by a frame saying that there's meant to be something there, and
78% that's it.
79%
80% There are two modes, chosen by package options: \opt{show} and \opt{hide}.
81% The default is \opt{show} mode, because I had to pick one. In \opt{show}
82% mode, everything happens normally; in \opt{hide} mode, slow boxes are
83% replaced by frames. In order for the package to know the sizes of all of
84% your boxes, you must first run through once in \opt{show} mode.
e8e9e5d8 85% Thereafter, all should be well.
281c40ee 86%
87% \DescribeEnv{slowbox}
88% In \opt{show} mode, the \env{slowbox} environment typesets its contents in
89% LR-mode (for \TeX nicians, restricted horizontal mode).\footnote{^^A
90% Vertical mode causes all sorts of pain, and makes things way too wide.
91% Horizontal mode seems a good `standard currency' for \LaTeX\ things like
92% diagrams.} ^^A
93% In \opt{hide} mode, the boxes are replaced by frames, and \TeX\ will skip
94% over the contents of the environment at high speed, ignoring it
95% completely.
96%
97% The \env{slowbox} environment needs an argument, a \emph{tag} which is used
98% to identify this box. This is needed because otherwise the package has no
99% way of deciding that you've inserted some new box and need to shunt
100% everything about. So the full syntax is
101% \syntax{"\\begin{slowbox}{"<tag>"}" \ldots "\\end{slowbox}"}.
102% Tags can be any piece of text. If you include control sequences in the
103% tag, then they get expanded. That might be what you want.
104%
105% \DescribeEnv{slowbox$*$}
106% Adding new slow boxes is best done using the starred version of the
107% environment. Stuff in a \env{slowbox$*$} environment is always typset in
108% \opt{show} mode, regardless of the global mode setting. The right thing to
109% do is wrap your new stuff in a \env{slowbox$*$} while you're writing it.
110% Then remove the \env{$*$} and it will turn into a frame. The
111% \env{slowbox$*$} environment takes a tag name, just like \env{slowbox}
112% does.
113%
114% \DescribeMacro\slowboxbegin
115% \DescribeMacro\slowboxend
116% It's useful to define your own commands environments which create slow
117% boxes. Often, though, what happens is that you want to put some stuff
118% \emph{inside} the slow box, but that doesn't work properly. What you must
119% do instead is say something like
456186fc 120%\begin{verbatim}
281c40ee 121% \newenvironment{splunt}[1]
122% {...\slowboxbegin{#1}{...\startsplunt...}}
123% {\slowboxend{...\finishsplunt...}...}
456186fc 124%\end{verbatim}
f3d67f57 125% That is, \syntax{"\\slowboxbegin{"<tag>"}{"<stuff>"}"} starts a slow box,
d00a940b
MW
126% beginning with \<stuff> if we're in \opt{show} mode; and
127% \syntax{"\\slowboxend{"<stuff>"}"} finishes it, ending with \<stuff>.
281c40ee 128%
129% The |\slowboxbegin| command has a |*|-variant, which causes the box to be
130% typeset regardless of the current mode setting.
131%
132% \DescribeMacro\newslowboxenv
239eeba9
MW
133% Plumbing all of this together is rather tedious, so there's also a
134% command for building slow box environments. Say
135% \syntax{"\\newslowboxenv{"<env-name>"}"\* "["<n-args>"]"\*"["<default>"]"\*
281c40ee 136% "{"<before-text>"}"\* "{"<start-text>"}"\* "{"<end-text>"}"\*
137% "{"<after-text>"}"}. This creates a new environment (just like with
d66aad8b
MW
138% |\newenvironment|, taking \<n-args> arguments, maybe with the first one
139% optional and defaulting to \<default>). The contents are put in a slow box
140% with \<start-text> on the front and \<end-text> on the end. Before the box
141% is begun, \<before-text> is performed, and \<after-text> is done
142% afterwards. The environments so created have \env{$*$}-variants which
143% ignore the current mode, just like \env{slowbox$*$}. They also gather an
144% additional \<tag> argument, which you don't have to bother with.
281c40ee 145%
146% \DescribeMacro\doslowbox
147% Finally, for commands, there's \syntax{"\\doslowbox{"<tag>"}"\*
148% "{"<stuff>"}"}. This typesets \<stuff> in a slow box with the given tag.
149% There's a |*|-variant, of course.
150%
151% \DescribeMacro\slowboxshow
152% \DescribeMacro\slowboxhide
153% \DescribeMacro\ifslowboxshow
154% The declarations |\showboxshow| and |\slowboxhide| switch between the
155% \opt{show} and \opt{hide} modes. They obey standard scoping rules.
156% They're probably not very useful. They twiddle the |\ifslowboxshow| macro,
157% which is an old-fashioned Plain \TeX\ switch. If you're the sort of person
158% who uses \package{ifthen}, then you can test |\boolean{slowboxshow}|.
159%
160%^^A-------------------------------------------------------------------------
161% \implementation
162%
163% \section{Implementation of \package{slowbox}}
164%
165% \begin{macrocode}
166%<*package>
167% \end{macrocode}
168%
169% \subsection{The mode switch}
170%
171% \begin{macro}{\ifslowboxshow}
172% \begin{macro}{\slowboxshow}
173% \begin{macro}{\slowboxhide}
174% The |\if@slowboxshow| switch remembers which mode we're in. The
175% |\slowboxshow| and |\slowboxhide| macros flip the switch. It's really
176% easy. The |\relax|es are to annoy people who say |\global\showboxshow|.
177% \begin{macrocode}
178\def\slowboxshow{\relax\let\ifslowboxshow\iftrue}
179\def\slowboxhide{\relax\let\ifslowboxshow\iffalse}
180% \end{macrocode}
181% \end{macro}
182% \end{macro}
183% \end{macro}
184%
185% \subsection{Dependencies}
186%
187% The skipping-over-stuff-at-high-speed is done by my \package{sverb}
188% package.
189% \begin{macrocode}
190\RequirePackage{sverb}
191% \end{macrocode}
192%
193% \subsection{Options}
194%
195% Oh, this is obvious.
196% \begin{macrocode}
197\DeclareOption{show}{\slowboxshow}
198\DeclareOption{hide}{\slowboxhide}
199\ExecuteOptions{show}
200\ProcessOptions
201% \end{macrocode}
202%
203% \subsection{Remembering stuff}
204%
205% \begin{macro}{\sb@def}
206% Box dimensions are recorded in the |.aux| file using
207% \syntax{"\\sb@def{"<tag>"}"\* "{"<width>"}"\* "{"<height>"}"\*
208% "{"<depth>"}"}. This turns into a definition of a strange control
209% sequence.
210% \begin{macrocode}
211\def\sb@def#1#2#3#4%
212 {\expandafter\gdef\csname sb@box:#1\endcsname{{#2}{#3}{#4}}}
213% \end{macrocode}
214% \end{macro}
215%
216% \subsection{The actual work}
217%
218% \begin{macro}{\sb@begin}
219% This is where most of the intelligence is.
220% \syntax{"\\sb@begin{"<tag>"}{"<stuff>"}"} starts a slow box, putting
221% \<stuff> at the start if we're in \opt{show} mode. It doesn't ignore stuff
222% -- though it sets |\sb@ignore| to be |\relax| in \opt{show} mode and
223% |\ignore| in \opt{hide} mode. It also sets |\sb@end| correctly, so that
224% \syntax{"\\sb@end{"<stuff>"}"} ends the current box, putting \<stuff> in
225% it.
226%
227% Disappointingly, perhaps, this is in fact just a dispatcher to the right
228% implementation.
229% \begin{macrocode}
230\def\sb@begin{%
231 \ifslowboxshow\expandafter\sb@begin@show%
232 \else\expandafter\sb@begin@hide\fi%
233}
234% \end{macrocode}
235% \end{macro}
236%
237% \begin{macro}{\sb@begin@show}
238% Now we have the implementation for \opt{show} mode. This is sometimes
239% called directly, by |*|-variants. Needs to be |\long| because \<stuff>
240% might contain embedded vmode-material which could legitimately have |\par|
241% tokens in.
242% \begin{macrocode}
243\long\def\sb@begin@show#1#2{%
244 \begingroup%
245 \def\sb@end##1{%
246 ##1%
247 \color@endgroup%
248 \egroup%
249 \immediate\write\@auxout%
250 {\string\sb@def{#1}{\the\wd\z@}{\the\ht\z@}{\the\dp\z@}}%
251 \leavevmode\box\z@%
252 \endgroup%
253 }%
254 \let\sb@ignore\relax%
255 \setbox\z@\hbox\bgroup\color@begingroup#2%
256}
257% \end{macrocode}
258% \end{macro}
259%
260% \begin{macro}{\sb@begin@hide}
261% Now for something a bit stranger. If we're in \opt{hide} mode, we need to
262% find out whether we've saved information about this box before. We pass
263% the \emph{control sequence} containing the box dimensions to another
264% macro. Needs to be |\long| to collect the \<stuff> argument.
265% \begin{macrocode}
266\long\def\sb@begin@hide#1#2{%
267 \begingroup%
268 \def\sb@end##1{\endgroup}%
269 \let\sb@ignore\ignore%
270 \expandafter\sb@hidden\csname sb@box:#1\endcsname{#1}%
271}
272% \end{macrocode}
273% \end{macro}
274%
275% \begin{macro}{\sb@hidden}
276% We're given the control token and the tag name. If the control sequence is
277% like |\relax| then |\csname| must have invented it and we just have to make
278% something up. Otherwise we put the right stuff in a frame. Don't forget
279% to write out the box dimensions to the new aux file!
280% \begin{macrocode}
281\def\sb@hidden#1#2{%
282 \ifx#1\relax\fbox{Unknown slow box \texttt{#2}!}%
283 \else\edef\next@{\noexpand\sb@hidden@i#1{#2}}\expandafter\next@\fi%
284}
285\def\sb@hidden@i#1#2#3#4{%
286 \frameonly{#1}{#2}{#3}{Omitted \texttt{#4}}%
e8e9e5d8 287 \immediate\write\@auxout{\string\sb@def{#4}{#1}{#2}{#3}}%
281c40ee 288}
289% \end{macrocode}
290% \end{macro}
291%
292% \subsection{Stuff in frames}
293%
294% \begin{macro}{\frameonly}
295% \syntax{"\\frameonly{"<width>"}{"<height>"}{"<depth>"}{"<stuff>"}"}
296% typesets \<stuff> in a frame with the given dimensions. This is a bit
297% tricky -- we want the \<stuff> in the middle of the box, but the box's
298% reference point is somewhere else. We start with a |\vcenter| of the right
299% height, and then nudge it into position later.
300%
301% In case the label is just too big, put shrinky glue all round. It'll look
302% horrible, but at least it won't mess everything up.
303% \begin{macrocode}
304\def\frameonly#1#2#3#4{%
305 \dimen\tw@#2\advance\dimen\tw@#3\advance\dimen\tw@-.8\p@%
306 \setbox\z@\hbox{$\vcenter{\hrule\@height\dimen\tw@\@depth\z@}$}%
307 \dimen@#1%
308 \advance\dimen@-.8\p@%
309 \setbox\z@\vbox{%
310 \hrule\vss%
311 \hb@xt@\dimen@{%
312 \vrule\@height\ht\z@\@depth\dp\z@\hss%
313 \advance\dimen@-2em%
314 \parbox\dimen@{\centering#4}%
315 \hss\vrule}%
316 \vss\hrule%
317 }%
318 \dimen@#3\advance\dimen@-\dp\z@%
319 \setbox\z@\hbox{\lower\dimen@\box\z@}%
e8e9e5d8 320 \leavevmode\box\z@%
281c40ee 321}
322% \end{macrocode}
323% \end{macro}
324%
325% \subsection{User commands}
326%
327% \begin{macro}{\slowboxbegin}
328% \begin{macro}{\slowboxend}
329% This is just a matter of using the machinery we've built already.
330% \begin{macrocode}
331\def\slowboxbegin{\@ifstar{\sb@go\sb@begin}{\sb@go\sb@begin@show}}
332\long\def\sb@go#1#2#3{#1{#2}{#3}\sb@ignore}
333\def\slowboxend{\sb@end}
334% \end{macrocode}
335% \end{macro}
336% \end{macro}
337%
338% \begin{macro}{\doslowbox}
339% And this too.
340% \begin{macrocode}
341\def\doslowbox{\@ifstar{\sb@do\sb@begin}{\sb@do\sb@begin@show}}
342\long\def\sb@do#1#2#3{#1{#2}{#3}\sb@end}
343% \end{macrocode}
344% \end{macro}
345%
346% \begin{macro}{\newslowboxenv}
347% Something a bit more interesting now. Gathering the optional arguments for
348% |\newenvironment| is a bit tedious, but we do it anyway. Picking up the
349% arguments for the environment is a bit tricky -- they come in the wrong
350% order, unfortunately.
351% \begin{macrocode}
352\def\newslowboxenv#1{\@ifnextchar[{\sb@nenv@i{#1}}{\sb@nenv@do{#1}{}}}
353\def\sb@nenv@i#1[#2]{%
354 \@ifnextchar[{\sb@nenv@ii{#1}{[{#2}]}}{\sb@nenv@do{#1}{[{#2}]}}%
355}
356\def\sb@nenv@ii#1#2[#3]{\sb@nenv@do{#1}{#2[{#2}]}}
357\long\def\sb@nenv@do#1#2#3#4#5#6{%
358 \newenvironment{#1}#2{#3\sb@env\sb@begin{#4}}{\sb@end{#5}#6}%
359 \newenvironment{#1*}#2{#3\sb@env\sb@begin@show{#4}}{\sb@end{#5}#6}%
360}
361\def\sb@env#1#2#3{#1{#3}{#2}\sb@ignore}
362% \end{macrocode}
363% \end{macro}
364%
365% \begin{environment}{slowbox}
366% And the \env{slowbox} is built using the above equipment.
367% \begin{macrocode}
368\newslowboxenv{slowbox}{}{}{}{}
369% \end{macrocode}
370% \end{environment}
371%
372% \begin{macrocode}
373%</package>
374% \end{macrocode}
375%
376% \Finale
e8e9e5d8 377\endinput