summaryrefslogtreecommitdiff
path: root/usergrps/uktug/baskervi/4_4/fine.tex
blob: ee9d53d1f25aa7c8e0d76d9be24cce602b3e8a60 (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
\title{Backslash---Mathematical Activity}
\author[Jonathan Fine]{Jonathan Fine\\\texttt{J.Fine@uk.ac.cam.pmms}}

\begin{Article}

\noindent 
First an apology.  I did not allow time to proof my last article and
so did notice many small errors.  None were \TeX{}nically important,
except the solution to exercise 3.  I thank David Carlise for
pointing out that although \verb"\par" and \verb"\xyz" might have the
same meaning, only \verb"\long" macros will accept a \verb"\par" in
their parameter text.  I guess I also forgot to mention that when used
as a macro parameter delimiter, the meaning of a control sequence has
no bearing but the name is everything.  And in the middle of page~17,
right column, the line
\begin{quote}\quad\verb!\spaceit \endspaceit!\end{quote}
\noindent should be deleted.

The themes of this \BV\ issue are mathematics and tables. Siep
Kroonenberg's article on tables is excellent.  Here is a little
trick for use within mathematics.  It involves active characters.  The
sort of thing one might wish to do is have, say, \verb"[[" act as a
sort of ligature for a compound math character, such as $[\![$.

For every character code 0--255 there is a mathcode, which controls
just how that character should be typeset, when in mathematics.  More
exactly, it gives the class or part of mathematical speech, the font
family to use, and the location with the font family.

A little known and little used feature of \TeX{} is,
\begin{quote}
A \verb"\mathcode" can also have the special value \verb+"8000"+,
which causes the character to behave as if it has catcode 13
(active).  Appendix~B uses this feature to make \verb"'" expand to
\verb"^{\prime}" in a slightly tricky way.
\end{quote}
Knuth writes on [155] (this means page 155 of the {\em \TeX book}). 
This feature is not used by \verb"plain" for any other purpose.  This
remark is flagged as a `double dangerous bend' and so this article
may not be suitable for all readers.

As a result of this magic value for mathcode, a character can be made
to act as if it were active when it is in mathematics mode, but not
in text mode.  This is done without changing the catcodes, and so even
if ordinary letters are so made special, formation of control
sequence names proceeds as usual.  Moreover, math macros such as
\verb"\matrix" and \verb"\eqalign" read their text as a parameter, and
this fixes the category codes.  (The \verb"plain" footnote macro goes
to some length to avoid this [363], so as to allow category code
changes to occur within the text of the footnote.  This enable
verbatim text to there appear.)

Knuth [48] ``discourage[s] people from making extensive use of
\verb"\catcode" changes except in unusual circumstances'' precisely
because ``when the arguments to a macro are first scanned \ldots{}
their categories are fixed once and for all at that time.'' A
\verb"\matrix" may contain math and ordinary text, or may itself be
the argument to another macro (this is why verbatim does not work
properly within \LaTeX{} section titles).  Thus, to achieve a smart
\verb"[[" by category code changes would be difficult, and create
many unwelcome side effects.

However, mathcode \verb+"8000+ does not have these problems, because
it is not a category code change.  To understand the use of this
unusual mathcode, let us change the math code of \verb"[" to this new
value in such a way that ordinary documents will process exactly as
before.  The line
\begin{verbatim}
\mathcode '\[ "8000
\end{verbatim}
will change the mathcode to the magic value, but the previous
value---which controlled its conduct---is now lost.  So we shall
first save it.  In fact the code below
\begin{verbatim}
\ifnum \mathcode`\[ = "8000
\else
  \begingroup
    \catcode `\[ =13
    \global \mathchardef [ \mathcode`\[
  \endgroup
  \mathcode `\[ = "8000
\fi
\end{verbatim}
will first test that we haven't monkeyed with it before, and if safe
to do so, will \verb"\mathchardef" an {\em active\/} \verb"[" to the
original mathcode value, and finally set the mathcode of \verb"[" to
the magic value.

These changes (unless \verb"[" already has an active meaning, say for
use within ordinary text) should have no effect whatsoever on the
processing of manuscripts.  So what have we gained?

Previously the mathcode of \verb"[" caused the appropiate character
to be looked up from the appropiate font, and used as a mathematical
part of speech of the appropiate class.  Now the mathcode of \verb"["
will cause the meaning of active character \verb"[" to be looked up. 
The current value of this meaning is a mathchar which causes the
previous appropiate action.  {\em This meaning can now be changed},
to produce new behaviour.  This is the gain.

Our example is that we wanted \verb"[[" to produce $[\![$.  This
compound symbol fragment was produced using \verb"$[\![$", where
\verb"\!" gives a negative thin space.  To obtain this same result,
but using \verb"[[" as input, we must reset the value for active
\verb"[".

Here's how.  Active \verb"[" must inspect the next token.  To avoid
\verb"\futurelet" complications, I will assume is not a brace or a
space, and so can be read as a parameter.  If it is another \verb"["
we produce the compound symbol, otherwise we produce a single $[$ and
restore the parameter to the input stream.
\begin{verbatim}
\def \next #1%
{%
  \ifx #1[%
    \lbrack@\!\lbrack@
  \else
    \lbrack@
    \expandafter #1%
  \fi
}
\end{verbatim}

\begin{verbatim}
\begingroup
  \catcode`\[=13  % active
  \global \let [ \next
\endgroup
\end{verbatim}
The control sequence \verb"\next" is used to hold the value until we
change the catcode of \verb"[" to access active \verb"[".  If we
tried to make the definition all at once, we would find that we would
no longer have access to regular \verb"[".  The command
\verb"\lbrack@" has been freshly introduced, to hold the customary
mathcode of \verb"[".  This could have been obtained via
\begin{verbatim}
\mathchardef \lbrack@ \mathcode`[
\end{verbatim}
if we had though to {\em before\/} we started changing things.  As it
now is, we can use
\begin{verbatim}
\mathchardef \lbrack@ "405B
\end{verbatim}
which value comes from \verb"plain.tex" (see [344]).

The \verb"\expandafter" in the above definition is to prevent code
such as
\begin{verbatim}
$ [ \mathmacro { argument } ] $
\end{verbatim}
producing a disaster, where \verb"\mathmacro" takes a single
parameter.  Stepping through the above code for active \verb"["
we will we get
\begin{verbatim}
\lbrack@ \expandafter 
\mathmacro \fi { argument }
\end{verbatim}
as an intermediate result.  Without the \verb"\expandafter", the
\verb"\mathmacro" would get \verb"\fi" as its argument, and that is
totally wrong.  As it is, the \verb"\expandafter" causes the token
{\em after\/} the \verb"\mathmacro", which is the \verb"\fi",  to be
expanded {\em before} \verb"\mathmacro" does its piece.  When
\verb"\fi" is expanded [213], 
\begin{quote}
\TeX{} reads to the end of any text that ought to be skipped.  The
``expansion'' of a conditional is empty.
\end{quote}
and this is just what we want.  The \verb"\fi" is gone, and so now
\verb"\mathmacro" gets its proper argument.

This device, which I call {\em active mathematical characters\/} makes
all sort of dirty trickery possible.  Mathematicians have a wide
range of complicated symbols, diagrams, matrices, and so forth. 
Perhaps use of this device will allow for improved input syntax for
at least some of these devices.

Finally, problems and solutions.  Problem~5 from last issue has a
short solution (six lines of 80~column code) but seems to require a
long explanation.  The solution to Problem~6 will be given in the
next issue.  There are two new problems for this issue.  The solution
to Problem~7 is in the {\em \TeX{}book}.  Problem~8 asks a question
about possible \verb"\mathchar" values.

\noindent
{\bf Solution 5.}
{\em The problem was to write a macro which will trim the leading and
trailing spaces from user supplied text.}
Assume that 
\verb"\text" is a macro whose expansion is the user-supplied text,
such as
\begin{verbatim}
\def \text { apples and oranges }
\end{verbatim}
and that \verb"\trim" \verb"\text" is to redefine \verb"\text" as
\begin{verbatim}
\def \text {apples and oranges}
\end{verbatim}
which is as before, but without leading and trailing spaces. 
However, the original value of \verb"\text" may contain macros,
nested braces, and perhaps even conditionals.

Here is the solution, with comments as we go along.
\begin{verbatim}
\catcode`\@=11  % @ is a letter
\def\trim #1{%
  \expandafter\trim@
  \expandafter{#1 }%
  #1%
}
\end{verbatim}
If \verb"\text" is the argument to \verb"\trim", the expansion of
\verb"\trim" will result in \verb"\trim@" being called with two
parameters.  The first will be, enclosed in braces, the user
supplied text {\em but with an additional trailing space} (the
reason for which will be given later) and the second the name of the
control sequence (\verb"\text") whose redefinition is sought.

We now set things up to remove the leading space, if any.  We use
\verb"@" as a private delimiter, for it cannot occur {\em with
category code 11\/} in user supplied text.  The expansion of
\begin{verbatim}
\def\trim@ #1{\trim@@ @#1 @ #1 @ @@}
\end{verbatim}
will cause \verb"\trim@@" to see before it {\em two\/} copies of the
user-supplied text, both with (another) additional trailing space,
the first copy without and the second with an additional leading space.
This whole mess is closed with \verb"@@", which functions as a
delimiter.

The trick now is to have \verb"\trim@@" look for text delimited on
both left and right by the pair \verb*"@ " of tokens (being an \verb"@"
followed by a space).  If the user-text has a leading space, such
occurs around the first copy.  If not, around the second copy.  The
parameter delimiters of
\begin{verbatim}
\def\trim@@ #1@ #2@ #3@@{%
  \trim@@@\empty #2 @%
}
\end{verbatim}
select the appropiate copy of the user-text to be parameter 
\verb"#2".  The rest of the arguments can be thrown away,
all the way up to the \verb"@@" delimiter.  The parameter \verb"#2"
will be the user-text, with a trailing space added twice
(by \verb"trim" and by \verb"trim@" also), and with the leading space
(if present) stripped.  

We are nearly done now.  The purpose of the \verb"\empty" (a macro
which expands to nothing) will be explained later.  We copy the user
supplied text with yet another trailing space (that's the third time
we've done this) and call \verb"\trim@@@" with \verb"@" as a
delimiter.

Here come the final and amusing macro.  We wish to strip the trailing
space, if present.  Perversely, we have three times added a trailing
space.  Now {\em in regular user defined text, by virtue of \TeX's
reading rules [37], it is impossible for user supplied text to
contain two successive explicit space characters}.  So we use two
successive spaces characters as a delimiter, to strip trailing
spaces.  This is why we have been so assiduously been building them
up at the end.  

We need a helper macro
\begin{verbatim}
\def\unbrace#1{#1}
\end{verbatim}
to allow the construction of the final macro
\begin{verbatim}
\unbrace{\def\trim@@@ #1 } #2@#3
{%
  \expandafter\def
  \expandafter #3%
  \expandafter {%
  #1}%
}
\catcode`\@=12  % restore @
\end{verbatim}
whose first parameter \verb"#1" is delimited by {\em two space
characters}.  This strips the trailing space, and we discard any
other spaces there may be, up to the trailing \verb"@".  The third
parameter \verb"#3" is the control sequence (\verb"\text" in our
case) whose stripped redefinition we seek.

By now, \verb"#1" is stripped of leading and trailing space, and has
an \verb"\empty" prepended.  This is `stripped' via the
\verb"\expandafter"'s.  The macro is finished.

Some further explanations are required.  A trailing space is added
{\em three\/} times when it might seem that twice is enough, to cover
the case that \verb"\text" is empty.  In that situation the first
added {\em trailing\/} space will also be a {\em leading\/} space,
and will be treated as such.  The purpose of the \verb"\empty" is to
forestall \TeX's (usually helpful) custom of stripping ``the
outermost braces enclosing the argument'' [204].  Without this sweet
nothing, the macros produce from
\begin{verbatim}
\def\text {{well wrapped}}
\end{verbatim}
the new value
\begin{verbatim}
\def\text {well wrapped}
\end{verbatim}
which is wrong!  Earlier in the expansion the trailing space(s)
stopped this happening.

Finally, an acknowledgement. The basic ideas for dealing with the
leading space are due to Donald Arseneau, but the trailing double
space trick is all my own work.

\noindent
{\bf Exercise 7.}
What reason does Knuth give for choosing \verb"$" as the math
bracket.  Hint:  mathematics and tables are known as `penalty work'
because they will attract an extra charge from the typsetter.  The
solution in on [127].

\noindent
{\bf Exercise 8.}
Why should the value \verb+"8000+ be forbidden [155] as mathchar
(rather then mathcode) value?  And why not?

\end{Article}
\endinput








\catcode`\@=11

\ifnum \mathcode`\[ = "8000
\else
  \begingroup
    \catcode `\[ =13
    \global \mathchardef [ \mathcode`\[
  \endgroup
  \mathcode `\[ = "8000
\fi
\def \next #1%
{%
  \ifx #1[%
    \lbrack@\!\lbrack@
  \else
    \lbrack@
    \expandafter #1%
  \fi
}
\begingroup
  \catcode`\[=13  % active
  \global \let [ \next
\endgroup
\mathchardef \lbrack@ "405B


\catcode`\@=12
\end{Article}
\endinput