summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/verbatimbox/verbatimbox.tex
blob: 6ae49988981cde7623e9eaa0b116e8f07000ff93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
\documentclass{article}
% Copyright 2013 Steven B. Segletes
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Steven B. Segletes.
%
\parskip 1em
\parindent 0em
\usepackage{verbatimbox}
\usepackage{etoolbox}
\usepackage{color}
\makeatletter
\preto{\@verbatim}{\topsep=0pt \partopsep=0pt }
\makeatother

\newcommand\rl{\rule{1em}{0in}}
\def\vbx{\textsf{verbatimbox}}
\let\vb\verb
\def\bs{{\ttfamily\char'134}}
\reversemarginpar
\marginparwidth 1.5in
\newcommand\margcmd[1]{\marginpar{\hfill\ttfamily\char'134#1}}
\newcommand\margenv[1]{\marginpar{\hfill\ttfamily#1}}

\begin{document}
\begin{myverbbox}{\bgn}\begin\end{myverbbox}
\begin{myverbbox}{\edng}\end\end{myverbbox}
\begin{myverbbox}{\vrbox}verbbox\end{myverbbox}
\begin{myverbbox}{\vrnobox}verbnobox\end{myverbbox}
\begin{myverbbox}{\myvrbox}myverbbox\end{myverbbox}
\begin{myverbbox}{\ovrbox}origverbbox\end{myverbbox}
\begin{myverbbox}{\vbenv}\begin{verbbox}\end{myverbbox}
\begin{myverbbox}{\evbenv}\end{verbbox}\end{myverbbox}
\begin{myverbbox}{\myvb}\begin{myverbbox}\end{myverbbox}
\begin{myverbbox}{\emyvb}end{myverbbox}\end{myverbbox}
\begin{myverbbox}{\vbfbox}\verbfilebox\end{myverbbox}
\begin{myverbbox}{\vbfnobox}\verbfilenobox\end{myverbbox}
\begin{myverbbox}{\tvb}\theverbbox\end{myverbbox}
\begin{myverbbox}{\avb}\addvbuffer\end{myverbbox}
\begin{myverbbox}{\bts}\boxtopsep\end{myverbbox}
\begin{myverbbox}{\bbs}\boxbottomsep\end{myverbbox}
\begin{myverbbox}{\eq} = \end{myverbbox}
\begin{myverbbox}{\vln}VerbboxLineNo\end{myverbbox}
\begin{myverbbox}{\lb}[\end{myverbbox}
\begin{myverbbox}{\rb}]\end{myverbbox}
\begin{myverbbox}{\lbr}{\end{myverbbox}
\begin{myverbbox}{\rbr}}\end{myverbbox}
\begin{myverbbox}[\footnotesize]{\fsvrbox}verbbox\end{myverbbox}
\begin{myverbbox}[\footnotesize]{\fbx}\fbox\end{myverbbox}
\begin{myverbbox}[\footnotesize]{\fbs}\fboxsep\end{myverbbox}

\begin{center}
\LARGE The {\vbx} Package\\
\rule{0em}{.7em}\small
{\centering
\begin{minipage}{.7\textwidth}%
Routines for placing stylized verbatim text into boxes, useful in 
places where the verbatim environment is inaccessible.  Secondarily, 
for adding vertical buffer around an object.
\end{minipage}
}\\
\rule{0em}{2.7em}\large Steven B. Segletes\\
steven.b.segletes.civ@mail.mil\\
\rule{0em}{1.7em}\today\\
\verbatimboxVersionNumber
\end{center}

\section{Description and Commands}

The {\vbx} package allows verbatim material to be placed into \LaTeX{}
boxes, for later recall.  This function is useful in several situations,
primarily in places where the verbatim environment is otherwise
inaccessible (for example, in the midst of a tabular environment).  It
is also useful if a given verbatim text needs to be recalled multiple
times within a document.

One very nice feature of this package is the optional argument to both
environments and macros that allows custom stylization of the verbatim
text (fontshapes, sizes, numbering lines, \textit{etc.}) through the use
of pre-commands.  For those who prefer this form of optional-argument
customization, the environments and macros are \textit{also} provided in
a ``no-box'' form that is output directly, rather than being saved in a
box.  The no-box forms can be used when the verbatim has to span across
page breaks.

While there is application for its use within the {\vbx} application,
this package also offers an independent command for conveniently
providing vertical buffer space above and below an object.

The environments and macros provided by this package are given as 
follows:\\\itshape
\rl%
\addvbuffer[1ex 1ex]%
{\parbox{4in}{%
  \vbenv\lb pre-commands\rb\ldots\evbenv\\
  \myvb\lb pre-commands\rb\lbr token\rbr\ldots\bs\emyvb\\
  \vbfbox\lb pre-commands\rb\lbr filename\rbr\\
  \tvb\lb\texttt{\upshape t}\rb\\
  \bts\eq length\\
  \bbs\eq length\\
  \avb\lb length \lb below length\rb\rb\lbr object\rbr\\
  \bgn\lbr\vrnobox\rbr\lb pre-commands\rb\ldots\edng\lbr\vrnobox\rbr\\
  \vbfnobox\lb pre-commands\rb\lbr filename\rbr
}}\\\upshape 
In addition, there is a counter, \vln\margenv{\vln}, which contains the
current verbatim line number being processed.  It's use as part of
the optional pre-commands to \vrbox, \myvrbox, or {\vbfbox} (in the form
  of\\ \rl\verb|[\arabic{VerbboxLineNo}:]|\\
will cause the lines of the environment to be numbered.

\subsection{The \texttt{verbbox} Environment}

The {\vrbox} environment places the content of the environment into a
verbatim box.  The box is not printed when the environment is closed.
However, the box can be later recalled (even in a verbatim-restricted
environment) by way of the command \tvb\margenv{\tvb}.  Being placed
into a box, it is important to remember that a \LaTeX{} box cannot span
across page boundaries.

The width of the box into which the contents of the environment are
placed is the width of the longest line in your environment, rather than
the width of the page.  This feature can be useful if the box is being
recalled inline with other text,
\begin{verbbox}[\scriptsize\scshape]
as in This Example
\end{verbbox}
\theverbbox, shown immediately to the left.

The environment has one optional argument, which can contain commands
that will be executed before each line of verbatim text is output.
Thus, they can include font size, series, shape, or family changes
affecting the appearance of the verbatim text in the box.  They can also
include printed matter, like a bullet

\begin{verbatim}
 \begin{verbbox}[\(\bullet\)\hspace{1ex}]
 first line
 second line
 third line
 \end{verbbox}
 \theverbbox
\end{verbatim}

\begin{verbbox}[\(\bullet\)\hspace{1ex}]
first line
second line
third line
\end{verbbox}
\rl\theverbbox

or, as mentioned earlier, the lines can be numbered:

\begin{verbatim}
 \begin{verbbox}[\arabic{VerbboxLineNo}:\hspace{1ex}]
 first line
 second line
 third line
 \end{verbbox}
 \theverbbox
\end{verbatim}

\begin{verbbox}[\arabic{VerbboxLineNo}:\hspace{1ex}]
first line
second line
third line
\end{verbbox}
\rl\theverbbox

The customization can make use of the \verb|VerbboxLineNo| counter in
ways that make it line specific.  Note that the optional argument
must be contained on a single line.

\begin{verbatim}
\newcommand*\ifline[3]{%
    \ifthenelse{\value{VerbboxLineNo} = #1}{#2}{#3}}
\newcommand*\highlight{%
    \color{red}\rmfamily\itshape\bfseries\large\(\bullet~\)}
\newcommand\nohighlight{\arabic{VerbboxLineNo}:\hspace{1ex}}
\begin{verbbox}[\ifline{2}{\highlight}{\nohighlight}]
Line 1
Line 2
Line 3
\end{verbbox}
\theverbbox
\end{verbatim}

\newcommand*\ifline[3]{%
    \ifthenelse{\value{VerbboxLineNo} = #1}{#2}{#3}}
\newcommand*\highlight{%
    \color{red}\rmfamily\itshape\bfseries\large\(\bullet~\)}
\newcommand\nohighlight{\arabic{VerbboxLineNo}:\hspace{1ex}}
\begin{verbbox}[\ifline{2}{\highlight}{\nohighlight}]
Line 1
Line 2
Line 3
\end{verbbox}
\rl\theverbbox

\begin{verbbox}[\arabic{VerbboxLineNo}:\hspace{1ex}]
first line
second line
third line
\end{verbbox}

\subsection{The \texttt{myverbbox} Environment}

With the {\vrbox} environment, one is limited to one verbatimbox at a
time, since each new environment invocation overwrites the prior box.  A
new environment, {\myvrbox}, has therefore been introduced with version
3.0 of the package.  It is very similar to \vrbox, except that it is not
recalled with the use of \tvb.  In addition to the optional argument
which functions like that in \vrbox, {\myvrbox} must be supplied a
mandatory argument which is the command name that will recall the box
contents.

This environment was created for the situation when there is a need to
recall more than one verbatimbox in a given restricted environment.
Here is an example where two verbatimboxes must be inserted into the
tabular environment (where verbatim is prohibited):

\begin{verbatim}
 \begin{myverbbox}{\vtheta}\theta\end{myverbbox}
 \begin{myverbbox}{\valpha}\alpha\end{myverbbox}
 \begin{tabular}{|c|c|} \hline
 \valpha & $\alpha$ \\  \hline
 \vtheta & $\theta$ \\  \hline
 \end{tabular}
\end{verbatim}

\begin{myverbbox}{\vtheta}\theta\end{myverbbox}
\begin{myverbbox}{\valpha}\alpha\end{myverbbox}
\rl\begin{tabular}{|c|c|} \hline
\valpha & $\alpha$ \\  \hline
\vtheta & $\theta$ \\  \hline
\end{tabular}

In this example the the command \verb|\valpha| will recall a verbatimbox
with the verbatim content \valpha.  Likewise for \verb|\vtheta|.

\subsection{The \bs\texttt{verbfilebox} Command}

The {\vbfbox} command is comparable to the aforementioned environments,
except that it is a command which takes the contents of a file specified
in the mandatory argument and places it in a verbatimbox.  Like
\vrbox, the boxed content can be recalled with an invocation of \tvb.
The optional argument contains pre-commands and functions in the same
manner as described for the {\vrbox} environment.

\subsection{The \bs\texttt{theverbbox} Command}

As already mentioned in the prior sections, the {\tvb} command is issued
to recall the contents of a box created by either the {\vrbox}
environment or the {\vbfbox} command.  This command can be issued in
places where the verbatim environment is otherwise inaccessible, such as
in the tabular environment or inside footnotes.

There is a \verb|[t]| option to this command, which preconditions {\tvb}
for environments where it will be framed, by adding 3pt (by default) of
space above the boxed content, since the top of the box is otherwise
clipped to the verbatim contents.  So in the following example, the left
invocation of {\tvb} is done without the \verb|[t]| option, whereas for
the right invocation, it is done with the \verb|[t]| option.  As you can
see, the framing on the right-hand box is more symmetric.

\rl\begin{tabular}{|c|}
\hline
\theverbbox\\
\hline
\end{tabular}
%
\rl\begin{tabular}{|c|}
\hline
\theverbbox[t]\\
\hline
\end{tabular}

If one wishes\margenv{\bts} a different vertical-buffer preconditioning
of {\tvb}, one can either reset the lengths {\bts} and
{\bbs}\margenv{\bbs} or else one can use the {\avb}\margenv{\avb}
command described below.

\subsection{The \bs\texttt{addvbuffer} Command}

The prior section already showed how when a verbatimbox is framed, it
may need some buffer space added above the box which is otherwise (by
design) clipped to the verbatim content.  While the \verb|[t]| option
will work for \tvb, that option does not exist for any of the boxes
created through the {\myvrbox} environment.  Furthermore, the user may
sometimes wish to add an arbitrary vertical buffer above and below an
object, without changing the underlying {\bts} and {\bbs} lengths
associated with the \verb|[t]| option of \tvb.

The {\avb} command is made to do this, and is useful in many situations
inside and outside of verbatimbox manipulations.  The mandatory argument
to the command is the object over and under which to place vertical
buffer.  As of version 3.0 of this package, the command comes with an
optional argument to specify how much buffer to use.  If the optional
argument is omitted, the buffer will be the amounts specified by the
{\bts} and {\bbs} lengths.

The optional argument can take two forms.  If the optional argument
comprises a single length, that length is symmetrically added above and
below the object.  So, for example,
  \verb|\fbox{\addvbuffer[5pt]{\theverbbox}}|
will produce

\rl\fbox{\addvbuffer[5pt]{\theverbbox}}

On the other hand, the optional argument may comprise two lengths, in
which case the first length is added above the object and the second is
added below the object.  Thus, 
\verb|\fbox{\addvbuffer[15pt 5pt]{\theverbbox}}|
will produce

\rl\fbox{\addvbuffer[15pt 5pt]{\theverbbox}}

But {\avb} need not only be used for \tvb.  It can be used on other
objects, for example a \verb|\parbox|

\rl\fbox{\addvbuffer[15pt 5pt]{\parbox{1in}{This is a test of the
emergency broadcast system}}}

or even on just plain text \verb|\fbox{\addvbuffer[15pt 5pt]{A test}}|:

\rl\fbox{\addvbuffer[15pt 5pt]{A test}}

It can even be used to remove vertical space from an objects size, by
adding negative buffer \verb|\fbox{\addvbuffer[-5pt -5pt]{A test}}|:

\rl\fbox{\addvbuffer[-5pt -5pt]{A test}}

This ability to work on a variety of objects makes {\avb} a powerful
command in many applications.

\textbf{ATTENTION.  This paragraph represents a change as of V3.11, and 
can break backward compatibilty}.
Likewise, if two length variables are to be used in the optional
argument, the two lengths must be separately braced, with a space in between:

\begin{verbatim}
  \fbox{\addvbuffer[{\baselineskip} {.5\baselineskip}]{A test}}
\end{verbatim}

\rl\fbox{\addvbuffer[{\baselineskip} {.5\baselineskip}]{A test}}

{\bfseries One may no longer use a ``\verb|\ |'' hard space to separate the
two arguments.}

\subsection{The ``nobox'' Alternatives}

Alternatives are provided for the {\vrbox} environment and the {\vbfbox}
macro, which output the content directly, rather than place it into a
box.  These alternatives are named {\vrnobox}\margenv{\vrnobox} and
{\vbfnobox}\margenv{\vbfnobox}.  Like their boxed counterparts, these
alternatives make use of the convenient optional pre-commands that allow
for custom stylization of the verbatim content.  

Because they are not placed into a box, but instead output directly,
their content cannot be recalled at a later time in the document.  While
the boxed versions have a particular use in environments where verbatim is
inaccessible, the no-boxed alternatives may be used when the content
must span a page break.

\section{Quirks}\fboxsep=0pt

The use of a single optional argument for the {\vrbox} environment has
caused problems in the past, if the first item in the environment was a
command, rather than text.  This problem has been resolved as of version
3.0 of the package (for backward compatibility, we have kept the earlier
incarnation of {\vrbox}, now renamed as \ovrbox).  However, a few minor
quirks remain even with the new version (which, incidentally, can be
avoided by using the {\myvrbox} environment).  Note that the commands of
this package do not enclose the created boxes in frames.\footnote{In all
these examples, the {\fsvrbox} material is explicitly placed in an \fbx,
to expressedly show the limits of the boxed material.  Throughout this
section, {\fbs} has been set to 0pt.} Thus, frames shown in these
examples are for illustrative purposes only.

The primary quirk of {\vrbox} is that its optional argument does not
take effect until the second line (on the line following the environment
invocation), so that

\begin{verbatim}
 \begin{verbbox}[\LARGE]first line
 second line
 \end{verbbox}
 \fbox{\theverbbox}
\end{verbatim}

would look like:\\
\begin{verbbox}[\LARGE]first line
second line
\end{verbbox}
\rl\addvbuffer[3pt 0pt]{\fbox{\theverbbox}}

The solution, in the presence of an optional argument, is to begin the
first line of the environment contents on the following line.  Thus,

\begin{verbatim}
 \begin{verbbox}[\LARGE]
 first line
 second line
 \end{verbbox}
 \fbox{\theverbbox}
\end{verbatim}

will yield the expected result:\\
\begin{verbbox}[\LARGE]
first line
second line
\end{verbbox}
\rl\addvbuffer[3pt 0pt]{\fbox{\theverbbox}}

No such requirement is necessary if there are no optional arguments.
So, for example,
\verb|\begin{verbbox}Hello World\end{verbbox}|
\begin{verbbox}Hello World\end{verbbox} 
will produce, upon issue of \tvb, the box ``\theverbbox.''  As with all
verbatim environments, the {\evbenv} must be followed by a linebreak, or
the subsequent text on that line will be lost.

The {\myvrbox} environment does not suffer the above quirk, so that\\
\verb|\begin{myverbbox}[\scriptsize]{\mybox}Hello World\end{myverbbox}|\\
gives, \begin{myverbbox}[\scriptsize]{\mybox}Hello World\end{myverbbox}
upon issue of \verb|\mybox|, the expected result: \mybox.

The optional argument of {\vrbox} may contain both printing or
nonprinting material.  The printing material will appear (as \LaTeX{},
not as \verb|verbatim|) at the beginning of every line of the \vrbox.
However, it is recommended to place nonprinting material at the lead of
the optional argument, or the box width may be improperly set, as in
this following example:

\begin{verbatim}
 \begin{verbbox}[\rmfamily\textsc{Debug}:\footnotesize]
 first line
 second line
 \end{verbbox}
 \fbox{\theverbbox}
\end{verbatim}
\begin{verbbox}[\rmfamily\textsc{Debug}:\footnotesize]
first line
second line
\end{verbbox}
\rl\fbox{\theverbbox}

Note how the box does not extend to the end of the text line.  When
placing printing commands before non-printing commands that change the
fontsize, the reverse is also possible, where the box is set too large
for the actual text.

The {\myvrbox} environment behaves identically in this regard.  Below we
show the prior example, this time created in the {\myvrbox} environment,
except that the non-printing optional material has been placed before
the printing optional material, so that the box size is correctly
interpreted:

\begin{myverbbox}[\rmfamily\footnotesize\textsc{Debug}:]{\mybox}
first line
second line
\end{myverbbox}
\rl\fbox{\mybox}

There are differences, however, in how {\vrbox} and {\myvrbox} process
the optional argument, which relate to overcoming the problems
associated with a single optional argument for the {\vrbox} environment.
In particular, while the {\myvrbox} optional argument should behave as
one would otherwise expect, the optional argument of {\vrbox} will
ignore spaces (which can be overcome with \verb|\hspace{}|) and will
choke on the dollar symbol (\verb|$|) as a way to enter and exit math 
mode (which can be overcome by using the \verb|\(|\ \verb|\)| syntax 
instead).  Thus, an optional argument like\\
  \rl\verb|[\arabic{VerbboxLineNo}$\cdot$ ]|\\
which works fine for \myvrbox,  would need to appear as\\
  \rl\verb|[\arabic{VerbboxLineNo}\(\cdot\)\hspace{1ex}]|\\
in the {\vrbox} environment.  In that case, it would number the lines of
the environment in the following manner:

\begin{verbbox}[\arabic{VerbboxLineNo}\(\cdot\)\hspace{1ex}]
first line
second line
third line
\end{verbbox}
\rl\theverbbox

There is also a quirk with the macro \verb|\addvbuffer|.
If the \verb|\addvbuffer| macro adds negative space below an argument, 
the argument is
vertically shifted downward by the same amount.  For example,
compare the following constructions, 
\verb|\fbox{gb}| and \verb|\fbox{\addvbuffer[-3pt]{gb}}|:
\fbox{gb}\fbox{\addvbuffer[-3pt]{gb}}.
In the latter case, the box is bottom-trimmed, but the result is shifted downward.  
This adverse outcome can generally be overcome with a countering 
\verb|\raisebox|,
\fbox{gb}\fbox{\raisebox{3pt}{\addvbuffer[-3pt]{gb}}}.
However, if the \verb|\raisebox| would otherwise place
the new box above the baseline, the effect of the 
\verb|\addvbuffer| on the bottom of the box is spoiled, as in the 
comparison given by the constructions
\verb|\fbox{\addvbuffer[-3pt]{X}}| versus 
\verb|\fbox{\raisebox{3pt}{\addvbuffer[-3pt]{X}}}|
which produces this result: 
\fbox{\addvbuffer[-3pt]{X}}\fbox{\raisebox{3pt}{\addvbuffer[-3pt]{X}}}.
Note how 3pt are not trimmed from the bottom of the second box.
For this reason, the \verb|\raisebox| remedy has not been incorporated into the definition
of \verb|\addvbuffer|; instead, the quirk has been allowed to stand.


\section{Acknowledgements}

I would like to thank Dr. David Carlisle for his great assistance
in helping me to understand the nuances of optional arguments used in
verbatim environments, allowing me to correct a longstanding bug in the
{\vrbox} environment:\\
  \rl\addvbuffer[1.1ex 1.4ex]{\parbox{\textwidth}{%
    http://tex.stackexchange.com/questions/109030/ \\
     optional-arguments-in-verbatim-environments
  }}\\
I would also like to acknowledge the use of three lines of code created
by Prof. Enrico Gregorio, to strip the leading backslash from a
\LaTeX{} command name\\
  \rl\addvbuffer[1.1ex 0ex]{\parbox{\textwidth}{%
    http://tex.stackexchange.com/questions/42318/ \\
      removing-a-backslash-from-a-character-sequence
  }}

\section{Code Listing}

\verbatiminput{verbatimbox.sty}

\end{document}