math-stc.mkvi /size: 57 Kb    last modification: 2021-10-28 13:50
1
%D \module
2
%D [ file=math-stc,
3
%D version=2012.12.29,
4
%D title=\CONTEXT\ Math Macros,
5
%D subtitle=Stackers,
6
%D comment=This replaces math-arr and friends,
7
%D author=Hans Hagen,
8
%D date=\currentdate,
9
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
10
%C
11
%C This module is part of the \CONTEXT\ macro||package and is
12
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
13
%C details.
14 15
\writestatus
{
loading
}
{
ConTeXt
Math
Macros
/
Stackers
}
16 17
\unprotect
18 19
%D WARNING: If the code here changes, the export needs to be checked! Stackers are
20
%D rather special because the order in mathml matters, so we flush in [base under
21
%D over] order. We also do some analysis at the \TEX\ end (passing the right
22
%D variant). It's easy in the export to deal with it but in the pdf stream less
23
%D trivial as we don't actually analyze there.
24
%D
25
%D At some point the \MKII\ arrow mechanism has been converted to \MKIV, but we kept
26
%D most of the logic. We now have a more generic variant dealing with extensibles.
27
%D There are a few demands than we need to meet:
28
%D
29
%D \startitemize
30
%D \startitem The width of the extensible need to adapt itself automatically. \stopitem
31
%D \startitem We need to be able to control horizontal and vertical offsets. \stopitem
32
%D \startitem We best have a math as well as a text variant (which is handy for chemistry). \stopitem
33
%D \startitem For historic reasons we need to deal with optional arguments in a special (reverse) way. \stopitem
34
%D \startitem We need alternatives for extensibles on top, in the middle and at the bottom. \stopitem
35
%D \stopitemize
36
%D
37
%D After I had experimented a bit with virtual characters for two headed arrows I
38
%D discussed the issue with the Gyre folks and we came to the conclusion that it
39
%D made sense to have real extensibles instead of constructing them out of snippets.
40
%D After all, \OPENTYPE\ math provides for it. So, in December 2013 beta versions of
41
%D Latin Modern and Gyre fonts came available that had these! Because we still want
42
%D to support the traditional Latin Modern Virtual math font those were extended
43
%D with a couple of virtual extensibles as well.
44
%D
45
%D {\em For the moment we still have some mess here: we can deal with known
46
%D dimensions, but fillers (like \type {\rightarrowfil} don't work with \OPENTYPE\
47
%D extensibles yet because there is no way to let them stretch like leaders. At some
48
%D point \LUATEX\ might provide a auto||fit||to||encapsulated||box and if not I will
49
%D cook up a \LUA\ based variant.}
50
%D
51
%D We could mess with something like \type {$mid\limits^{top}_{bottom}$} but we like
52
%D a bit more control. At some point we need to add some hacks to get exports
53
%D working well.
54
%D
55
%D In the end we have a more flexible mechanism which also handles text variants.
56 57
%D When wrapping up some math developments I decided to add mp support here as well.
58
%D A nice evening job with Joe Bonamassa performing live on the big screen (real
59
%D nice bluray's). See meta-imp-mat.mkiv for examples.
60 61
% possible improvements:
62
%
63
% - we could skip the left/right offsets when offset=normal, this saves some access time
64
% at the lua end and some checking: use \mathhorizontalcode or \mathextensiblecode
65
% but in practice arrows etc are not used that often
66 67
\installcorenamespace
{
mathextensiblefallbacks
}
68 69
% currently no italic correction ... problem is that we don't know yet if we have an italic
70
% below so we we need to postpone
71 72
% \def\math_stackers_fallback
73
% {\hbox to \scratchwidth{\csname\??mathextensiblefallbacks\ifcsname\??mathextensiblefallbacks\number\scratchunicode\endcsname\number\scratchunicode\fi\endcsname}}
74
% %{\csname\??mathextensiblefallbacks\ifcsname\??mathextensiblefallbacks\number\scratchunicode\endcsname\number\scratchunicode\fi\endcsname }
75 76
\def
\math_stackers_fallback
77
{
\mathstylehbox
to
\scratchwidth
{
\usemathstackerscolorparameter
\c!color
78
\hss
79
\hskip
\mathstackersparameter
\c!topoffset
\relax
% for manual italic correction
80
\ifcsname
\??mathextensiblefallbacks
\number
\scratchunicode
\endcsname
81
\lastnamedcs
82
\else
83
\Umathchar
\fam
\zerocount
\scratchunicode
84
\fi
85
\hss
}
}
86 87
\def
\math_stackers_regular
88
{
\mathstylehbox
{
\usemathstackerscolorparameter
\c!color
89
\hskip
\d_math_stackers_offset_l
90
\Umathaccent
\fam
\zerocount
\scratchunicode
91
{
\hskip
\dimexpr
\scratchwidth
-
\d_math_stackers_offset_l
-
\d_math_stackers_offset_r
}
%
92
\hskip
\d_math_stackers_offset_r
93
}
}
94 95
\def
\math_stackers_stretch
% we don't have that one yet
96
{
\mathstylehbox
{
\usemathstackerscolorparameter
\c!color
97
\hskip
\d_math_stackers_offset_l
98
\Umathaccent
\fam
\zerocount
\scratchunicode
99
{
\hskip
\dimexpr
\hsize
-
\d_math_stackers_offset_l
-
\d_math_stackers_offset_r
}
%
100
\hskip
\d_math_stackers_offset_r
101
}
}
102 103
% these delimiters are a unuseable as they don't center for small arguments:
104
%
105
% $\Umathaccent 0 0 "2190{x}$ \par $\Umathaccent 0 0 "27F8{x}$\par
106
% $\Udelimiterunder 0 "2190{x}$ \par $\Udelimiterunder 0 "27F8{x}$\par
107 108
\setvalue
{
\??mathextensiblefallbacks
}
%
109
{
\hpack
{
\vrule
\s!width
\scratchwidth
\s!height
.
1
\mathexheight
\s!depth
\zeropoint
}
}
110 111
% \def\math_stackers_with_fallback#codepoint%
112
% {\begingroup
113
% \scratchunicode#codepoint\relax
114
% \ifcase\mathextensiblecode\fam\scratchunicode\relax
115
% \math_stackers_fallback
116
% \else
117
% \math_stackers_stretch
118
% \fi
119
% \endgroup}
120 121
%D We don't really need this because we can assume that fonts have the right
122
%D extensibles. If needed I will make a general virtual extender for \OPENTYPE\
123
%D fonts.
124
%D
125
%D Because we have quite some control over positioning, we have somewhat extensive
126
%D tracing built in.
127 128
\let
\math_stackers_top
\relax
129
\let
\math_stackers_middle
\relax
130
\let
\math_stackers_bottom
\relax
131
\let
\math_stackers_skip
\hskip
132 133
\installtextracker
134
{
math
.
stackers
.
texts
}
135
{
\let
\math_stackers_top
\filledhboxb
136
\let
\math_stackers_middle
\filledhboxr
137
\let
\math_stackers_bottom
\filledhboxg
138
\let
\math_stackers_skip
\math_stackers_skip_indeed
}
139
{
\let
\math_stackers_top
\relax
140
\let
\math_stackers_middle
\relax
141
\let
\math_stackers_bottom
\relax
142
\let
\math_stackers_skip
\hskip
}
143 144
\def
\math_stackers_skip_indeed
#
amount
%
145
{
\filledhboxk
{
\unsetteststrut
\strut
\hskip
#
amount
}
}
% \dontshowstruts
146 147
\let
\math_stackers_start_tagged_mid
\relax
148
\let
\math_stackers_start_tagged_top
\relax
149
\let
\math_stackers_start_tagged_bot
\relax
150
\let
\math_stackers_stop_tagged
\relax
151 152
\appendtoks
153
\def
\math_stackers_start_tagged_mid
{
\dostarttagged
\t!mstackermid
\empty
\hbox
\bgroup
}
%
154
\def
\math_stackers_start_tagged_top
{
\dostarttagged
\t!mstackertop
\empty
\hbox
\bgroup
}
%
155
\def
\math_stackers_start_tagged_bot
{
\dostarttagged
\t!mstackerbot
\empty
\hbox
\bgroup
}
%
156
\def
\math_stackers_stop_tagged
{
\egroup
\dostoptagged
}
%
157
\to
\everysetuptagging
158 159
%D We define a full featured command handler.
160 161
\installcorenamespace
{
mathstackers
}
162 163
\installcommandhandler
\??mathstackers
{
mathstackers
}
\??mathstackers
164 165
\setupmathstackers
166
[
%c!alternative=\v!text, % text | mathematics
167
\c!left
=
,
168
\c!right
=
,
169
\c!mathclass
=
\s!rel
,
170
\c!alternative
=
\v!normal
,
171
\c!voffset
=
.
2
5
\mathexheight
,
172
\c!hoffset
=
\zeropoint
,
173
\c!topoffset
=
\zeropoint
,
% for manual italic correction
174
\c!distance
=
\mathstackersparameter
\c!voffset
,
% distance between symbol and base (can be different from voffset)
175
\c!minheight
=
\mathexheight
,
176
\c!mindepth
=
\zeropoint
,
177
\c!minwidth
=
.
5
\mathemwidth
,
178
\c!order
=
\v!normal
,
179
\c!strut
=
,
180
\c!color
=
,
% todo: when I need it
181
\c!topcommand
=
,
182
\c!middlecommand
=
,
183
\c!bottomcommand
=
,
184
\c!offset
=
\v!normal
,
% normal | min | max
185
\c!location
=
\v!top
]
% none | normal | small | medium | big
186 187
%D We assume that the middle characters (that can be an extensible) to sit on
188
%D top of the baseline by default.
189 190
\installcorenamespace
{
mathstackerslocation
}
191
\installcorenamespace
{
mathstackersalternative
}
192 193
\letvalue
{
\??mathstackerslocation
\v!top
}
\plusone
% on top of baseline
194
\letvalue
{
\??mathstackerslocation
\v!high
}
\plustwo
% 25 % down
195
\letvalue
{
\??mathstackerslocation
\v!middle
}
\plusthree
% centered
196
\letvalue
{
\??mathstackerslocation
\v!low
}
\plusfour
% 75 % down
197
\letvalue
{
\??mathstackerslocation
\v!bottom
}
\plusfive
% below baseline
198
\letvalue
{
\??mathstackerslocation
}
\zerocount
199 200
%D First we implement the helper that deals with an extensible in the middle and
201
%D top and|/|or bottom texts:
202 203
\let
\m_math_stackers_text_top
\empty
204
\let
\m_math_stackers_text_bottom
\empty
205
\let
\m_math_stackers_text_middle
\empty
206 207
\def
\math_stackers_flushtext
#
command
#
text
%
208
{
\ifdim
\scratchleftoffset
>
\zeropoint
\math_stackers_skip
\scratchleftoffset
\fi
209
\ifx
\p_strut
\v!no
\else
210
\strut
211
\fi
212
\mathstackersparameter
#
command
#
text
%
213
\ifdim
\scratchrightoffset
>
\zeropoint
\math_stackers_skip
\scratchrightoffset
\fi
}
214 215
\def
\math_stackers_toptext
{
\math_stackers_flushtext
\c!topcommand
\m_math_stackers_text_top
}
216
\def
\math_stackers_bottomtext
{
\math_stackers_flushtext
\c!bottomcommand
\m_math_stackers_text_bottom
}
217
\def
\math_stackers_middletext
{
\math_stackers_flushtext
\c!middlecommand
\m_math_stackers_text_middle
}
218 219
\def
\math_stackers_content
220
{
\ifcase
\scratchcounter
221
\math_stackers_fallback
222
\or
% left
223
\math_stackers_regular
224
\or
% right
225
\math_stackers_regular
226
\or
% horizontal
227
\math_stackers_regular
228
\else
229
\math_stackers_fallback
230
\fi
}
231 232
% no checking, we assume sane use
233 234
\letvalue
{
\??mathstackersalternative
\v!normal
}
\math_stackers_content
235
\letvalue
{
\??mathstackersalternative
\v!default
}
\math_stackers_content
236 237
\setupmathstackers
238
[
\c!mp
=
math
:
stacker
:
\number
\scratchunicode
,
239
\c!mpheight
=
\mathcharht
\scratchunicode
,
240
\c!mpdepth
=
\mathchardp
\scratchunicode
,
241
\c!mpoffset
=
.
2
5
\mathexheight
]
242 243
% \setvalue{\??mathstackersalternative\v!mp}%
244
% {\hbox\bgroup % todo: add code key + tag
245
% \d_overlay_width \scratchwidth
246
% \d_overlay_height \dimexpr\mathstackersparameter\c!mpheight
247
% \d_overlay_depth \dimexpr\mathstackersparameter\c!mpdepth
248
% \d_overlay_offset \dimexpr\mathstackersparameter\c!mpoffset
249
% \d_overlay_linewidth\linewidth
250
% \edef\overlaylinecolor{\mathstackersparameter\c!color}%
251
% \edef\p_mp{\mathstackersparameter\c!mp}%
252
% \uniqueMPgraphic{\p_mp}%
253
% \egroup}
254 255
\setvalue
{
\??mathstackersalternative
\v!mp
}
%
256
{
\normalexpanded
{
\math_stackers_mp_box
257
{
\the
\dimexpr
\mathstackersparameter
\c!mpheight
}
%
258
{
\the
\dimexpr
\mathstackersparameter
\c!mpdepth
}
%
259
{
\the
\dimexpr
\mathstackersparameter
\c!mpoffset
}
%
260
{
\the
\dimexpr
\triggeredmathstyleparameter
\Umathfractionrule
}
%
261
{
\the
\dimexpr
\triggeredmathstyleparameter
\Umathaxis
}
%
262
{
\the
\mathexheight
}
%
263
{
\the
\mathemwidth
}
%
264
}
}
265 266
\unexpanded
\def
\math_stackers_mp_box
#
1
#
2
#
3
#
4
#
5
#
6
#
7
%
267
{
\hpack
\bgroup
% todo: add code key + tag
268
% we can speed up \mathexheight expansion a bit
269
\d_overlay_width
\scratchwidth
270
\d_overlay_height
#
1
\relax
271
\d_overlay_depth
#
2
\relax
272
\d_overlay_offset
#
3
\relax
273
\d_overlay_linewidth
#
4
\relax
274
\edef
\overlaylinecolor
{
\mathstackersparameter
\c!color
}
%
275
\edef
\p_mp
{
\mathstackersparameter
\c!mp
}
%
276
\uniqueMPgraphic
{
\p_mp
}
{
axis=#5,ex=#6,em=#7
}
%
277
\egroup
}
278 279
\def
\math_stackers_check_unicode
#
codepoint
%
280
{
\scratchunicode
#
codepoint
\relax
281
\scratchhoffset
\mathstackersparameter
\c!hoffset
\relax
282
\scratchvoffset
\mathstackersparameter
\c!voffset
\relax
283
\scratchcounter
\mathhorizontalcode
\fam
\scratchunicode
\relax
% also sets \leftscratchoffset and \rightscratchoffset
284
\ifx
\p_offset
\v!max
285
% heads/tails + hoffset
286
\else
\ifx
\p_offset
\v!min
287
% heads/tails - hoffset
288
\advance
\scratchleftoffset
-
\scratchhoffset
289
\advance
\scratchrightoffset
-
\scratchhoffset
290
\else
% \v!normal
291
% hoffset
292
\scratchleftoffset
\zeropoint
293
\scratchrightoffset
\zeropoint
294
\fi
\fi
295
\ifdim
\scratchleftoffset
<
\zeropoint
296
\scratchleftoffset
\zeropoint
297
\fi
298
\ifdim
\scratchrightoffset
<
\zeropoint
299
\scratchrightoffset
\zeropoint
300
\fi
}
301 302
\def
\math_stackers_normalize_three
303
{
\scratchheight
\ht
\scratchboxthree
304
\scratchdepth
\dp
\scratchboxthree
305
\scratchtopoffset
\scratchheight
306
\scratchbottomoffset
\scratchdepth
307
\scratchdimen
\mathstackersparameter
\c!minheight
\relax
308
\ifdim
\scratchheight
<
\scratchdimen
309
\scratchheight
\scratchdimen
310
\ht
\scratchboxthree
\scratchheight
311
\fi
312
\scratchdimen
\mathstackersparameter
\c!mindepth
\relax
313
\ifdim
\scratchdepth
<
\scratchdimen
314
\scratchdepth
\scratchdimen
315
\dp
\scratchboxthree
\scratchdepth
316
\fi
317
\advance
\scratchtopoffset
-
\scratchheight
318
\advance
\scratchbottomoffset
-
\scratchdepth
319
\ifdim
\scratchtopoffset
<
\zeropoint
320
\scratchtopoffset
\zeropoint
321
\fi
322
\ifdim
\scratchbottomoffset
<
\zeropoint
323
\scratchbottomoffset
\zeropoint
324
\fi
}
325 326
\unexpanded
\def
\math_stackers_triplet
#
method
#
category
#
codepoint
#
toptext
#
bottomtext
%
327
%{\math_stackers_start_group{#category}%
328
{
\begingroup
329
\edef
\currentmathstackers
{
#
category
}
%
330
\mathstackersparameter
\c!left
\relax
331
\dostarttagged
\t!mstacker
\currentmathstackers
332
\ifmmode
\math_class_by_parameter
\mathstackersparameter
\else
\dontleavehmode
\fi
333
{
\edef
\p_offset
{
\mathstackersparameter
\c!offset
}
%
334
\edef
\p_location
{
\mathstackersparameter
\c!location
}
%
335
\edef
\p_strut
{
\mathstackersparameter
\c!strut
}
%
336
\edef
\p_alternative
{
\mathstackersparameter
\c!alternative
}
%
337
% \ifx\p_order\v!reverse
338
% \ifsecondargument
339
% \edef\m_math_stackers_text_top {#bottomtext}%
340
% \edef\m_math_stackers_text_bottom{#toptext}%
341
% \else
342
% \edef\m_math_stackers_text_top {#toptext}%
343
% \let\m_math_stackers_text_bottom \empty
344
% \fi
345
% \else
346
% \edef\m_math_stackers_text_top {#toptext}%
347
% \edef\m_math_stackers_text_bottom{#bottomtext}%
348
% \fi
349
\edef
\m_math_stackers_text_top
{
#
toptext
}
%
350
\edef
\m_math_stackers_text_bottom
{
#
bottomtext
}
%
351
\ifsecondargument
352
\edef
\p_order
{
\mathstackersparameter
\c!order
}
%
353
\ifx
\p_order
\v!reverse
354
\swapmacros
\m_math_stackers_text_top
\m_math_stackers_text_bottom
355
\fi
356
\fi
357
\scratchleftoffset
\zeropoint
358
\scratchrightoffset
\zeropoint
359
\ifcase
#
method
\relax
360
\math_stackers_check_unicode
{
#
codepoint
}
%
361
\else
362
\edef
\m_math_stackers_text_middle
{
#
codepoint
}
%
363
\fi
364
\ifx
\m_math_stackers_text_top
\empty
365
\setbox
\scratchboxone
\emptyhbox
366
\else
367
\setmathsmalltextbox
\scratchboxone
\hbox
{
\math_stackers_toptext
}
%
368
\fi
369
\ifx
\m_math_stackers_text_bottom
\empty
370
\setbox
\scratchboxtwo
\emptyhbox
371
\else
372
\setmathsmalltextbox
\scratchboxtwo
\hbox
{
\math_stackers_bottomtext
}
%
373
\fi
374
%
375
\ifcase
#
method
\relax
376
% e.g. extensible
377
%\scratchwidth\wd
378
% \ifdim\wd\scratchboxone>\wd\scratchboxtwo
379
% \scratchboxone
380
% \else
381
% \scratchboxtwo
382
% \fi
383
%\relax
384
\scratchwidth
\mathcharwd
\scratchunicode
385
\ifdim
\wd
\scratchboxone
>
\scratchwidth
386
\scratchwidth
\wd
\scratchboxone
387
\else
\ifdim
\wd
\scratchboxtwo
>
\scratchwidth
388
\scratchwidth
\wd
\scratchboxtwo
389
\fi
\fi
390
\else
391
\ifx
\m_math_stackers_text_middle
\empty
392
\setbox
\scratchboxthree
\emptyhbox
393
\else
394
\setmathtextbox
\scratchboxthree
\hbox
{
\math_stackers_middletext
}
%
395
\fi
396
\scratchwidth
\wd
397
\ifdim
\wd
\scratchboxone
>
\wd
\scratchboxtwo
398
\ifdim
\wd
\scratchboxone
>
\wd
\scratchboxthree
399
\scratchboxone
400
\else
401
\scratchboxthree
402
\fi
403
\else
\ifdim
\wd
\scratchboxtwo
>
\wd
\scratchboxthree
404
\scratchboxtwo
405
\else
406
\scratchboxthree
407
\fi
\fi
408
\relax
409
\fi
410
%
411
\scratchdimen
\mathstackersparameter
\c!minwidth
\relax
412
\ifdim
\scratchwidth
<
\scratchdimen
413
\scratchwidth
\scratchdimen
414
\fi
415
\advance
\scratchwidth
2
\scratchhoffset
416
%
417
\ifcase
#
method
\relax
418
\dostarttagged
\t!mstackermid
\empty
419
\setbox
\scratchboxthree
\csname
\??mathstackersalternative
\p_alternative
\endcsname
420
\dostoptagged
421
\fi
422
%
423
\ifdim
\wd
\scratchboxone
<
\scratchwidth
424
\setbox
\scratchboxone
\hpack
to
\scratchwidth
{
\hss
\unhbox
\scratchboxone
\hss
}
% unhboxing makes leaders work
425
\fi
426
\ifdim
\wd
\scratchboxtwo
<
\scratchwidth
427
\setbox
\scratchboxtwo
\hpack
to
\scratchwidth
{
\hss
\unhbox
\scratchboxtwo
\hss
}
%
428
\fi
429
\ifdim
\wd
\scratchboxthree
<
\scratchwidth
430
\setbox
\scratchboxthree
\hpack
to
\scratchwidth
{
\hss
\unhbox
\scratchboxthree
\hss
}
%
431
\fi
432
%
433
\ifcsname
\??mathstackerslocation
\p_location
\endcsname
434
\ifcase
\csname
\??mathstackerslocation
\p_location
\endcsname
\relax
435
\scratchdistance
\zeropoint
436
\or
% top
437
\scratchdistance
\zeropoint
438
\or
% high
439
\scratchdistance
.
2
5
\htdp
\scratchboxthree
440
\or
% centered
441
\scratchdistance
.
5
\htdp
\scratchboxthree
442
\or
% low
443
\scratchdistance
.
7
5
\htdp
\scratchboxthree
444
\or
% bottom
445
\scratchdistance
\htdp
\scratchboxthree
446
\else
447
\scratchdistance
\zeropoint
448
\fi
449
\else
450
\scratchdistance
\p_location
\htdp
\scratchboxthree
451
\fi
452
%
453
\ifzeropt
\scratchdistance
\else
454
\setbox
\scratchboxthree
\hpack
{
\lower
\scratchdistance
\box
\scratchboxthree
}
%
455
\fi
456
%
457
\math_stackers_normalize_three
458
% analysis
459
\ifdim
\htdp
\scratchboxtwo
>
\zeropoint
460
\ifdim
\htdp
\scratchboxone
>
\zeropoint
461
\dosettagproperty
\s!subtype
\t!munderover
462
\else
463
\dosettagproperty
\s!subtype
\t!munder
464
\fi
465
\else
466
\ifdim
\htdp
\scratchboxone
>
\zeropoint
467
\dosettagproperty
\s!subtype
\t!mover
468
\else
469
% brrr
470
\fi
471
\fi
472
% base
473
\math_stackers_start_tagged_mid
474
\math_stackers_middle
\bgroup
475
\box
\scratchboxthree
476
\egroup
477
\math_stackers_stop_tagged
478
% under
479
\ifdim
\htdp
\scratchboxtwo
>
\zeropoint
480
\math_stackers_start_tagged_bot
481
\scratchoffset
\scratchvoffset
482
\kern
-
\scratchwidth
483
\math_stackers_bottom
\bgroup
484
\lower
\dimexpr
\ht
\scratchboxtwo
+
\scratchdepth
+
\scratchoffset
+
\scratchbottomoffset
\relax
485
\box
\scratchboxtwo
486
\egroup
487
\math_stackers_stop_tagged
488
\fi
489
% over
490
\ifdim
\htdp
\scratchboxone
>
\zeropoint
491
\math_stackers_start_tagged_top
492
\scratchoffset
\scratchvoffset
493
\kern
-
\scratchwidth
494
\math_stackers_top
\bgroup
495
\raise
\dimexpr
\dp
\scratchboxone
+
\scratchheight
+
\scratchoffset
+
\scratchtopoffset
\relax
496
\box
\scratchboxone
497
\egroup
498
\math_stackers_stop_tagged
499
\fi
500
%
501
}
%
502
\dostoptagged
503
\mathstackersparameter
\c!right
\relax
504
\endgroup
}
505
%\math_stackers_stop_group}
506 507
\unexpanded
\def
\definemathextensible
508
{
\dotripleempty
\math_stackers_define_normal
}
509 510
\def
\math_stackers_define_normal
[
#
1
]
[
#
2
]
[
#
3
]
% category name unicode
511
{
\ifthirdargument
512
\setuevalue
{
#
2
}
{
\math_stackers_auto_normal
{
#
1
}
{
\number
#
3
}
}
%
513
\else
514
\setuevalue
{
#
1
}
{
\math_stackers_auto_normal
\noexpand
\currentmathstackers
{
\number
#
2
}
}
%
515
\fi
}
516 517
\unexpanded
\def
\math_stackers_auto_normal
#
category
#
codepoint
%
518
{
\begingroup
519
\edef
\currentmathstackers
{
#
category
}
%
520
\scratchcounter
#
codepoint
\relax
521
\dosingleempty
\math_stackers_auto_normal_first
}
522 523
\unexpanded
\def
\math_stackers_auto_normal_first
[
#
category
]
% [#2]% #2 gobble spaces
524
{
\iffirstargument
\edef
\currentmathstackers
{
#
category
}
\fi
525
\permitspacesbetweengroups
526
\dodoublegroupempty
\math_stackers_auto_normal_second
}
527 528
\def
\math_stackers_auto_normal_second
#
toptext
#
bottomtext
%
529
{
\math_stackers_triplet
\zerocount
\currentmathstackers
\scratchcounter
{
#
toptext
}
{
#
bottomtext
}
%
530
\endgroup
}
531 532
%D A few direct accessors (in the meantime we redefined \mathextensible so we renamed the
533
%D following):
534 535
\unexpanded
\def
\directmathextensible
{
\begingroup
\dosingleempty
\math_stackers_handle_math
}
536
\unexpanded
\def
\directtextextensible
{
\begingroup
\dosingleempty
\math_stackers_handle_text
}
537 538
\let
\mathstacker
\directmathextensible
539
\let
\textstacker
\directtextextensible
540 541
\unexpanded
\def
\math_stackers_handle_math
[
#
category
]
%
542
{
\math_stackers_handle_extensible
{
\iffirstargument
#
category
\else
\v!mathematics
\fi
}
}
% will be defined later on
543 544
\unexpanded
\def
\math_stackers_handle_text
[
#
category
]
%
545
{
\math_stackers_handle_extensible
{
\iffirstargument
#
category
\else
\v!text
\fi
}
}
% will be defined later on
546 547
\def
\math_stackers_handle_extensible
#
category
#
codepoint
#
toptext
#
bottomtext
%
548
{
\math_stackers_triplet
\zerocount
{
#
category
}
{
#
codepoint
}
{
#
toptext
}
{
#
bottomtext
}
%
549
\endgroup
}
550 551
%D The next one deals with under and over extensibles (arrows mostly):
552 553
\installcorenamespace
{
mathclasses
}
554 555
\letvalue
{
\??mathclasses
}
\mathord
556
\letvalue
{
\??mathclasses
rel
}
\mathrel
557
\letvalue
{
\??mathclasses
ord
}
\mathord
558 559
\def
\math_class_by_parameter
#
1
%
560
{
\normalexpanded
{
\noexpand
\math_class_by_parameter_indeed
{
#
1
\c!mathclass
}
}
}
561 562
\def
\math_class_by_parameter_indeed
#
1
%
563
{
\csname
\??mathclasses
\ifcsname
\??mathclasses
#
1
\endcsname
#
1
\fi
\endcsname
}
564 565
% 1 0 name n 0 | 0 1 name n 0 | 1 1 name n n
566 567
\unexpanded
\def
\math_stackers_start_group
#
category
%
568
{
\begingroup
569
\edef
\currentmathstackers
{
#
category
}
%
570
\edef
\p_limits
{
\mathstackersparameter
\c!mathlimits
}
%
571
\ifx
\p_limits
\v!yes
572
\def
\math_stackers_stop_group
{
\egroup
\endgroup
\ordlimits
}
%
573
\mathop
\bgroup
574
\else
575
\let
\math_stackers_stop_group
\endgroup
576
\fi
}
577 578
\newconstant
\c_math_stackers_top
579
\newconstant
\c_math_stackers_bottom
580
\newconstant
\c_math_stackers_codepoint
581
\newconstant
\c_math_stackers_extracode
582
\newdimen
\d_math_stackers_offset_l
583
\newdimen
\d_math_stackers_offset_r
584 585
\setupmathstackers
[
lt
=
\zeropoint
,
rt
=
\zeropoint
,
lb
=
\zeropoint
,
rb
=
\zeropoint
]
586 587
\unexpanded
\def
\math_stackers_make_double
#
top
#
bottom
#
category
#
codepoint
#
codeextra
%
588
{
\math_stackers_start_group
{
#
category
}
%
589
\c_math_stackers_top
#
top
\relax
590
\c_math_stackers_bottom
#
bottom
\relax
591
\c_math_stackers_codepoint
#
codepoint
\relax
592
\c_math_stackers_extracode
#
codeextra
\relax
593
\dosingleempty
\math_stackers_make_double_indeed
}
594 595
\unexpanded
\def
\math_stackers_make_double_indeed
[
#
settings
]
#
text
%
596
{
\iffirstargument
597
\setupcurrentmathstackers
[
#
settings
]
%
598
\fi
599
\mathstackersparameter
\c!left
\relax
600
\dostarttagged
\t!mstacker
\currentmathstackers
601
\ifmmode
\math_class_by_parameter
\mathstackersparameter
\else
\dontleavehmode
\fi
602
{
\edef
\m_math_stackers_text_middle
{
#
text
}
%
603
%
604
\edef
\p_offset
{
\mathstackersparameter
\c!offset
}
%
605
\edef
\p_location
{
\mathstackersparameter
\c!location
}
%
606
\edef
\p_strut
{
\mathstackersparameter
\c!strut
}
%
607
\edef
\p_alternative
{
\mathstackersparameter
\c!alternative
}
%
608
%
609
\scratchleftoffset
\zeropoint
610
\scratchrightoffset
\zeropoint
611
%
612
\math_stackers_check_unicode
\c_math_stackers_codepoint
613
%
614
\ifx
\math_stackers_middle
\empty
615
\setbox
\scratchboxthree
\emptyhbox
616
\else
617
\setmathtextbox
\scratchboxthree
\hbox
{
\math_stackers_middletext
}
%
618
\fi
619
\scratchwidth
\wd
\scratchboxthree
620
%
621
\scratchdimen
\mathstackersparameter
\c!minwidth
\relax
622
\ifdim
\scratchwidth
<
\scratchdimen
623
\scratchwidth
\scratchdimen
624
\fi
625
\advance
\scratchwidth
2
\scratchhoffset
626
%
627
%\scratchunicode\c_math_stackers_codepoint
628
\ifcase
\c_math_stackers_bottom
629
\d_math_stackers_offset_l
\mathstackersparameter
{
lt
}
%
630
\d_math_stackers_offset_r
\mathstackersparameter
{
rt
}
%
631
\else
\ifcase
\c_math_stackers_top
632
\d_math_stackers_offset_l
\mathstackersparameter
{
lb
}
%
633
\d_math_stackers_offset_r
\mathstackersparameter
{
rb
}
%
634
\else
635
\d_math_stackers_offset_l
\mathstackersparameter
{
lt
}
%
636
\d_math_stackers_offset_r
\mathstackersparameter
{
rt
}
%
637
\fi
\fi
638
\setbox
\scratchboxtwo
\csname
\??mathstackersalternative
\p_alternative
\endcsname
639
\setbox
\scratchboxthree
\hpack
to
\scratchwidth
{
\hss
\box
\scratchboxthree
\hss
}
%
640
%
641
\ifcase
\c_math_stackers_extracode
\else
642
\scratchunicode
\c_math_stackers_extracode
643
\d_math_stackers_offset_l
\mathstackersparameter
{
lb
}
%
644
\d_math_stackers_offset_r
\mathstackersparameter
{
rb
}
%
645
\setbox
\scratchboxone
\csname
\??mathstackersalternative
\p_alternative
\endcsname
646
\fi
647
%
648
\math_stackers_normalize_three
649
% analysis
650
\ifcase
\c_math_stackers_bottom
651
\ifcase
\c_math_stackers_top
652
\dosettagproperty
\s!subtype
\t!munderover
653
\else
654
\dosettagproperty
\s!subtype
\t!mover
655
\fi
656
\else
657
\ifcase
\c_math_stackers_top
658
\dosettagproperty
\s!subtype
\t!munder
659
\else
660
% brrr
661
\fi
662
\fi
663
% base
664
\math_stackers_start_tagged_mid
665
\math_stackers_middle
\bgroup
666
\box
\scratchboxthree
667
\egroup
668
\math_stackers_stop_tagged
669
%
670
\ifdim
\htdp
\scratchboxtwo
>
\zeropoint
671
\ifcase
\c_math_stackers_bottom
\else
672
\kern
-
\scratchwidth
673
% under
674
\math_stackers_start_tagged_bot
675
\math_stackers_bottom
\bgroup
676
\lower
\dimexpr
677
\scratchdepth
678
+
\ht
\scratchboxtwo
679
+
\mathstackersparameter
\c!distance
% was \c!voffset
680
\relax
681
\ifcase
\c_math_stackers_top
682
\box
\scratchboxtwo
683
\else
684
\box
\scratchboxone
685
\fi
686
\egroup
687
\math_stackers_stop_tagged
688
\fi
689
\ifcase
\c_math_stackers_top
\else
690
\kern
-
\scratchwidth
691
% over
692
\math_stackers_start_tagged_top
693
\math_stackers_top
\bgroup
694
\raise
\dimexpr
695
\scratchheight
696
+
\dp
\scratchboxtwo
% new
697
+
\mathstackersparameter
\c!distance
% was \c!voffset
698
\relax
699
\box
\scratchboxtwo
700
\egroup
701
\math_stackers_stop_tagged
702
\fi
703
\fi
}
%
704
\dostoptagged
705
\mathstackersparameter
\c!right
\relax
706
\math_stackers_stop_group
}
707 708
\unexpanded
\def
\definemathoverextensible
{
\dotripleempty
\math_extensibles_define_over
}
709
\unexpanded
\def
\definemathunderextensible
{
\dotripleempty
\math_extensibles_define_under
}
710
\unexpanded
\def
\definemathdoubleextensible
{
\doquadrupleempty
\math_extensibles_define_double
}
711 712
\def
\math_extensibles_define_over
[
#
1
]
[
#
2
]
[
#
3
]
%
713
{
\ifthirdargument
714
\setuevalue
{
#
2
}
{
\math_stackers_make_double
\plusone
\zerocount
{
#
1
}
{
\number
#
3
}
{
0
}
}
%
715
\else
716
\setuevalue
{
#
1
}
{
\math_stackers_make_double
\plusone
\zerocount
\noexpand
\currentmathstackers
{
\number
#
2
}
{
0
}
}
%
717
\fi
}
718 719
\def
\math_extensibles_define_under
[
#
1
]
[
#
2
]
[
#
3
]
%
720
{
\ifthirdargument
721
\setuevalue
{
#
2
}
{
\math_stackers_make_double
\zerocount
\plusone
{
#
1
}
{
\number
#
3
}
{
0
}
}
%
722
\else
723
\setuevalue
{
#
1
}
{
\math_stackers_make_double
\zerocount
\plusone
\noexpand
\currentmathstackers
{
\number
#
2
}
{
0
}
}
%
724
\fi
}
725 726
\def
\math_extensibles_define_double
[
#
1
]
[
#
2
]
[
#
3
]
[
#
4
]
%
727
{
\iffourthargument
728
\setuevalue
{
#
2
}
{
\math_stackers_make_double
\plusone
\plusone
{
#
1
}
{
\number
#
3
}
{
\number
#
4
}
}
%
729
\else
730
\setuevalue
{
#
1
}
{
\math_stackers_make_double
\plusone
\plusone
\noexpand
\currentmathstackers
{
\number
#
2
}
{
\number
#
3
}
}
%
731
\fi
}
732 733
\unexpanded
\def
\definemathover
{
\dotripleargument
\math_stackers_define_over
}
734
\unexpanded
\def
\definemathunder
{
\dotripleargument
\math_stackers_define_under
}
735
\unexpanded
\def
\definemathdouble
{
\doquadrupleargument
\math_stackers_define_double
}
736 737
\def
\math_stackers_define_over
[
#
category
]
[
#
command
]
[
#
topcode
]
%
738
{
\setuvalue
{
#
command
}
{
\math_stackers_handle_direct
\plusone
\zerocount
{
#
category
}
{
#
topcode
}
{
0
}
}
}
739 740
\def
\math_stackers_define_under
[
#
category
]
[
#
command
]
[
#
bottomcode
]
%
741
{
\setuvalue
{
#
command
}
{
\math_stackers_handle_direct
\zerocount
\plusone
{
#
category
}
{
#
bottomcode
}
{
0
}
}
}
742 743
\def
\math_stackers_define_double
[
#
category
]
[
#
command
]
[
#
topcode
]
[
#
bottomcode
]
%
744
{
\setuvalue
{
#
command
}
{
\math_stackers_handle_direct
\plusone
\plusone
{
#
category
}
{
#
topcode
}
{
#
bottomcode
}
}
}
745 746
\unexpanded
\def
\mathover
{
\begingroup
\dodoubleempty
\math_stackers_handle_over
}
747
\unexpanded
\def
\mathunder
{
\begingroup
\dodoubleempty
\math_stackers_handle_under
}
748
\unexpanded
\def
\mathdouble
{
\begingroup
\dodoubleempty
\math_stackers_handle_double
}
749 750
\def
\math_stackers_handle_over
[
#
category
]
[
#
settings
]
#
topcode
#
text
%
751
{
\edef
\currentmathstackers
{
\iffirstargument
#
category
\else
\v!top
\fi
}
%
752
\ifsecondargument
753
\setupcurrentmathstackers
[
#
settings
]
%
754
\fi
755
\math_stackers_make_double
\plusone
\zerocount
756
{
\currentmathstackers
}
%
757
{
#
topcode
}
%
758
{
0
}
%
759
{
#
text
}
%
760
\endgroup
}
761 762
\def
\math_stackers_handle_under
[
#
category
]
[
#
settings
]
#
bottomcode
#
text
%
763
{
\edef
\currentmathstackers
{
\iffirstargument
#
category
\else
\v!bottom
\fi
}
%
764
\ifsecondargument
765
\setupcurrentmathstackers
[
#
settings
]
%
766
\fi
767
\math_stackers_make_double
\zerocount
\plusone
768
{
\currentmathstackers
}
%
769
{
#
bottomcode
}
%
770
{
0
}
%
771
{
#
text
}
%
772
\endgroup
}
773 774
\def
\math_stackers_handle_double
[
#
category
]
[
#
settings
]
#
topcode
#
bottomcode
#
text
%
775
{
\edef
\currentmathstackers
{
\iffirstargument
#
category
\else
\v!both
\fi
}
%
776
\ifsecondargument
777
\setupcurrentmathstackers
[
#
settings
]
%
778
\fi
779
\math_stackers_make_double
\plusone
\plusone
780
{
\currentmathstackers
}
%
781
{
#
topcode
}
%
782
{
#
bottomcode
}
%
783
{
#
text
}
%
784
\endgroup
}
785 786
\def
\math_stackers_handle_direct
#
top
#
bottom
#
category
#
topcode
#
bottomcode
#
text
%
787
{
\begingroup
788
\math_stackers_make_double
#
top
#
bottom
{
#
category
}
{
#
topcode
}
{
#
bottomcode
}
{
#
text
}
%
789
\endgroup
}
790 791
%D A relative new one is a combination of accents and text (as needed in mathml):
792 793
\unexpanded
\def
\math_stackers_make_double_text
#
where
#
category
#
codepoint
#
text
#
extra
%
794
{
\math_stackers_start_group
{
#
category
}
%
795
\mathstackersparameter
\c!left
\relax
796
\dostarttagged
\t!mstacker
\currentmathstackers
797
\ifmmode
\math_class_by_parameter
\mathstackersparameter
\else
\dontleavehmode
\fi
798
{
\edef
\currentmathstackers
{
#
category
}
%
799
%
800
\edef
\p_offset
{
\mathstackersparameter
\c!offset
}
%
801
\edef
\p_location
{
\mathstackersparameter
\c!location
}
%
802
\edef
\p_strut
{
\mathstackersparameter
\c!strut
}
%
803
\edef
\p_alternative
{
\mathstackersparameter
\c!alternative
}
%
804
%
805
\scratchleftoffset
\zeropoint
806
\scratchrightoffset
\zeropoint
807
%
808
\edef
\m_math_stackers_text_middle
{
#
text
}
%
809
\math_stackers_check_unicode
{
#
codepoint
}
%
810
\scratchunicode
#
codepoint
\relax
811
%
812
\ifx
\math_stackers_middle
\empty
813
\setbox
\scratchboxthree
\emptyhbox
814
\else
815
\setmathtextbox
\scratchboxthree
\hbox
{
\math_stackers_middletext
}
%
816
\fi
817
%
818
\ifcase
#
where
\relax
819
\edef
\m_math_stackers_text_top
{
#
extra
}
%
820
\ifx
\math_stackers_top
\empty
821
\setbox
\scratchboxone
\emptyhbox
822
\else
823
\setmathsmalltextbox
\scratchboxone
\hbox
{
\math_stackers_toptext
}
%
824
\fi
825
\else
826
\edef
\m_math_stackers_text_bottom
{
#
extra
}
%
827
\ifx
\math_stackers_bottom
\empty
828
\setbox
\scratchboxone
\emptyhbox
829
\else
830
\setmathsmalltextbox
\scratchboxone
\hbox
{
\math_stackers_bottomtext
}
%
831
\fi
832
\fi
833
%
834
\scratchwidth
\wd
835
\ifdim
\wd
\scratchboxone
>
\wd
\scratchboxthree
836
\scratchboxone
837
\else
838
\scratchboxthree
839
\fi
840
\relax
841
\scratchdimen
\mathstackersparameter
\c!minwidth
\relax
842
\ifdim
\scratchwidth
<
\scratchdimen
843
\scratchwidth
\scratchdimen
844
\fi
845
\advance
\scratchwidth
2
\scratchhoffset
846
%
847
\ifdim
\wd
\scratchboxone
<
\scratchwidth
848
\setbox
\scratchboxone
\hpack
to
\scratchwidth
{
\hss
\unhbox
\scratchboxone
\hss
}
%
849
\fi
850
\ifdim
\wd
\scratchboxthree
<
\scratchwidth
851
\setbox
\scratchboxthree
\hpack
to
\scratchwidth
{
\hss
\unhbox
\scratchboxthree
\hss
}
%
852
\fi
853
%
854
\math_stackers_normalize_three
855
% analysis
856
\dosettagproperty
\s!subtype
\t!munderover
857
% base
858
\math_stackers_start_tagged_mid
859
\math_stackers_middle
\bgroup
860
\box
\scratchboxthree
861
\egroup
862
\math_stackers_stop_tagged
863
%
864
\setbox
\scratchboxtwo
\csname
\??mathstackersalternative
\p_alternative
\endcsname
865
\kern
-
\scratchwidth
866
\ifcase
#
where
\relax
867
% under
868
\math_stackers_start_tagged_bot
869
\math_stackers_bottom
\bgroup
870
\lower
\dimexpr
871
\scratchdepth
872
+
\ht
\scratchboxtwo
873
+
\mathstackersparameter
\c!distance
874
\relax
875
\box
\scratchboxtwo
% accent
876
\egroup
877
\math_stackers_stop_tagged
878
\kern
-
\scratchwidth
879
% over
880
\math_stackers_start_tagged_top
881
\math_stackers_top
\bgroup
882
\raise
\dimexpr
883
\scratchheight
884
+
\dp
\scratchboxone
885
+
\mathstackersparameter
\c!voffset
886
\relax
887
\box
\scratchboxone
% toptext
888
\egroup
889
\math_stackers_stop_tagged
890
\else
891
% under
892
\math_stackers_start_tagged_bot
893
\math_stackers_bottom
\bgroup
894
\lower
\dimexpr
895
\scratchdepth
896
+
\ht
\scratchboxone
897
+
\mathstackersparameter
\c!voffset
898
\relax
899
\box
\scratchboxone
% bottext
900
\egroup
901
\math_stackers_stop_tagged
902
\kern
-
\scratchwidth
903
% over
904
\math_stackers_start_tagged_top
905
\math_stackers_top
\bgroup
906
\raise
\dimexpr
907
\scratchheight
908
+
\dp
\scratchboxtwo
% new
909
+
\mathstackersparameter
\c!distance
910
\relax
911
\box
\scratchboxtwo
% accent
912
\egroup
913
\math_stackers_stop_tagged
914
\fi
915
}
%
916
\dostoptagged
917
\mathstackersparameter
\c!right
\relax
918
\math_stackers_stop_group
}
919 920
\unexpanded
\def
\definemathovertextextensible
{
\dotripleempty
\math_extensibles_define_over_text
}
921
\unexpanded
\def
\definemathundertextextensible
{
\dotripleempty
\math_extensibles_define_under_text
}
922 923
\def
\math_extensibles_define_over_text
[
#
1
]
[
#
2
]
[
#
3
]
%
924
{
\ifthirdargument
925
\setuevalue
{
#
2
}
{
\math_stackers_make_double_text
\plusone
{
#
1
}
{
\number
#
3
}
}
%
926
\else
927
\setuevalue
{
#
1
}
{
\math_stackers_make_double_text
\plusone
\noexpand
\currentmathstackers
{
\number
#
2
}
}
%
928
\fi
}
929 930
\def
\math_extensibles_define_under_text
[
#
1
]
[
#
2
]
[
#
3
]
%
931
{
\ifthirdargument
932
\setuevalue
{
#
2
}
{
\math_stackers_make_double_text
\zerocount
{
#
1
}
{
\number
#
3
}
}
%
933
\else
934
\setuevalue
{
#
1
}
{
\math_stackers_make_double_text
\zerocount
\noexpand
\currentmathstackers
{
\number
#
2
}
}
%
935
\fi
}
936 937
\unexpanded
\def
\mathovertext
{
\begingroup
\dosingleempty
\math_stackers_handle_over_text
}
938
\unexpanded
\def
\mathundertext
{
\begingroup
\dosingleempty
\math_stackers_handle_under_text
}
939 940
\def
\math_stackers_handle_over_text
[
#
category
]
%
941
{
\math_stackers_direct_double_text
\plusone
{
\iffirstargument
#
category
\else
\v!top
\fi
}
}
% will be defined later on
942 943
\def
\math_stackers_handle_under_text
[
#
category
]
%
944
{
\math_stackers_direct_double_text
\zerocount
{
\iffirstargument
#
category
\else
\v!bottom
\fi
}
}
% will be defined later on
945 946
\def
\math_stackers_direct_double_text
#
where
#
category
#
codepoint
#
text
#
extra
%%
947
{
\math_stackers_make_double_text
#
where
{
#
category
}
{
#
codepoint
}
{
#
text
}
{
#
extra
}
%
948
\endgroup
}
949 950
%D Here is a bonus macro that takes three texts. It can be used to get consistent
951
%D mixed usage.
952 953
\unexpanded
\def
\mathtriplet
954
{
\begingroup
955
\dosingleempty
\math_stackers_handle_triplet
}
956 957
\def
\math_stackers_handle_triplet
[
#
category
]
#
middletext
#
toptext
#
bottomtext
%
958
{
\math_stackers_triplet
\plusone
{
\iffirstargument
#
category
\else
\currentmathstackers
\fi
}
{
#
middletext
}
{
#
toptext
}
{
#
bottomtext
}
%
959
\endgroup
}
960 961
\unexpanded
\def
\definemathtriplet
962
{
\dotripleempty
\math_stackers_define_triplet
}
963 964
\def
\math_stackers_define_triplet
[
#
1
]
[
#
2
]
[
#
3
]
% category name default
965
{
\ifthirdargument
966
\setuevalue
{
#
2
}
{
\math_stackers_auto_triplet_yes
{
#
1
}
{
#
3
}
}
%
967
\else
\ifsecondargument
968
\setuevalue
{
#
2
}
{
\math_stackers_auto_triplet_nop
{
#
1
}
}
%
969
\else
970
\setuevalue
{
#
1
}
{
\math_stackers_auto_triplet_nop
\noexpand
\currentmathstackers
}
%
971
\fi
\fi
}
972 973
\unexpanded
\def
\math_stackers_auto_triplet_yes
#
category
#
middletext
%
974
{
\begingroup
975
\edef
\currentmathstackers
{
#
category
}
%
976
\def
\m_math_stackers_text_middle
{
#
middletext
}
%
977
\dosingleempty
\math_stackers_auto_triplet_yes_first
}
978 979
\unexpanded
\def
\math_stackers_auto_triplet_yes_first
[
#
category
]
% [#2]% #2 gobble spaces
980
{
\iffirstargument
\edef
\currentmathstackers
{
#
category
}
\fi
981
\permitspacesbetweengroups
982
\dodoublegroupempty
\math_stackers_auto_triplet_yes_second
}
983 984
\def
\math_stackers_auto_triplet_yes_second
#
toptext
#
bottomtext
%
985
{
\math_stackers_triplet
\plusone
\currentmathstackers
\m_math_stackers_text_middle
{
#
toptext
}
{
#
bottomtext
}
%
986
\endgroup
}
987 988
\unexpanded
\def
\math_stackers_auto_triplet_nop
#
category
%
989
{
\begingroup
990
\edef
\currentmathstackers
{
#
category
}
%
991
\dosingleempty
\math_stackers_auto_triplet_nop_first
}
992 993
\unexpanded
\def
\math_stackers_auto_triplet_nop_first
[
#
category
]
% [#2]% #2 gobble spaces
994
{
\iffirstargument
\edef
\currentmathstackers
{
#
category
}
\fi
995
\permitspacesbetweengroups
996
\dotriplegroupempty
\math_stackers_auto_triplet_nop_second
}
997 998
\def
\math_stackers_auto_triplet_nop_second
#
middletext
#
toptext
#
bottomtext
%
999
{
\math_stackers_triplet
\plusone
\currentmathstackers
{
#
middletext
}
{
#
toptext
}
{
#
bottomtext
}
%
1000
\endgroup
}
1001 1002
%D Definitions:
1003 1004
\definemathstackers
1005
[
\v!mathematics
]
1006
[
\c!topcommand
=
\mathematics
,
1007
\c!middlecommand
=
\mathematics
,
1008
\c!bottomcommand
=
\mathematics
]
1009 1010
\definemathstackers
1011
[
\s!math
]
1012
[
\v!mathematics
]
1013 1014
\definemathstackers
1015
[
\v!text
]
1016
[
\v!mathematics
]
1017
[
\c!topcommand
=
,
1018
\c!middlecommand
=
\mathematics
,
1019
\c!bottomcommand
=
]
1020 1021
\definemathstackers
1022
[
\v!reverse
]
1023
[
\v!mathematics
]
1024
[
\c!order
=
\v!reverse
]
1025 1026
\definemathstackers
1027
[
\v!both
]
1028
[
\v!mathematics
]
1029
[
\c!location
=
\v!top
,
% ?
1030
\c!strut
=
\v!no
,
1031
\c!middlecommand
=
\mathematics
,
1032
\c!hoffset
=
\zeropoint
]
1033 1034
\definemathstackers
1035
[
\v!top
]
1036
[
\v!both
]
1037 1038
\definemathstackers
1039
[
\v!bottom
]
1040
[
\v!both
]
1041 1042
\definemathstackers
1043
[
\v!vfenced
]
1044
[
\v!both
]
1045
[
\c!mathclass
=
\s!ord
,
1046
\c!mathlimits
=
\v!yes
]
1047 1048
% these are needed for mathml:
1049 1050
% \setupmathstackers
1051
% [\v!both]
1052
% [\c!hoffset=1pt,
1053
% \c!voffset=1pt]
1054 1055
\definemathstackers
1056
[
\v!bothtext
]
1057
[
\v!both
]
1058
[
\c!strut
=
\v!yes
]
1059 1060
% These are compatibity definitions, math only.
1061 1062
% todo: top= bottom= middle= is nicer (compare math-fen)
1063 1064
%D We save a few definitions that we automatically got from the \type {char-def.lua}
1065
%D database.
1066 1067
% Be careful in choosing what accents you take (the code below uses a combining
1068
% one):
1069
%
1070
% \startbuffer
1071
% % $\Umathaccent top 0 0 "20D7 {example}$
1072
% % $\Umathaccent top fixed 0 0 "20D7 {example}$
1073
% $\Umathaccent 0 0 "20D7 {example}$
1074
% $\Umathaccent fixed 0 0 "20D7 {example}$
1075
% $\Umathaccent bottom 0 0 "20D7 {example}$
1076
% $\Umathaccent bottom fixed 0 0 "20D7 {example}$
1077
% $\Umathaccent both 0 0 "20D7
1078
% 0 0 "20D7 {example}$
1079
% $\Umathaccent both fixed 0 0 "20D7
1080
% fixed 0 0 "20D7 {example}$
1081
% $\Umathaccent both 0 0 "20D7
1082
% fixed 0 0 "20D7 {example}$
1083
% $\Umathaccent both fixed 0 0 "20D7
1084
% 0 0 "20D7 {example}$
1085
% \stopbuffer
1086
%
1087
% \setupbodyfont[modern] \getbuffer
1088
% \setupbodyfont[xits] \getbuffer
1089
% \setupbodyfont[cambria] \getbuffer
1090 1091
\unexpanded
\def
\normaldoublebrace
{
\Umathaccents
0
\defaultmathfamily
"
2
3
DE
0
\defaultmathfamily
"
2
3
DF
}
1092
\unexpanded
\def
\normaldoubleparent
{
\Umathaccents
0
\defaultmathfamily
"
2
3
DC
0
\defaultmathfamily
"
2
3
DD
}
1093 1094
% let's keep this
1095 1096
\let
\normaloverbrace
\overbrace
1097
\let
\normalunderbrace
\underbrace
1098
\let
\normaloverparent
\overparent
1099
\let
\normalunderparent
\underparent
1100
\let
\normaloverbracket
\overbracket
1101
\let
\normalunderbracket
\underbracket
1102
\let
\normalunderleftarrow
\underleftarrow
1103
\let
\normaloverleftarrow
\overleftarrow
1104
\let
\normalunderrightarrow
\underrightarrow
1105
\let
\normaloverrightarrow
\overrightarrow
1106 1107
%D Here come the new ones:
1108 1109
\definemathstackers
[
\v!none
]
[
\v!mathematics
]
[
\c!hoffset
=
\zeropoint
]
1110
\definemathstackers
[
\v!normal
]
[
\v!mathematics
]
[
\c!hoffset
=
0
.
5
\mathemwidth
]
% the default
1111
\definemathstackers
[
\v!small
]
[
\v!mathematics
]
[
\c!hoffset
=
1
\mathemwidth
]
1112
\definemathstackers
[
\v!medium
]
[
\v!mathematics
]
[
\c!hoffset
=
1
.
5
\mathemwidth
]
1113
\definemathstackers
[
\v!big
]
[
\v!mathematics
]
[
\c!hoffset
=
2
\mathemwidth
]
1114 1115
\definemathextensible
[
\v!reverse
]
[
xrel
]
[
"
0
0
2
D
]
1116
\definemathextensible
[
\v!reverse
]
[
xequal
]
[
"
0
0
3
D
]
1117
\definemathextensible
[
\v!reverse
]
[
xleftarrow
]
[
"
2
1
9
0
]
% ["27F5]
1118
\definemathextensible
[
\v!reverse
]
[
xrightarrow
]
[
"
2
1
9
2
]
% ["27F6]
1119
\definemathextensible
[
\v!reverse
]
[
xleftrightarrow
]
[
"
2
7
F
7
]
1120
\definemathextensible
[
\v!reverse
]
[
xLeftarrow
]
[
"
2
7
F
8
]
1121
\definemathextensible
[
\v!reverse
]
[
xRightarrow
]
[
"
2
7
F
9
]
1122
\definemathextensible
[
\v!reverse
]
[
xLeftrightarrow
]
[
"
2
7
FA
]
1123
\definemathextensible
[
\v!reverse
]
[
xtwoheadleftarrow
]
[
"
2
1
9
E
]
1124
\definemathextensible
[
\v!reverse
]
[
xtwoheadrightarrow
]
[
"
2
1
A
0
]
1125
\definemathextensible
[
\v!reverse
]
[
xmapsto
]
[
"
2
1
A
6
]
1126
\definemathextensible
[
\v!reverse
]
[
xhookleftarrow
]
[
"
2
1
A
9
]
1127
\definemathextensible
[
\v!reverse
]
[
xhookrightarrow
]
[
"
2
1
AA
]
1128
\definemathextensible
[
\v!reverse
]
[
xleftharpoondown
]
[
"
2
1
BD
]
1129
\definemathextensible
[
\v!reverse
]
[
xleftharpoonup
]
[
"
2
1
BC
]
1130
\definemathextensible
[
\v!reverse
]
[
xrightharpoondown
]
[
"
2
1
C
1
]
1131
\definemathextensible
[
\v!reverse
]
[
xrightharpoonup
]
[
"
2
1
C
0
]
1132
\definemathextensible
[
\v!reverse
]
[
xrightoverleftarrow
]
[
"
2
1
C
4
]
1133
\definemathextensible
[
\v!reverse
]
[
xleftrightharpoons
]
[
"
2
1
CB
]
1134
\definemathextensible
[
\v!reverse
]
[
xrightleftharpoons
]
[
"
2
1
CC
]
1135
\definemathextensible
[
\v!reverse
]
[
xtriplerel
]
[
"
2
2
6
1
]
1136 1137
\definemathextensible
[
\v!mathematics
]
[
mrel
]
[
"
0
0
2
D
]
1138
\definemathextensible
[
\v!mathematics
]
[
mequal
]
[
"
0
0
3
D
]
1139
\definemathextensible
[
\v!mathematics
]
[
mleftarrow
]
[
"
2
1
9
0
]
% ["27F5]
1140
\definemathextensible
[
\v!mathematics
]
[
mrightarrow
]
[
"
2
1
9
2
]
% ["27F6]
1141
\definemathextensible
[
\v!mathematics
]
[
mleftrightarrow
]
[
"
2
7
F
7
]
1142
\definemathextensible
[
\v!mathematics
]
[
mLeftarrow
]
[
"
2
7
F
8
]
1143
\definemathextensible
[
\v!mathematics
]
[
mRightarrow
]
[
"
2
7
F
9
]
1144
\definemathextensible
[
\v!mathematics
]
[
mLeftrightarrow
]
[
"
2
7
FA
]
1145
\definemathextensible
[
\v!mathematics
]
[
mtwoheadleftarrow
]
[
"
2
1
9
E
]
1146
\definemathextensible
[
\v!mathematics
]
[
mtwoheadrightarrow
]
[
"
2
1
A
0
]
1147
\definemathextensible
[
\v!mathematics
]
[
mmapsto
]
[
"
2
1
A
6
]
1148
\definemathextensible
[
\v!mathematics
]
[
mhookleftarrow
]
[
"
2
1
A
9
]
1149
\definemathextensible
[
\v!mathematics
]
[
mhookrightarrow
]
[
"
2
1
AA
]
1150
\definemathextensible
[
\v!mathematics
]
[
mleftharpoondown
]
[
"
2
1
BD
]
1151
\definemathextensible
[
\v!mathematics
]
[
mleftharpoonup
]
[
"
2
1
BC
]
1152
\definemathextensible
[
\v!mathematics
]
[
mrightharpoondown
]
[
"
2
1
C
1
]
1153
\definemathextensible
[
\v!mathematics
]
[
mrightharpoonup
]
[
"
2
1
C
0
]
1154
\definemathextensible
[
\v!mathematics
]
[
mrightoverleftarrow
]
[
"
2
1
C
4
]
1155
\definemathextensible
[
\v!mathematics
]
[
mleftrightharpoons
]
[
"
2
1
CB
]
1156
\definemathextensible
[
\v!mathematics
]
[
mrightleftharpoons
]
[
"
2
1
CC
]
1157
\definemathextensible
[
\v!mathematics
]
[
mtriplerel
]
[
"
2
2
6
1
]
1158 1159
\definemathextensible
[
\v!mathematics
]
[
eleftarrowfill
]
[
"
2
1
9
0
]
% ["27F5]
1160
\definemathextensible
[
\v!mathematics
]
[
erightarrowfill
]
[
"
2
1
9
2
]
% ["27F6]
1161
\definemathextensible
[
\v!mathematics
]
[
eleftrightarrowfill
]
[
"
2
7
F
7
]
1162
\definemathextensible
[
\v!mathematics
]
[
etwoheadrightarrowfill
]
[
"
2
7
F
9
]
1163
\definemathextensible
[
\v!mathematics
]
[
eleftharpoondownfill
]
[
"
2
1
BD
]
1164
\definemathextensible
[
\v!mathematics
]
[
eleftharpoonupfill
]
[
"
2
1
BC
]
1165
\definemathextensible
[
\v!mathematics
]
[
erightharpoondownfill
]
[
"
2
1
C
1
]
1166
\definemathextensible
[
\v!mathematics
]
[
erightharpoonupfill
]
[
"
2
1
C
0
]
1167 1168
\definemathextensible
[
\v!mathematics
]
[
eoverbarfill
]
[
"
FE
3
3
E
]
1169
\definemathextensible
[
\v!mathematics
]
[
eunderbarfill
]
[
"
FE
3
3
F
]
1170
\definemathextensible
[
\v!mathematics
]
[
eoverbracefill
]
[
"
FE
3
DE
]
1171
\definemathextensible
[
\v!mathematics
]
[
eunderbracefill
]
[
"
FE
3
DF
]
1172
\definemathextensible
[
\v!mathematics
]
[
eoverparentfill
]
[
"
FE
3
DC
]
1173
\definemathextensible
[
\v!mathematics
]
[
eunderparentfill
]
[
"
FE
3
DD
]
1174
\definemathextensible
[
\v!mathematics
]
[
eoverbracketfill
]
[
"
FE
3
B
4
]
1175
\definemathextensible
[
\v!mathematics
]
[
eunderbracketfill
]
[
"
FE
3
B
5
]
1176 1177
\definemathextensible
[
\v!text
]
[
trel
]
[
"
0
0
2
D
]
1178
\definemathextensible
[
\v!text
]
[
tequal
]
[
"
0
0
3
D
]
1179
\definemathextensible
[
\v!text
]
[
tmapsto
]
[
"
2
1
A
6
]
1180
\definemathextensible
[
\v!text
]
[
tleftarrow
]
[
"
2
1
9
0
]
% ["27F5]
1181
\definemathextensible
[
\v!text
]
[
trightarrow
]
[
"
2
1
9
2
]
% ["27F6]
1182
\definemathextensible
[
\v!text
]
[
tleftrightarrow
]
[
"
2
7
F
7
]
1183
\definemathextensible
[
\v!text
]
[
tLeftarrow
]
[
"
2
7
F
8
]
1184
\definemathextensible
[
\v!text
]
[
tRightarrow
]
[
"
2
7
F
9
]
1185
\definemathextensible
[
\v!text
]
[
tLeftrightarrow
]
[
"
2
7
FA
]
1186
\definemathextensible
[
\v!text
]
[
ttwoheadleftarrow
]
[
"
2
1
9
E
]
1187
\definemathextensible
[
\v!text
]
[
ttwoheadrightarrow
]
[
"
2
1
A
0
]
1188
\definemathextensible
[
\v!text
]
[
thookleftarrow
]
[
"
2
1
A
9
]
1189
\definemathextensible
[
\v!text
]
[
thookrightarrow
]
[
"
2
1
AA
]
1190
\definemathextensible
[
\v!text
]
[
tleftharpoondown
]
[
"
2
1
BD
]
1191
\definemathextensible
[
\v!text
]
[
tleftharpoonup
]
[
"
2
1
BC
]
1192
\definemathextensible
[
\v!text
]
[
trightharpoondown
]
[
"
2
1
C
1
]
1193
\definemathextensible
[
\v!text
]
[
trightharpoonup
]
[
"
2
1
C
0
]
1194
\definemathextensible
[
\v!text
]
[
trightoverleftarrow
]
[
"
2
1
C
4
]
1195
\definemathextensible
[
\v!text
]
[
tleftrightharpoons
]
[
"
2
1
CB
]
1196
\definemathextensible
[
\v!text
]
[
trightleftharpoons
]
[
"
2
1
CC
]
1197
\definemathextensible
[
\v!text
]
[
ttriplerel
]
[
"
2
2
6
1
]
1198 1199
\definemathoverextensible
[
\v!top
]
[
overleftarrow
]
[
"
2
1
9
0
]
% ["27F5]
1200
\definemathoverextensible
[
\v!top
]
[
overrightarrow
]
[
"
2
1
9
2
]
% ["27F6]
1201
\definemathoverextensible
[
\v!top
]
[
overleftrightarrow
]
[
"
2
7
F
7
]
1202
\definemathoverextensible
[
\v!top
]
[
overtwoheadleftarrow
]
[
"
2
7
F
8
]
1203
\definemathoverextensible
[
\v!top
]
[
overtwoheadrightarrow
]
[
"
2
7
F
9
]
1204
\definemathoverextensible
[
\v!top
]
[
overleftharpoondown
]
[
"
2
1
BD
]
1205
\definemathoverextensible
[
\v!top
]
[
overleftharpoonup
]
[
"
2
1
BC
]
1206
\definemathoverextensible
[
\v!top
]
[
overrightharpoondown
]
[
"
2
1
C
1
]
1207
\definemathoverextensible
[
\v!top
]
[
overrightharpoonup
]
[
"
2
1
C
0
]
1208 1209
\definemathunderextensible
[
\v!bottom
]
[
underleftarrow
]
[
"
2
1
9
0
]
% ["27F5]
1210
\definemathunderextensible
[
\v!bottom
]
[
underrightarrow
]
[
"
2
1
9
2
]
% ["27F6]
1211
\definemathunderextensible
[
\v!bottom
]
[
underleftrightarrow
]
[
"
2
7
F
7
]
1212
\definemathunderextensible
[
\v!bottom
]
[
undertwoheadleftarrow
]
[
"
2
7
F
8
]
1213
\definemathunderextensible
[
\v!bottom
]
[
undertwoheadrightarrow
]
[
"
2
7
F
9
]
1214
\definemathunderextensible
[
\v!bottom
]
[
underleftharpoondown
]
[
"
2
1
BD
]
1215
\definemathunderextensible
[
\v!bottom
]
[
underleftharpoonup
]
[
"
2
1
BC
]
1216
\definemathunderextensible
[
\v!bottom
]
[
underrightharpoondown
]
[
"
2
1
C
1
]
1217
\definemathunderextensible
[
\v!bottom
]
[
underrightharpoonup
]
[
"
2
1
C
0
]
1218 1219
% We don't use overline and underline. This is one of the overlooked aspects of
1220
% unicode cq. opentype math: why treat rules different than e.g. arrows and
1221
% accents. It is a bit unfortunate that the opportunity to move math to new
1222
% technologies happened outside the tex domain (and/or some aspects were kept while
1223
% in fact they were side effects of limitations of traditional fonts). From the
1224
% unicode aware tex engines' implementation point of view things could have been
1225
% done a bit nicer but then: the community didn't seem to care too much and just
1226
% has to follow now.
1227
%
1228
% Anyhow, we use a character based approach so that at least we get unicode stuff
1229
% in the backend (okay, we still need to deal with some cut and paste issues but at
1230
% least we now know what we deal with.
1231 1232
% alternatively we can move the original to FE*
1233 1234
\definemathoverextensible
[
\v!vfenced
]
[
overbar
]
[
"
FE
3
3
E
]
% ["203E]
1235
\definemathunderextensible
[
\v!vfenced
]
[
underbar
]
[
"
FE
3
3
F
]
% ["203E]
1236
\definemathdoubleextensible
[
\v!vfenced
]
[
doublebar
]
[
"
FE
3
3
E
]
[
"
FE
3
3
F
]
1237 1238
\definemathoverextensible
[
\v!vfenced
]
[
overbrace
]
[
"
FE
3
DE
]
% ["023DE]
1239
\definemathunderextensible
[
\v!vfenced
]
[
underbrace
]
[
"
FE
3
DF
]
% ["023DF]
1240
\definemathdoubleextensible
[
\v!vfenced
]
[
doublebrace
]
[
"
FE
3
DE
]
[
"
FE
3
DF
]
1241 1242
\definemathoverextensible
[
\v!vfenced
]
[
overparent
]
[
"
FE
3
DC
]
% ["023DC]
1243
\definemathunderextensible
[
\v!vfenced
]
[
underparent
]
[
"
FE
3
DD
]
% ["023DD]
1244
\definemathdoubleextensible
[
\v!vfenced
]
[
doubleparent
]
[
"
FE
3
DC
]
[
"
FE
3
DD
]
1245 1246
\definemathoverextensible
[
\v!vfenced
]
[
overbracket
]
[
"
FE
3
B
4
]
% ["023B4]
1247
\definemathunderextensible
[
\v!vfenced
]
[
underbracket
]
[
"
FE
3
B
5
]
% ["023B5]
1248
\definemathdoubleextensible
[
\v!vfenced
]
[
doublebracket
]
[
"
FE
3
B
4
]
[
"
FE
3
B
5
]
1249 1250
% \unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits}
1251 1252
%D For mathml:
1253 1254
\definemathdoubleextensible
[
\v!both
]
[
overbarunderbar
]
[
"
FE
3
3
E
]
[
"
FE
3
3
F
]
1255
\definemathdoubleextensible
[
\v!both
]
[
overbraceunderbrace
]
[
"
FE
3
DE
]
[
"
FE
3
DF
]
1256
\definemathdoubleextensible
[
\v!both
]
[
overparentunderparent
]
[
"
FE
3
DC
]
[
"
FE
3
DD
]
1257
\definemathdoubleextensible
[
\v!both
]
[
overbracketunderbracket
]
[
"
FE
3
B
4
]
[
"
FE
3
B
5
]
1258 1259
\definemathovertextextensible
[
\v!bothtext
]
[
overbartext
]
[
"
FE
3
3
E
]
1260
\definemathundertextextensible
[
\v!bothtext
]
[
underbartext
]
[
"
FE
3
3
F
]
1261
\definemathovertextextensible
[
\v!bothtext
]
[
overbracetext
]
[
"
FE
3
DE
]
1262
\definemathundertextextensible
[
\v!bothtext
]
[
underbracetext
]
[
"
FE
3
DF
]
1263
\definemathovertextextensible
[
\v!bothtext
]
[
overparenttext
]
[
"
FE
3
DC
]
1264
\definemathundertextextensible
[
\v!bothtext
]
[
underparenttext
]
[
"
FE
3
DD
]
1265
\definemathovertextextensible
[
\v!bothtext
]
[
overbrackettext
]
[
"
FE
3
B
4
]
1266
\definemathundertextextensible
[
\v!bothtext
]
[
underbrackettext
]
[
"
FE
3
B
5
]
1267 1268
%D Some bonus ones (for the moment here):
1269 1270
\definemathstackers
1271
[
\v!chemistry
]
1272
[
\c!offset
=
\v!max
,
1273
\c!left
=
\enspace
,
1274
\c!right
=
\enspace
,
1275
\c!hoffset
=
.
5
\mathemwidth
]
1276 1277
\definemathextensible
[
\v!chemistry
]
[
cleftarrow
]
[
"
2
1
9
0
]
1278
\definemathextensible
[
\v!chemistry
]
[
crightarrow
]
[
"
2
1
9
2
]
1279
\definemathextensible
[
\v!chemistry
]
[
crightoverleftarrow
]
[
"
2
1
C
4
]
1280 1281
% for the moment:
1282 1283
\def
\math_stackers_hacked_fill
#
1
#
2
#
3
%
1284
{
\mathematics
1285
{
\begingroup
1286
\mathsurround
\zeropoint
1287
\thickmuskip
\zeromuskip
1288
\medmuskip
\zeromuskip
1289
\thinmuskip
\zeromuskip
1290
#
1
%
1291
\mkern
-
7
\onemuskip
1292
\cleaders
\mathstylehbox
{
\mkern
-
2
\onemuskip
#
2
\mkern
-
2
\onemuskip
}
\hfill
1293
\mkern
-
7
\onemuskip
1294
#
3
%
1295
\endgroup
}
}
1296 1297
% These will be defined in char-def as well once we have \leaders<number>
1298 1299
\unexpanded
\def
\rightarrowfill
{
\math_stackers_hacked_fill
\relbar
\relbar
\rightarrow
}
1300
\unexpanded
\def
\leftarrowfill
{
\math_stackers_hacked_fill
\leftarrow
\relbar
\relbar
}
1301
\unexpanded
\def
\rightoverleftarrowfill
{
\math_stackers_hacked_fill
\ctxdoublearrowfillleftend
\ctxdoublearrowfillmiddlepart
\ctxdoublearrowfillrightend
}
1302
\unexpanded
\def
\equalfill
{
\math_stackers_hacked_fill
\Relbar
\Relbar
\Relbar
}
1303
\unexpanded
\def
\Rightarrowfill
{
\math_stackers_hacked_fill
\Relbar
\Relbar
\Rightarrow
}
1304
\unexpanded
\def
\Leftarrowfill
{
\math_stackers_hacked_fill
\Leftarrow
\Relbar
\Relbar
}
1305
\unexpanded
\def
\Leftrightarrowfill
{
\math_stackers_hacked_fill
\Leftarrow
\Relbar
\Rightarrow
}
1306
\unexpanded
\def
\leftrightarrowfill
{
\math_stackers_hacked_fill
\leftarrow
\relbar
\rightarrow
}
1307
\unexpanded
\def
\mapstofill
{
\math_stackers_hacked_fill
{
\mapstochar
\relbar
}
\relbar
\rightarrow
}
1308
\unexpanded
\def
\twoheadrightarrowfill
{
\math_stackers_hacked_fill
\relbar
\relbar
\twoheadrightarrow
}
1309
\unexpanded
\def
\twoheadleftarrowfill
{
\math_stackers_hacked_fill
\twoheadleftarrow
\relbar
\relbar
}
1310
\unexpanded
\def
\rightharpoondownfill
{
\math_stackers_hacked_fill
\relbar
\relbar
\rightharpoondown
}
1311
\unexpanded
\def
\rightharpoonupfill
{
\math_stackers_hacked_fill
\relbar
\relbar
\rightharpoonup
}
1312
\unexpanded
\def
\leftharpoondownfill
{
\math_stackers_hacked_fill
\leftharpoondown
\relbar
\relbar
}
1313
\unexpanded
\def
\leftharpoonupfill
{
\math_stackers_hacked_fill
\leftharpoonup
\relbar
\relbar
}
1314
\unexpanded
\def
\hookleftfill
{
\math_stackers_hacked_fill
\leftarrow
\relbar
{
\relbar
\joinrel
\rhook
}
}
1315
\unexpanded
\def
\hookrightfill
{
\math_stackers_hacked_fill
{
\lhook
\joinrel
\relbar
}
\relbar
\rightarrow
}
1316
\unexpanded
\def
\relfill
{
\math_stackers_hacked_fill
\relbar
\relbar
\relbar
}
1317
\unexpanded
\def
\triplerelfill
{
\math_stackers_hacked_fill
\equiv
\equiv
\equiv
}
1318 1319
\unexpanded
\def
\singlebond
{
{
\xrel
}
}
% or \def\singlebond{{\xrel[2]}}
1320
\unexpanded
\def
\doublebond
{
{
\xequal
}
}
1321
\unexpanded
\def
\triplebond
{
{
\xtriplerel
}
}
1322 1323
\unexpanded
\def
\defineextensiblefiller
1324
{
\dodoubleargument
\math_stackers_define_filler
}
1325 1326
% \def\math_stackers_define_filler[#1][#2]%
1327
% {\setuevalue{#1}{\leaders\number#2\hfill}}
1328 1329
%D For the moment (needs checking):
1330 1331
\def
\math_stackers_define_filler
[
#
1
]
[
#
2
]
%
1332
{
\expandafter
\let
\csname
\??mathextensiblefallbacks
\number
#
2
\expandafter
\endcsname
\csname
#
1
\endcsname
1333
\expandafter
\let
\csname
#
1
\expandafter
\endcsname
\csname
#
1
\endcsname
}
% huh?
1334 1335
\defineextensiblefiller
[
barfill
]
[
"
2
0
3
E
]
1336
\defineextensiblefiller
[
relfill
]
[
"
0
0
2
D
]
1337
\defineextensiblefiller
[
equalfill
]
[
"
0
0
3
D
]
1338
\defineextensiblefiller
[
leftarrowfill
]
[
"
2
1
9
0
]
1339
\defineextensiblefiller
[
rightarrowfill
]
[
"
2
1
9
2
]
1340
\defineextensiblefiller
[
twoheadleftarrowfill
]
[
"
2
1
9
E
]
1341
\defineextensiblefiller
[
twoheadrightarrowfill
]
[
"
2
1
A
0
]
1342
\defineextensiblefiller
[
mapstofill
]
[
"
2
1
A
6
]
1343
\defineextensiblefiller
[
hookleftarrowfill
]
[
"
2
1
A
9
]
1344
\defineextensiblefiller
[
hookrightarrowfill
]
[
"
2
1
AA
]
1345
\defineextensiblefiller
[
leftharpoondownfill
]
[
"
2
1
BD
]
1346
\defineextensiblefiller
[
leftharpoonupfill
]
[
"
2
1
BC
]
1347
\defineextensiblefiller
[
rightharpoondownfill
]
[
"
2
1
C
1
]
1348
\defineextensiblefiller
[
rightharpoonupfill
]
[
"
2
1
C
0
]
1349
\defineextensiblefiller
[
rightoverleftarrowfill
]
[
"
2
1
C
4
]
1350
\defineextensiblefiller
[
leftrightharpoonsfill
]
[
"
2
1
CB
]
1351
\defineextensiblefiller
[
rightleftharpoonsfill
]
[
"
2
1
CC
]
1352
\defineextensiblefiller
[
triplerelfill
]
[
"
2
2
6
1
]
1353
\defineextensiblefiller
[
leftrightarrowfill
]
[
"
2
7
F
7
]
1354
\defineextensiblefiller
[
Leftarrowfill
]
[
"
2
7
F
8
]
1355
\defineextensiblefiller
[
Rightarrowfill
]
[
"
2
7
F
9
]
1356
\defineextensiblefiller
[
Leftrightarrowfill
]
[
"
2
7
FA
]
1357
\defineextensiblefiller
[
Leftrightarrowfill
]
[
"
2
7
FA
]
1358 1359
%defineextensiblefiller [overbarfill] ["FE33E] % untested
1360
%defineextensiblefiller [underbarfill] ["FE33F] % untested
1361
\defineextensiblefiller
[
overbracefill
]
[
"
FE
3
DE
]
% untested
1362
\defineextensiblefiller
[
underbracefill
]
[
"
FE
3
DF
]
% untested
1363
\defineextensiblefiller
[
overparentfill
]
[
"
FE
3
DC
]
% untested
1364
\defineextensiblefiller
[
underparentfill
]
[
"
FE
3
DD
]
% untested
1365
\defineextensiblefiller
[
overbracketfill
]
[
"
FE
3
B
4
]
% untested
1366
\defineextensiblefiller
[
underbracketfill
]
[
"
FE
3
B
5
]
% untested
1367 1368
%D Extra:
1369 1370
\unexpanded
\edef
\singlebond
{
\mathematics
{
\mathsurround
\zeropoint
\char
\number
"
0
0
2
D
\relax
}
}
1371
\unexpanded
\edef
\doublebond
{
\mathematics
{
\mathsurround
\zeropoint
\char
\number
"
0
0
3
D
\relax
}
}
1372
\unexpanded
\edef
\triplebond
{
\mathematics
{
\mathsurround
\zeropoint
\char
\number
"
2
2
6
1
\relax
}
}
1373 1374
% \mathchardef\singlebond"002D
1375
% \mathchardef\doublebond"003D
1376
% \mathchardef\triplebond"2261
1377 1378
%D Also handy:
1379 1380
\unexpanded
\def
\definemathunstacked
1381
{
\dotripleempty
\math_stackers_define_unstacked_normal
}
1382 1383
\def
\math_stackers_define_unstacked_normal
[
#
1
]
[
#
2
]
[
#
3
]
% category name unicode
1384
{
\ifthirdargument
1385
\setuevalue
{
#
2
}
{
\math_stackers_unstacked_normal
{
#
1
}
{
\number
#
3
}
}
%
1386
\else
1387
\setuevalue
{
#
1
}
{
\math_stackers_unstacked_normal
\noexpand
\currentmathstackers
{
\number
#
2
}
}
%
1388
\fi
}
1389 1390
\unexpanded
\def
\math_stackers_unstacked_normal
#
category
#
codepoint
%
1391
{
\begingroup
1392
\edef
\currentmathstackers
{
#
category
}
%
1393
\edef
\p_moffset
{
\mathstackersparameter
\c!moffset
}
%
1394
\ifx
\p_moffset
\empty
\else
1395
\mskip
\p_moffset
\relax
1396
\fi
1397
\ifmmode
\math_class_by_parameter
\mathstackersparameter
\else
\dontleavehmode
\fi
1398
{
\usemathstackerscolorparameter
\c!color
1399
\Umathchar
\zerocount
\defaultmathfamily
#
codepoint
}
%
1400
\ifx
\p_moffset
\empty
\else
1401
\mskip
\p_moffset
\relax
1402
\fi
1403
\endgroup
}
1404 1405
\definemathstackers
[
\v!wide
]
[
\c!moffset
=
\thickmuskip
,
\c!mathclass
=
\s!rel
]
1406 1407
\definemathunstacked
[
\v!wide
]
[
And
]
[
"
0
0
2
6
]
% \mathrel{\;&\;}
1408
\definemathunstacked
[
\v!wide
]
[
impliedby
]
[
"
2
7
F
8
]
% \mathrel{\;\Longleftarrow\;}
1409
\definemathunstacked
[
\v!wide
]
[
implies
]
[
"
2
7
F
9
]
% \mathrel{\;\Longrightarrow\;}
1410
\definemathunstacked
[
\v!wide
]
[
iff
]
[
"
2
7
FA
]
% \mathrel{\;\Longleftrightarrow\;}
1411 1412
% New (an example of using \mathexheight):
1413 1414
\definemathstackers
1415
[
\v!symbol
]
1416
[
\c!voffset
=
-
.
3
\mathexheight
,
1417
\c!hoffset
=
\zeropoint
,
1418
\c!mathclass
=
ord
,
1419
\c!topoffset
=
.
4
\mathemwidth
,
% poor man's italic correction
1420
\c!middlecommand
=
\mathematics
]
1421 1422
\definemathover
[
\v!symbol
]
[
interiorset
]
[
"
2
2
1
8
]
1423 1424
\protect
\endinput
1425 1426
% \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}
1427
% \limits\normalsuperscript{\box0}\normalsubscript{\box2}}%
1428 1429
% $\Uoverdelimiter \defaultmathfamily "2194 {xxxx}$
1430
% $\Uunderdelimiter\defaultmathfamily "2194 {xxxx}$
1431
% $\Udelimiterover \defaultmathfamily "2194 {xxxx}$
1432
% $\Udelimiterunder\defaultmathfamily "2194 {xxxx}$
1433
% $\Udelimiterover \defaultmathfamily "219A {\Udelimiterunder \defaultmathfamily "219B {xxxx}}$
1434 1435
% $a \mathrel{\mathop{\filledhboxr{mid}}}\limits^{\filledhboxg{\strut top}}_{\filledhboxb{\strut bottom}} b$
1436