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