math-fen.mkxl /size: 49 Kb    last modification: 2024-01-16 09:02
1%D \module
2%D   [       file=math-fen,
3%D        version=2012.02.18,
4%D          title=\CONTEXT\ Math Macros,
5%D       subtitle=Fences,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Math Macros / Fences}
15
16\unprotect
17
18% \definemathfence [fancybracket] [bracket] [define=yes,color=blue]
19%
20% test $|x|$ test \par
21% test $||x||$ test (okay) \par
22% test $a\left|\frac{1}{b}\right|c$ test \par
23% test $a\left||\frac{1}{b}\right||c$ test (not okay) \par
24%
25% \setupmathfences [color=red]
26%
27% test $a\fenced[bar]{\frac{1}{b}}c$ test \par
28% test $a\fenced[doublebar]{\frac{1}{b}}c$ test \par
29% test $a\fenced[bracket]{\frac{1}{b}}c$ test \par
30% test $a\fancybracket{\frac{1}{b}}c$ test \par
31
32\installcorenamespace{mathfences}
33
34\installcommandhandler \??mathfences {mathfence} \??mathfences
35
36\aliased\let\setupmathfences\setupmathfence
37
38\setupmathfences
39  [\c!method=, % maybe always \v!auto
40   \c!left=,
41   \c!right=,
42   \c!middle=,
43   \c!mathstyle=,
44   \c!color=,
45   \c!define=, % was \c!command
46   \c!mathclass=,
47   \c!leftclass=\mathopencode,
48   \c!rightclass=\mathclosecode,
49   \c!middleclass=\mathmiddlecode,
50   \c!leftsource=\zerocount,
51   \c!middlesource=\zerocount,
52   \c!rightsource=\mathfenceparameter\c!source,
53   \c!source=\zerocount,
54   \c!height=\zeropoint,
55   \c!depth=\zeropoint,
56   \c!distance=\zerocount,
57   \c!topspace=\zeropoint,
58   \c!bottomspace=\zeropoint,
59 % \c!overflow=\v!no,
60   \c!overflow=\v!auto,
61   \c!factor=\v!auto,
62   \c!snap=\mathematicsparameter\c!snap] % "28
63
64\appendtoks
65    \ifcstok{\mathfenceparameter\c!define}\v!yes
66        \protected\edefcsname\currentmathfence\endcsname{\math_fenced_fenced{\currentmathfence}}%
67    \fi
68\to \everydefinemathfence
69
70% we need the direct use of \Udelimiter because of { etc
71
72%D So we can do:
73%D
74%D \starttyping
75%D $ a + \fenced[bar][size=1]   {\frac {b} {c}} + d $
76%D $ a + \fenced[bar][size=2]   {\frac {b} {c}} + d $
77%D $ a + \fenced[bar][size=3]   {\frac {b} {c}} + d $
78%D $ a + \fenced[bar][size=4]   {\frac {b} {c}} + d $
79%D $ a + \fenced[bar][size=big] {\frac {b} {c}} + d $
80%D $ a + \fenced[bar][size=Big] {\frac {b} {c}} + d $
81%D $ a + \fenced[bar][size=bigg]{\frac {b} {c}} + d $
82%D $ a + \fenced[bar][size=Bigg]{\frac {b} {c}} + d $
83%D $ a + \fenced[bar][factor=1] {\frac {b} {c}} + d $
84%D $ a + \fenced[bar][factor=2] {\frac {b} {c}} + d $
85%D $ a + \fenced[bar][factor=4] {\frac {b} {c}} + d $
86%D $ a + \fenced[bar]           {\frac {b} {c}} + d $
87%D \stoptyping
88
89% \startbuffer
90%     $ \left( \frac{1}{x}^{2} \right)$
91%     $ \left( x \right)$
92%     $ \left( x^2 \right)$
93%     $ \left( \frac{1}{x} \right)$
94%     $ \left( \frac{1}{x}^2 \right)$
95% \stopbuffer
96%
97% \getbuffer\blank
98% {\setupmathfence[topspace=-2pt,bottomspace=-1pt]\getbuffer\blank}
99
100% todo : class -> number
101
102\newconditional\c_math_fenced_mirror \c_math_fenced_mirror\conditionaltrue
103\newconditional\c_math_fenced_sized  \c_math_fenced_sized\conditionalfalse
104\newinteger    \c_math_fence_nesting
105
106\installcorenamespace {mathfencesize}
107
108\defcsname\??mathfencesize  big\endcsname{1}
109\defcsname\??mathfencesize  Big\endcsname{2}
110\defcsname\??mathfencesize bigg\endcsname{3}
111\defcsname\??mathfencesize Bigg\endcsname{4}
112
113\let\math_fenced_trace\donothing
114
115\def\math_fenced_force_size#1#2%
116  {\c_attr_mathsize\numexpr
117     #1*\plushundred
118    +\ifcsname\??mathfencesize#2\endcsname\lastnamedcs\else#2\fi
119   \relax}
120
121\def\math_fenced_common_factor_none
122  {\math_fenced_force_size\bigmathdelimitervariant\c_math_fence_nesting\relax
123   \Uvextensible
124   \s!axis
125   \s!exact}
126
127\def\math_fenced_common_factor_fixed
128  {\Uvextensible
129   \s!axis
130   \s!exact}
131
132\def\math_fenced_common_factor_unknown
133  {\scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax
134   \Uvextensible
135   \s!height\scratchdimen
136   \s!depth\scratchdimen
137   \s!axis
138   \s!exact}
139
140\def\math_fenced_common_factor_force
141  {\Uvextensible
142   \s!height\mathfenceparameter\c!height
143   \s!depth\mathfenceparameter\c!depth
144   \s!axis
145   \s!exact}
146
147% \startTEXpage[offset=1dk]
148%     \dm { \fenced[brace][middle="7C] { \frac{p}{q} \fence p,q \in \naturalnumbers} }\par
149%     \dm { \fenced[brace][middle=`|]  { \frac{p}{q} \fence p,q \in \naturalnumbers} }\par
150%     \dm { \fenced[brace][middle=124] { \frac{p}{q} \fence p,q \in \naturalnumbers} }\par
151%     \dm { \fenced[brace][middle=|]   { \frac{p}{q} \fence p,q \in \naturalnumbers} }
152% \stopTEXpage
153
154\newconstant\c_math_fenced_class
155\newinteger \c_math_fence_check
156
157\integerdef\c_math_factor_fenced\zerocount
158
159\installglobalmacrostack\c_math_factor_fenced
160
161\protected\def\math_fenced_common#1#2#3#4% \Uwhatever class symbol source
162  {\c_math_fenced_class\math_class_by_parameter\mathfenceparameter#2%
163   \math_fenced_check_size_mismatch % we need to catch an unbalanced \F as we are sequential
164   \ifconditional\c_math_fenced_sized
165   \orelse\ifconditional\c_math_fenced_level_mode
166     \ifnum\c_math_fenced_class=\mathopencode
167     % \hpack{\infofont<L:\the\c_math_fenced_level:\the\c_attr_mathsize>}%
168       \integerdef\c_math_fenced_stack\c_attr_mathsize
169       \push_macro_c_math_fenced_stack
170     \orelse\ifnum\c_math_fenced_class=\mathclosecode
171       \pop_macro_c_math_fenced_stack
172       \c_attr_mathsize\c_math_fenced_stack
173     % \hpack{\infofont<R:\the\c_math_fenced_level:\the\c_attr_mathsize>}%
174     \fi
175   \fi
176   \edef\p_fence{#3}%
177   \ifempty\p_fence
178     \ifnum\c_math_fenced_class=\mathmiddlecode\else#1.\relax\fi
179   \else
180     \edef\p_factor   {\mathfenceparameter\c!factor}%
181     \edef\p_overflow {\mathfenceparameter\c!overflow}%
182     \edef\p_size     {\mathfenceparameter\c!size}%
183     \edef\p_mathclass{\mathfenceparameter\c!mathclass}%
184     \edef\p_inline_factor{\ifconditional\indisplaymath\mathfenceparameter\c!displayfactor\else\mathfenceparameter\c!inlinefactor\fi}%
185     \ifempty\p_inline_factor
186       % nothing
187     \orelse\ifx#1\Uleft
188       \push_macro_c_math_factor_fenced
189       \integerdef\c_math_factor_fenced\p_inline_factor\relax
190     \orelse\ifx#1\Uright
191       \pop_macro_c_math_factor_fenced
192     \fi
193     \ifnum\c_math_fenced_level>\zerocount
194       \math_fenced_common_factor_fixed
195     \orelse\ifconditional\c_math_fenced_sized
196       \math_fenced_common_factor_fixed
197     \orelse\ifempty\p_factor
198       \ifconditional\c_math_fenced_level_mode
199         \Uvextensible
200       \else
201         #1% \Uleft \Umiddle \Uleft
202         \ifx#1\Umiddle
203           \ifx\p_overflow\v!auto
204             middle %
205             nooverflow %
206           \orelse\ifx\p_overflow\v!no
207             nooverflow %
208           \fi
209         \fi
210       \fi
211     \orelse\ifx\p_factor\v!auto
212       \ifconditional\c_math_fenced_level_mode
213         \Uvextensible
214       \else
215         #1% \Uleft \Umiddle \Uleft
216        \ifx#1\Umiddle
217           \ifx\p_overflow\v!auto
218             middle %
219             nooverflow %
220           \orelse\ifx\p_overflow\v!no
221             nooverflow %
222           \fi
223        \fi
224       \fi
225     \orelse\ifx\p_factor\v!none
226       \math_fenced_common_factor_none
227     \orelse\ifx\p_factor\v!fixed
228       \math_fenced_common_factor_fixed
229     \orelse\ifx\p_factor\v!force
230       \math_fenced_common_factor_force
231     \else
232       \math_fenced_common_factor_unknown
233     \fi
234     \usedcolorparameterattributes{\mathfenceparameter\c!color}%
235     \s!class
236        \ifx\p_fence\v!none
237          \mathghostcode
238        \orelse\ifempty\p_mathclass
239          \c_math_fenced_class
240        \else
241          \mathcodechecked\p_mathclass
242        \fi
243     \s!source
244        \numexpr\namedboxanchor{\mathfenceparameter#4}\relax
245     %
246     \s!top    \mathfenceparameter\c!topspace
247     \s!bottom \mathfenceparameter\c!bottomspace
248     %
249     \ifzero\c_math_factor_fenced\else
250         \s!factor \c_math_factor_fenced
251     \fi
252     %
253     \ifcstok{\mathfenceparameter\c!snap}\v!yes
254        \s!single\space
255     \fi
256     %
257     \math_fenced_trace
258     \ifx\p_fence\v!none
259       \Udelimiter\mathghostcode\fam\zerocount
260     \orelse\ifchknumber\p_fence\or
261       \Udelimiter\mathghostcode\fam\lastchknumber
262     \else
263       \p_fence
264     \fi
265   \fi
266   % we could use \s!attr \c_math_fenced_stack here
267   \ifconditional\c_math_fenced_sized
268   \orelse\ifcase\c_math_fenced_level
269     \c_attr_mathsize\attributeunsetvalue
270   \fi}
271
272\def\math_fenced_left
273  {\advanceby\c_math_fence_nesting\plusone
274   \math_fenced_common\Uleft\c!leftclass\math_fenced_p_left\c!leftsource}
275
276\def\math_fenced_right
277  {\math_fenced_common\Uright\c!rightclass\math_fenced_p_right\c!rightsource
278   \advanceby\c_math_fence_nesting\minusone}
279
280\def\math_fenced_middle_normal
281  {\math_fenced_common\Umiddle\c!middleclass\math_fenced_p_middle\c!middlesource}
282
283\def\math_fenced_middle_sized
284  {\c_math_fenced_sized\conditionaltrue
285   \math_fenced_middle_normal
286   \c_math_fenced_sized\conditionalfalse}
287
288\appendtoks
289    \let\math_fenced_middle\math_fenced_middle_normal
290    \enforced\let\fence\math_fenced_direct
291\to \everymathatom
292
293\let\math_fenced_middle\math_fenced_middle_normal
294
295\def\math_fenced_p_left
296  {\ifconditional\c_math_fenced_mirror
297     \ifconditional\c_math_right_to_left
298       \mathfenceparameter\c!right
299     \else
300       \mathfenceparameter\c!left
301     \fi
302   \else
303     \mathfenceparameter\c!left
304   \fi}
305
306\def\math_fenced_p_middle
307  {\mathfenceparameter\c!middle}%
308
309\def\math_fenced_p_right
310  {\ifconditional\c_math_fenced_mirror
311     \ifconditional\c_math_right_to_left
312       \mathfenceparameter\c!left
313     \else
314       \mathfenceparameter\c!right
315     \fi
316   \else
317     \mathfenceparameter\c!right
318   \fi}
319
320\aliased\let\fence \relax
321\aliased\let\fenced\relax
322
323\protected\def\math_fenced_middle_bar  {\mfence |\relax}
324\protected\def\math_fenced_middle_colon{\mfence :\relax}
325\protected\def\math_fenced_middle_comma{\mathatom \s!leftclass \mathpunctuationcode \s!rightclass \mathmiddlecode {,}}
326
327\startsetups math:fence:set:bar
328    \aliased\let\suchthat\math_fenced_middle_bar
329    \aliased\let\where   \math_fenced_middle_comma
330    \aliased\let\and     \math_fenced_middle_comma
331\stopsetups
332
333\startsetups math:fence:set:colon
334    \aliased\let\suchthat\math_fenced_middle_colon
335    \aliased\let\where   \math_fenced_middle_comma
336    \aliased\let\and     \math_fenced_middle_comma
337\stopsetups
338
339\startsetups math:fence:set
340    \directsetup{math:fence:set:bar}
341\stopsetups
342
343\mutable\lettonothing\suchthat
344% \fastsetup{math:fence:set}
345
346\protected\def\math_fenced_middle_common
347  {\math_fenced_middle} % redefined inside atom
348
349\protected\def\math_fenced_fenced_common
350  {\startusemathstyleparameter\mathfenceparameter\c!mathstyle
351   \usesetupsparameter\mathfenceparameter
352   \enforced\let\fence\math_fenced_middle_common}
353
354\protected\def\math_fenced_fenced_start#1%
355  {\begingroup
356 %{\beginmathgroup
357   \cdef\currentmathfence{#1}%
358   \math_fenced_fenced_common
359   \math_fenced_left}
360
361\protected\def\math_fenced_fenced_stop#1%
362  {\cdef\currentmathfence{#1}%
363   \math_fenced_right
364   \stopusemathstyleparameter
365   \endgroup}
366  %\endmathgroup}
367
368\installlocalcurrenthandler \??mathfences {mathfence}
369
370%D The horizontal text variant was introduced for Alan Braslau. Because this is not
371%D used that often we only support double text arguments.
372%D
373%D Musical timestamp: I am The Moon by Tedeschi Trucks Band
374
375% \definemathfence [tupdownarrows] [text] [\c!left="2191,\c!right="2193]
376
377\def\math_fenced_check#1%
378  {\ifempty{\mathfenceparameter#1}\letmathfenceparameter#1\v!none\fi}
379
380\appendtoks
381    \math_fenced_check\c!left
382    \math_fenced_check\c!right
383\to \everysetupmathfence
384
385\appendtoks
386    \math_fenced_check\c!left
387    \math_fenced_check\c!right
388\to \everydefinemathfence
389
390\protected\def\math_fenced_horizontal_common#1#2#3#4% \Uwhatever class symbol source
391  {\c_math_fenced_class\math_class_by_parameter\mathfenceparameter#2\relax
392   \edef\p_fence{#3}%
393   #1% \Uleft \Umiddle \Uleft
394   \usedcolorparameterattributes{\mathfenceparameter\c!color}%
395   \s!leftclass  \mathunspacedcode
396   \s!rightclass \mathunspacedcode
397   \s!class      \mathunspacedcode
398   \s!source     \numexpr\namedboxanchor{\mathfenceparameter#4}\relax
399   \Udelimiter\mathghostcode\fam\p_fence}
400
401\tolerant\protected\def\math_fenced_horizontal#1#*[#S#2]#:#*#3#4%
402  {% \csname math\mathfenceparameter\c!mathclass\endcsname
403   \mathord \bgroup % class here
404     \setlocalmathfencecurrent{#1}% \cdef\currentmathfence{#1}%
405     \setupcurrentmathfence[#2]%
406   % \usemathstyleparameter\mathfenceparameter\c!mathstyle
407     \setmathsmalltextbox\scratchboxone\hbox{\usemathfencestyleandcolor\c!leftstyle \c!leftcolor #3}%
408     \setmathsmalltextbox\scratchboxtwo\hbox{\usemathfencestyleandcolor\c!rightstyle\c!rightcolor#4}%
409     \let\math_fenced_common\math_fenced_horizontal_common
410     \edef\p_fenced_middle{\mathfenceparameter\c!middle}%
411     \ifempty\p_fenced_middle\else
412       \letmathfenceparameter\c!left \p_fenced_middle
413       \letmathfenceparameter\c!right\zerocount
414     \fi
415     \scratchdistance\mathfenceparameter\c!distance
416     \box\scratchboxone
417     \kern\scratchdistance
418     \math_fenced_fenced_start\currentmathfence
419     \math_fenced_fenced_stop \currentmathfence
420     \kern\scratchdistance
421     \box\scratchboxtwo
422   \egroup}
423
424\tolerant\protected\def\math_fenced_fenced#1%
425  {\ifcstok{\namedmathfenceparameter{#1}\c!text}\v!yes % not the best keyword
426     \expandafter\math_fenced_horizontal
427   \else
428     \expandafter\math_fenced_vertical
429   \fi{#1}}
430
431% two step because we don't want to define text itself as command
432
433\definemathfence
434  [\v!text]
435
436\setupmathfence
437  [\v!text]
438  [\c!text=\v!yes,
439   \c!define=\v!yes,
440   \c!distance=.125\emwidth]
441
442\tolerant\protected\def\math_fenced_vertical#1#*[#S#2]%
443  {\begingroup
444 %{\beginmathgroup
445   \setlocalmathfencecurrent{#1}% \cdef\currentmathfence{#1}%
446   % under test:
447   \c_math_fenced_level_mode\conditionalfalse
448   \c_attr_mathsize\attributeunsetvalue
449   %
450   \resetmathfenceparameter\c!size
451   \letmathfenceparameter\c!factor\v!auto
452   % so far
453   \ifparameter#2\or
454     \setupcurrentmathfence[#2]%
455     \bigmathdelimitervariant\mathfenceparameter\c!alternative\relax
456   \fi
457   \math_fenced_fenced_common
458   \edef\p_size{\mathfenceparameter\c!size}%
459   \ifempty\p_size
460     \expandafter\math_fenced_fenced_indeed_adapt
461   \else
462     \expandafter\math_fenced_fenced_indeed_fixed
463   \fi}
464
465\protected\def\math_fenced_fenced_indeed_finish
466  {\stopusemathstyleparameter
467   \endgroup}
468  %\endmathgroup}
469
470\protected\def\math_fenced_fenced_indeed_fixed#1%
471  {\math_fenced_force_size\bigmathdelimitervariant\p_size
472   \c_math_fenced_sized\conditionaltrue
473   \math_fenced_left
474   \c_math_fenced_sized\conditionalfalse
475   \let\math_fenced_middle\math_fenced_middle_sized
476 % \enforced\let\middle\math_fenced_middle_sized
477\begingroup
478   #1% otherwise middle interferes
479\endgroup
480   \c_math_fenced_sized\conditionaltrue
481   \math_fenced_right
482   \c_math_fenced_sized\conditionalfalse
483   \math_fenced_fenced_indeed_finish}
484
485\protected\def\math_fenced_fenced_indeed_adapt#1%
486  {\c_math_fenced_sized\conditionalfalse
487   \math_fenced_left
488   #1%
489   \c_math_fenced_sized\conditionalfalse
490   \math_fenced_right
491   \math_fenced_fenced_indeed_finish}
492
493\protected\def\math_fenced_direct[#1]%
494  {\math_fenced_fenced{#1}}
495
496\appendtoks
497    \enforced\let\fenced\math_fenced_direct
498\to \everymathematics
499
500\permanent\tolerant\protected\def\startmathfenced[#1]#*[#S#2]%
501  {\begingroup
502   \cdef\currentmathfence{#1}%
503   \setupcurrentmathfence[#2]%
504   \math_fenced_fenced_start{#1}}
505
506\permanent\protected\def\stopmathfenced
507  {\math_fenced_fenced_stop\currentmathfence
508   \endgroup}
509
510\protected\def\math_fenced_start_wrap#1%
511  {\begingroup
512   \edef\m_math_fenced_wrap{#1}%
513   \ifempty\m_math_fenced_wrap \else
514     \math_fenced_fenced_start\m_math_fenced_wrap
515   \fi}
516
517\protected\def\math_fenced_stop_wrap
518  {\ifempty\m_math_fenced_wrap \else
519     \math_fenced_fenced_stop\m_math_fenced_wrap
520   \fi
521   \endgroup}
522
523% for torture testing mikael sundqvist:
524%
525% \setupmathfence[brace][middle=124]
526%
527% \im{\fenced[brace]        {\vec{x}\in\reals^3\middle\vert \vec{x}\neq \vec{0}}}
528% \im{\fenced[brace]        {\vec{x}\in\reals^3\mid         \vec{x}\neq \vec{0}}}
529% \im{\fenced[brace][size=0]{\vec{x}\in\reals^3\fence       \vec{x}\neq \vec{0}}}
530
531\aliased\let\normalmid\mid
532
533\protected\def\mid{\ifcase\c_math_fence_nesting\normalmid\else\middle\vert\fi}
534
535% cases are defined in math-ali:
536
537\definemathfence [cases]   [\c!left="007B,\c!right=\v!none]
538\definemathfence [sesac]   [\c!left=\v!none,\c!right="007D]
539\definemathfence [tekcarb] [\c!left="005D,\c!right="005B]   % used for xıɹʇɐɯ
540
541%D This is new:
542%D
543%D \starttyping
544%D $ \F0 \left( x + \F1 \left( x \right) + x \right) $
545%D $
546%D   \F0 \left( x + \F1 \left( x + \F2 \left( x + \F3 \left( x + \F4 \left( x +
547%D   2
548%D   + x \right) + x \right) + x \right) + x \right) + x \right)
549%D $
550%D $ \F1 \left( x + \F1 \left( x \right) + x \right) $
551%D $ \F3 \left( x + \F1 \left( x \right) + x \right) $
552%D $ \F1 \left( x + \F4 \left( x \right) + x \right) $
553%D $ \F4 \left( x + \F- \left( x \right) + x \right) $
554%D $ \F4
555%D     \left( 1 +
556%D         \F- \left( 2 +
557%D             \F* \left( 3 +
558%D                 4
559%D             \right)
560%D             + 5 +
561%D             \F- \left( 6 +
562%D                 7
563%D             \right)
564%D         \right)
565%D         + 8
566%D     \right)
567%D $
568%D \stoptyping
569%D
570%D \starttyping
571%D \startTEXpage[offset=1dk,width=20dk]
572%D   \ruledhbox{$ \F3 \left( 1 + \F2 \left( a + b \right) + \left( a + b \right) \right) $}\par
573%D   \ruledhbox{$ \left( 1 + \F3 \left( a + b \right) + \left( a + b \right) \right) $}\par
574%D   \ruledhbox{$ \F3 \left( 1 + \F0 \left( a + b \right) \right) $}\par
575%D   \ruledhbox{$ \F3 \left( 1 + \F= \left( a + b \right) \right) $}\par
576%D   \ruledhbox{$ \F4 \left( 1 + \fenced[parenthesis]{a + b} \right) $}\par
577%D   \ruledhbox{$ \F3 \left( 1 + \F- \left( a + b \right) \right) $}\par
578%D   \ruledhbox{$ \left( \frac{1}{1+x} \right) $}\par
579%D   \ruledhbox{$ \left( \frac{1}{1+x} \right) $}\par
580%D \stopTEXpage
581%D \stoptyping
582
583\newinteger    \c_math_fenced_level
584\newconditional\c_math_fenced_level_mode
585
586\integerdef\c_math_fenced_stack \zerocount
587
588\installmacrostack \c_math_fenced_stack
589
590\installcorenamespace{fencelevels}
591\installcorenamespace{fencestack}
592
593\defcsname\??fencelevels+\endcsname{\advanceby\c_math_fenced_level\plusone  }
594\defcsname\??fencelevels-\endcsname{\advanceby\c_math_fenced_level\minusone }
595\defcsname\??fencelevels=\endcsname          {\c_math_fenced_level\zerocount}
596
597\letcsname\??fencelevels*\endcsname\donothing
598
599\def\math_fenced_check_size_mismatch
600 {\ifnum\c_math_fence_check=\c_math_fence_nesting
601    \c_attr_mathsize\attributeunsetvalue
602    \c_math_fenced_level_mode\conditionalfalse
603    \c_math_fenced_level\zerocount
604  \fi}
605
606\permanent\protected\def\F#1%
607  {\ifconditional\c_math_fenced_level_mode\else
608     \c_math_fence_check\c_math_fence_nesting
609   \fi
610   \c_math_fenced_level_mode\conditionaltrue
611   \ifchknum#1\or
612     \c_math_fenced_level#1\relax
613   \orelse\ifcsname\??fencelevels#1\endcsname
614     \lastnamedcs
615   \else
616     \c_math_fenced_level\zerocount
617   \fi
618   \math_fenced_force_size\bigmathdelimitervariant\c_math_fenced_level\relax}
619
620% \appendtoks
621%     \enforced\aliased\let|\letterbar
622%    %\enforced\aliased\let\bar\letterbar
623% \to \everymathematics
624
625\definemathfence [parenthesis] [\c!left="0028,\c!right="0029]
626\definemathfence [bracket]     [\c!left="005B,\c!right="005D]
627\definemathfence [brace]       [\c!left="007B,\c!right="007D]
628\definemathfence [bar]         [\c!left="007C,\c!right="007C]
629\definemathfence [doublebar]   [\c!left="2016,\c!right="2016]
630\definemathfence [triplebar]   [\c!left="2980,\c!right="2980]
631\definemathfence [angle]       [\c!left="27E8,\c!right="27E9]
632\definemathfence [doubleangle] [\c!left="27EA,\c!right="27EB]
633\definemathfence [solidus]     [\c!left="2044,\c!right="2044]
634\definemathfence [ceiling]     [\c!left="2308,\c!right="2309]
635\definemathfence [floor]       [\c!left="230A,\c!right="230B]
636\definemathfence [moustache]   [\c!left="23B0,\c!right="23B1]
637\definemathfence [uppercorner] [\c!left="231C,\c!right="231D]
638\definemathfence [lowercorner] [\c!left="231E,\c!right="231F]
639\definemathfence [group]       [\c!left="27EE,\c!right="27EF]
640\definemathfence [openbracket] [\c!left="27E6,\c!right="27E7]
641
642\definemathfence [nothing]
643
644\definemathfence [mirrored] % \v!mirrored
645
646\definemathfence [mirroredparenthesis] [mirrored] [\c!right="0028,\c!left="0029]
647\definemathfence [mirroredbracket]     [mirrored] [\c!right="005B,\c!left="005D]
648\definemathfence [mirroredbrace]       [mirrored] [\c!right="007B,\c!left="007D]
649\definemathfence [mirroredbar]         [mirrored] [\c!right="007C,\c!left="007C]
650\definemathfence [mirroreddoublebar]   [mirrored] [\c!right="2016,\c!left="2016]
651\definemathfence [mirroredtriplebar]   [mirrored] [\c!right="2980,\c!left="2980]
652\definemathfence [mirroredangle]       [mirrored] [\c!right="27E8,\c!left="27E9]
653\definemathfence [mirroreddoubleangle] [mirrored] [\c!right="27EA,\c!left="27EB]
654\definemathfence [mirroredsolidus]     [mirrored] [\c!right="2044,\c!left="2044]
655\definemathfence [mirroredceiling]     [mirrored] [\c!right="2308,\c!left="2309]
656\definemathfence [mirroredfloor]       [mirrored] [\c!right="230A,\c!left="230B]
657\definemathfence [mirroredmoustache]   [mirrored] [\c!right="23B0,\c!left="23B1]
658\definemathfence [mirroreduppercorner] [mirrored] [\c!right="231C,\c!left="231D]
659\definemathfence [mirroredlowercorner] [mirrored] [\c!right="231E,\c!left="231F]
660\definemathfence [mirroredgroup]       [mirrored] [\c!right="27EE,\c!left="27EF]
661\definemathfence [mirroredopenbracket] [mirrored] [\c!right="27E6,\c!left="27E7]
662
663\definemathfence [mirrorednothing]     [mirrored]
664
665%D A bonus:
666
667\pushoverloadmode
668
669\immutable\protected\def\Lparenthesis         {\math_fenced_fenced_start{parenthesis}}          \immutable\protected\def\Rparenthesis         {\math_fenced_fenced_stop {parenthesis}}
670\immutable\protected\def\Lbracket             {\math_fenced_fenced_start{bracket}}              \immutable\protected\def\Rbracket             {\math_fenced_fenced_stop {bracket}}
671\immutable\protected\def\Lbrace               {\math_fenced_fenced_start{brace}}                \immutable\protected\def\Rbrace               {\math_fenced_fenced_stop {brace}}
672\immutable\protected\def\Langle               {\math_fenced_fenced_start{angle}}                \immutable\protected\def\Rangle               {\math_fenced_fenced_stop {angle}}
673\immutable\protected\def\Ldoubleangle         {\math_fenced_fenced_start{doubleangle}}          \immutable\protected\def\Rdoubleangle         {\math_fenced_fenced_stop {doubleangle}}
674\immutable\protected\def\Lbar                 {\math_fenced_fenced_start{bar}}                  \immutable\protected\def\Rbar                 {\math_fenced_fenced_stop {bar}}
675\immutable\protected\def\Ldoublebar           {\math_fenced_fenced_start{doublebar}}            \immutable\protected\def\Rdoublebar           {\math_fenced_fenced_stop {doublebar}}
676\immutable\protected\def\Ltriplebar           {\math_fenced_fenced_start{triplebar}}            \immutable\protected\def\Rtriplebar           {\math_fenced_fenced_stop {triplebar}}
677\immutable\protected\def\Lsolidus             {\math_fenced_fenced_start{solidus}}              \immutable\protected\def\Rsolidus             {\math_fenced_fenced_stop {solidus}}
678\immutable\protected\def\Lfloor               {\math_fenced_fenced_start{floor}}                \immutable\protected\def\Rfloor               {\math_fenced_fenced_stop {floor}}
679\immutable\protected\def\Lceiling             {\math_fenced_fenced_start{ceiling}}              \immutable\protected\def\Rceiling             {\math_fenced_fenced_stop {ceiling}}
680\immutable\protected\def\Lmoustache           {\math_fenced_fenced_start{moustache}}            \immutable\protected\def\Rmoustache           {\math_fenced_fenced_stop {moustache}}
681\immutable\protected\def\Luppercorner         {\math_fenced_fenced_start{uppercorner}}          \immutable\protected\def\Ruppercorner         {\math_fenced_fenced_stop {uppercorner}}
682\immutable\protected\def\Llowercorner         {\math_fenced_fenced_start{lowercorner}}          \immutable\protected\def\Rlowercorner         {\math_fenced_fenced_stop {lowercorner}}
683\immutable\protected\def\Lgroup               {\math_fenced_fenced_start{group}}                \immutable\protected\def\Rgroup               {\math_fenced_fenced_stop {group}}
684\immutable\protected\def\Lopenbracket         {\math_fenced_fenced_start{openbracket}}          \immutable\protected\def\Ropenbracket         {\math_fenced_fenced_stop {openbracket}}
685\immutable\protected\def\Lnothing             {\math_fenced_fenced_start{nothing}}              \immutable\protected\def\Rnothing             {\math_fenced_fenced_stop {nothing}}
686
687\immutable\protected\def\Lparenthesismirrored {\math_fenced_fenced_stop {mirroredparenthesis}}  \immutable\protected\def\Rparenthesismirrored {\math_fenced_fenced_start{mirroredparenthesis}}
688\immutable\protected\def\Lbracketmirrored     {\math_fenced_fenced_stop {mirroredbracket}}      \immutable\protected\def\Rbracketmirrored     {\math_fenced_fenced_start{mirroredbracket}}
689\immutable\protected\def\Lbracemirrored       {\math_fenced_fenced_stop {mirroredbrace}}        \immutable\protected\def\Rbracemirrored       {\math_fenced_fenced_start{mirroredbrace}}
690\immutable\protected\def\Langlemirrored       {\math_fenced_fenced_stop {mirroredangle}}        \immutable\protected\def\Ranglemirrored       {\math_fenced_fenced_start{mirroredangle}}
691\immutable\protected\def\Ldoubleanglemirrored {\math_fenced_fenced_stop {mirroreddoubleangle}}  \immutable\protected\def\Rdoubleanglemirrored {\math_fenced_fenced_start{mirroreddoubleangle}}
692\immutable\protected\def\Lbarmirrored         {\math_fenced_fenced_stop {mirroredbar}}          \immutable\protected\def\Rbarmirrored         {\math_fenced_fenced_start{mirroredbar}}
693\immutable\protected\def\Ldoublebarmirrored   {\math_fenced_fenced_stop {mirroreddoublebar}}    \immutable\protected\def\Rdoublebarmirrored   {\math_fenced_fenced_start{mirroreddoublebar}}
694\immutable\protected\def\Ltriplebarmirrored   {\math_fenced_fenced_stop {mirroredtriplebar}}    \immutable\protected\def\Rtriplebarmirrored   {\math_fenced_fenced_start{mirroredtriplebar}}
695\immutable\protected\def\Lsolidusmirrored     {\math_fenced_fenced_stop {mirroredsolidus}}      \immutable\protected\def\Rsolidusmirrored     {\math_fenced_fenced_start{mirroredsolidus}}
696\immutable\protected\def\Lfloormirrored       {\math_fenced_fenced_stop {mirroredfloor}}        \immutable\protected\def\Rfloormirrored       {\math_fenced_fenced_start{mirroredfloor}}
697\immutable\protected\def\Lceilingmirrored     {\math_fenced_fenced_stop {mirroredceiling}}      \immutable\protected\def\Rceilingmirrored     {\math_fenced_fenced_start{mirroredceiling}}
698\immutable\protected\def\Lmoustachemirrored   {\math_fenced_fenced_stop {mirroredmoustache}}    \immutable\protected\def\Rmoustachemirrored   {\math_fenced_fenced_start{mirroredmoustache}}
699\immutable\protected\def\Luppercornermirrored {\math_fenced_fenced_stop {mirroreduppercorner}}  \immutable\protected\def\Ruppercornermirrored {\math_fenced_fenced_start{mirroreduppercorner}}
700\immutable\protected\def\Llowercornermirrored {\math_fenced_fenced_stop {mirroredlowercorner}}  \immutable\protected\def\Rlowercornermirrored {\math_fenced_fenced_start{mirroredlowercorner}}
701\immutable\protected\def\Lgroupmirrored       {\math_fenced_fenced_stop {mirroredgroup}}        \immutable\protected\def\Rgroupmirrored       {\math_fenced_fenced_start{mirroredgroup}}
702\immutable\protected\def\Lopenbracketmirrored {\math_fenced_fenced_stop {mirroredopenbracket}}  \immutable\protected\def\Ropenbracketmirrored {\math_fenced_fenced_start{mirroredopenbracket}}
703\immutable\protected\def\Lnothingmirrored     {\math_fenced_fenced_stop {mirrorednothing}}      \immutable\protected\def\Rnothingmirrored     {\math_fenced_fenced_start{mirrorednothing}}
704
705% These tortoise chars almost only exist in stix (and ar not commonly used)
706
707% \definemathfence [interval]                     [\c!left="2997,\c!right="2998]
708% \definemathfence [openinterval]      [interval] [\c!left="2998,\c!right="2998]
709% \definemathfence [leftopeninterval]  [interval] [\c!left="2997,\c!right="2997]
710% \definemathfence [rightopeninterval] [interval] [\c!left="2998,\c!right="2998]
711
712% Different intervals. The variants are the ones suggested by Bourbaki.
713
714\definemathfence [interval]                        [\c!left="005B,\c!right="005D]
715\definemathfence [openinterval]         [interval] [\c!left="0028,\c!right="0029]
716\definemathfence [closedinterval]       [interval] [\c!left="005B,\c!right="005D]
717\definemathfence [leftopeninterval]     [interval] [\c!left="0028,\c!right="005D]
718\definemathfence [rightopeninterval]    [interval] [\c!left="005B,\c!right="0029]
719\definemathfence [varopeninterval]      [interval] [\c!left="005D,\c!right="005B]
720\definemathfence [varleftopeninterval]  [interval] [\c!left="005D,\c!right="005D]
721\definemathfence [varrightopeninterval] [interval] [\c!left="005B,\c!right="005B]
722
723\immutable\protected\def\Linterval   {\math_fenced_fenced_start{interval}}
724\immutable\protected\def\Lointerval  {\math_fenced_fenced_start{openinterval}}
725\immutable\protected\def\Llointerval {\math_fenced_fenced_start{leftopeninterval}}
726\immutable\protected\def\Lrointerval {\math_fenced_fenced_start{rightopeninterval}}
727
728\immutable\protected\def\Rinterval   {\math_fenced_fenced_stop {interval}}
729\immutable\protected\def\Rointerval  {\math_fenced_fenced_stop {openinterval}}
730\immutable\protected\def\Rlointerval {\math_fenced_fenced_stop {leftopeninterval}}
731\immutable\protected\def\Rrointerval {\math_fenced_fenced_stop {rightopeninterval}}
732
733% \startformula
734% \left{ \frac{1}{a} \right}
735% \left[ \frac{1}{b} \right]
736% \left( \frac{1}{c} \right)
737% \left< \frac{1}{d} \right>
738% \left| \frac{1}{e} \right|
739% \stopformula
740
741\popoverloadmode
742
743\installcorenamespace{mathleft}
744\installcorenamespace{mathright}
745\installcorenamespace{mathmiddle}
746
747\pushoverloadmode
748
749% \protected\def\left  {\afterassignment\math_left  \let\nexttoken}
750% \protected\def\right {\afterassignment\math_right \let\nexttoken}
751% \protected\def\middle{\afterassignment\math_middle\let\nexttoken}
752
753% \im { \left{       \frac{1}{2} \right}       }
754% \im { \left\bgroup \frac{1}{2} \right\egroup }
755% \im { \left\{      \frac{1}{2} \right\}      }
756% \im { \left\lbrace \frac{1}{2} \right\rbrace }
757
758\lettonothing\math_fenced_x_p_left
759\lettonothing\math_fenced_x_p_right
760\lettonothing\math_fenced_x_p_middle
761
762\def\math_fenced_x_left
763  {\advanceby\c_math_fence_nesting\plusone
764   \ifx\math_fenced_x_p_left\bgroup\let\math_fenced_x_p_left\letterleftbrace\fi
765   \math_fenced_common\Uleft\c!leftclass\math_fenced_x_p_left\c!leftsource}
766
767\def\math_fenced_x_right
768  {\ifx\math_fenced_x_p_right\egroup\let\math_fenced_x_p_right\letterrightbrace\fi
769   \math_fenced_common\Uright\c!rightclass\math_fenced_x_p_right\c!rightsource
770   \advanceby\c_math_fence_nesting\minusone}
771
772\def\math_fenced_x_middle
773  {\math_fenced_common\Umiddle\c!middleclass\math_fenced_x_p_middle\c!middlesource}
774
775% the expandafter permits \left\tocharacter...
776
777\protected\def\lfence{\afterassignment\math_fenced_x_left  \expandafter\let\expandafter\math_fenced_x_p_left}
778\protected\def\rfence{\afterassignment\math_fenced_x_right \expandafter\let\expandafter\math_fenced_x_p_right}
779\protected\def\mfence{\afterassignment\math_fenced_x_middle\expandafter\let\expandafter\math_fenced_x_p_middle}
780
781\aliased\let\left  \lfence
782\aliased\let\right \rfence
783\aliased\let\middle\mfence
784
785\popoverloadmode
786
787% \let\leftorright\relax
788
789\newconditional\c_math_fenced_unknown  \c_math_fenced_unknown\conditionaltrue
790
791% \permanent\protected\def\installmathfencepair#1#2#3#4%
792%   {\letcsname\??mathleft \normalmeaningless#1\endcsname#2%
793%    \letcsname\??mathright\normalmeaningless#3\endcsname#4}
794
795\permanent\protected\def\installmathfencepair#1#2#3#4%
796  {}
797
798% \def\math_unknown_left  {\ifconditional\c_math_fenced_unknown\Uleft              \nexttoken\fi}
799% \def\math_unknown_right {\ifconditional\c_math_fenced_unknown\Uright             \nexttoken\fi}
800% \def\math_unknown_middle{\ifconditional\c_math_fenced_unknown\Umiddle nooverflow \nexttoken\fi}
801
802% \def\math_unknown_left
803%   {\let\math_fenced_p_left\nexttoken
804%    \math_fenced_left}
805%
806% \def\math_unknown_right
807%   {\let\math_fenced_p_right\nexttoken
808%    \math_fenced_right}
809%
810% \def\math_unknown_middle
811%   {\let\math_fenced_p_middle\nexttoken
812%    \math_fenced_middle}
813%
814% \letcsname\??mathleft  \s!unknown\endcsname\math_unknown_left
815% \letcsname\??mathright \s!unknown\endcsname\math_unknown_right
816% \letcsname\??mathmiddle\s!unknown\endcsname\math_unknown_middle
817%
818% \def\math_left
819%   {\ifcsname\??mathleft\normalmeaningless\nexttoken\endcsname
820%      \expandafter\lastnamedcs
821%    \else
822%      \expandafter\math_unknown_left
823%    \fi}
824%
825% \def\math_right
826%   {\ifcsname\??mathright\normalmeaningless\nexttoken\endcsname
827%      \expandafter\lastnamedcs
828%    \else
829%      \expandafter\math_unknown_right
830%    \fi}
831%
832% \def\math_middle
833%   {\ifcsname\??mathmiddle\normalmeaningless\nexttoken\endcsname
834%      \expandafter\lastnamedcs
835%    \else
836%      \expandafter\math_unknown_middle
837%    \fi}
838%
839% \permanent\protected\def\lfence#1%
840%   {\let\nexttoken#1%
841%    \ifcsname\??mathleft\normalmeaningless\nexttoken\endcsname
842%      \expandafter\lastnamedcs
843%    \else
844%      \expandafter\math_unknown_left
845%    \fi}
846%
847% \permanent\protected\def\rfence#1%
848%   {\let\nexttoken#1%
849%    \ifcsname\??mathright\normalmeaningless\nexttoken\endcsname
850%      \expandafter\lastnamedcs
851%    \else
852%      \expandafter\math_unknown_right
853%    \fi}
854%
855% \permanent\protected\def\mfence#1%
856%   {\let\nexttoken#1%
857%    \ifcsname\??mathmiddle\normalmeaningless\nexttoken\endcsname
858%      \expandafter\lastnamedcs
859%    \else
860%      \expandafter\math_unknown_middle
861%    \fi}
862
863% \normalexpanded{\installmathfencepair {|\detokenize {|}} \Ldoublebar {|\detokenize {|}} \Rdoublebar}
864% \normalexpanded{\installmathfencepair {|\detokenize{||}} \Ltriplebar {|\detokenize{||}} \Rtriplebar}
865%
866% \installmathfencepair \bgroup \Lbrace         \egroup \Rbrace
867% \installmathfencepair \egroup \Rbracemirrored \bgroup \Lbracemirrored
868%
869% \installmathfencepair \letteropenbrace \Lbrace \letterclosebrace \Rbrace % as we escape in mp textexts
870%
871% \installmathfencepair . \Lnothing             . \Rnothing
872% \installmathfencepair . \Rnothingmirrored     . \Lnothingmirrored
873%
874% \installmathfencepair [ \Lbracket             ] \Rbracket
875% \installmathfencepair ] \Rbracketmirrored     [ \Lbracketmirrored
876%
877% \installmathfencepair ( \Lparenthesis         ) \Rparenthesis
878% \installmathfencepair ) \Rparenthesismirrored ( \Lparenthesismirrored
879%
880% \installmathfencepair < \Langle               > \Rangle
881% \installmathfencepair > \Ranglemirrored       < \Langlemirrored
882%
883% \installmathfencepair / \Lsolidus             / \Rsolidus
884% %installmathfencepair / \Rsolidusmirrored     / \Lsolidusmirrored
885%
886% \installmathfencepair | \Lbar                 | \Rbar
887% %installmathfencepair | \Rbarmirrored         | \Lbarmirrored
888%
889% \installmathfencepair ⌊ \Lfloor               ⌋ \Rfloor
890% \installmathfencepair ⌋ \Rfloormirrored       ⌊ \Lfloormirrored
891% \installmathfencepair ⌈ \Lceiling             ⌉ \Rceiling
892% \installmathfencepair ⌉ \Rceilingmirrored     ⌈ \Lceilingmirrored
893%
894% \installmathfencepair ⟨ \Langle               ⟩ \Rangle
895% \installmathfencepair ⟩ \Ranglemirrored       ⟨ \Langlemirrored
896%
897% \installmathfencepair ⟪ \Ldoubleangle         ⟫ \Rdoubleangle
898% \installmathfencepair ⟫ \Rdoubleanglemirrored ⟪ \Ldoubleanglemirrored
899%
900% \installmathfencepair ‖ \Ldoublebar           ‖ \Rdoublebar
901% %installmathfencepair ‖ \Rdoublebarmirrored   ‖ \Ldoublebarmirrored
902%
903% \installmathfencepair ⦀ \Ltriplebar           ⦀ \Rtriplebar
904% %installmathfencepair ⦀ \Rtriplebarmirrored   ⦀ \Ltriplebarmirrored
905%
906% % \installmathfencepair { \Lbrace             } \Rbrace
907% % \installmathfencepair } \Rbracemirrored     { \Lbracemirrored
908%
909% \installmathfencepair ⦗ \Linterval            ⦘ \Rinterval
910
911% \appendtoks
912%     \ignorediscretionaries % so $\mtext{a|b}$ works, this is ok because it's an \hbox
913% \to \everymathematics
914
915% We unofficial support some synonyms as we need them for some fuzzy web related math.
916
917% The names in char-def.lua (historic mess):
918
919\pushoverloadmode
920
921\aliased\let\lbrack      \lbracket
922\aliased\let\rbrack      \rbracket
923\aliased\let\lceiling    \lceil
924\aliased\let\rceiling    \rceil
925\aliased\let\lparenthesis\lparent
926\aliased\let\rparenthesis\rparent
927\aliased\let\lparen      \lparent
928\aliased\let\rparen      \rparent
929
930% Just defined:
931
932\aliased\let\Lceil  \Lceiling
933\aliased\let\Rceil  \Rceiling
934\aliased\let\Lparent\Lparenthesis
935\aliased\let\Rparent\Rparenthesis
936\aliased\let\Lparen \Lparenthesis
937\aliased\let\Rparen \Rparenthesis
938
939% \installmathfencepair \lbrace       \Lbrace       \rbrace       \Rbrace
940% \installmathfencepair \lbracket     \Lbracket     \rbracket     \Rbracket
941% \installmathfencepair \lbrack       \Lbracket     \rbracket     \Rbracket
942% \installmathfencepair \lparenthesis \Lparenthesis \rparenthesis \Rparenthesis
943% \installmathfencepair \lparent      \Lparenthesis \rparent      \Rparenthesis
944% \installmathfencepair \lparen       \Lparenthesis \rparen       \Rparenthesis
945% \installmathfencepair \langle       \Langle       \rangle       \Rangle
946% \installmathfencepair \llangle      \Ldoubleangle \rrangle      \Rdoubleangle
947% %installmathfencepair \lbar         \Lbar         \rbar         \Rbar
948% \installmathfencepair \lVert        \Ldoublebar   \rVert        \Rdoublebar
949% \installmathfencepair \vert         \Lbar         \vert         \Rbar
950% \installmathfencepair \solidus      \Lsolidus     \solidus      \Rsolidus
951% \installmathfencepair \lfloor       \Lfloor       \rfloor       \Rfloor
952% \installmathfencepair \lceiling     \Lceiling     \rceiling     \Rceiling
953% \installmathfencepair \lceil        \Lceiling     \rceil        \Rceiling
954
955% \installmathfencepair \ulcorner     \Luppercorner \urcorner     \Ruppercorner
956% \installmathfencepair \llcorner     \Llowercorner \lrcorner     \Rlowercorner
957% \installmathfencepair \lmoustache   \Lmoustache   \rmoustache   \Rmoustache
958% \installmathfencepair \llbracket    \Lopenbracket \rrbracket    \Ropenbracket
959% \installmathfencepair \lgroup       \Lgroup       \rgroup       \Rgroup
960
961% \installmathfencepair \linterval    \Linterval    \rinterval    \Rinterval
962% %installmathfencepair \linterv      \Linterval    \rinterv      \Rinterval
963% \installmathfencepair \lointerval   \Linterval    \rointerval   \Rinterval
964% \installmathfencepair \llointerval  \Llointerval  \rlointerval  \Rlointerval
965% \installmathfencepair \lrointerval  \Lrointerval  \rrointerval  \Rrointerval
966
967\aliased\let\textlbar\lbar \aliased\let\mathlbar\Lbar
968\aliased\let\textrbar\lbar \aliased\let\mathrbar\Rbar
969
970\immutable\protected\def\lbar{\mathortext\mathlbar\textlbar}
971\immutable\protected\def\rbar{\mathortext\mathrbar\textrbar}
972
973% \setupmathfences[color=darkgreen]
974
975% \permanent\protected\def\{{\mathortext\lbrace      \letterleftbrace       } % or maybe a chardef
976% \permanent\protected\def\}{\mathortext\rbrace      \letterrightbrace      } % or maybe a chardef
977% \permanent\protected\def\[{\mathortext\lbracket    \letterleftbracket     } % or maybe a chardef
978% \permanent\protected\def\]{\mathortext\rbracket    \letterrightbracket    } % or maybe a chardef
979% \permanent\protected\def\({\mathortext\lparenthesis\letterleftparenthesis } % or maybe a chardef
980% \permanent\protected\def\){\mathortext\rparenthesis\letterrightparenthesis} % or maybe a chardef
981% \permanent\protected\def\|{\mathortext\vert        \letterbar             } % or maybe a chardef
982% %permanent\protected\def\/{\mathortext\solidus     \letterslash           } % or maybe a chardef
983%
984% \installmathfencepair \{ \Lbrace        \} \Rbrace
985% \installmathfencepair \[ \Lbracket      \] \Rbracket
986% \installmathfencepair \( \Lparenthesis  \) \Rparenthesis
987% \installmathfencepair \< \Langle        \> \Rangle
988% \installmathfencepair \| \Lbar          \| \Rbar
989
990% isn't that already the case .. still needed in lua mode ?
991
992\aliased\let\{\letterleftbrace
993\aliased\let\}\letterrightbrace
994\aliased\let\[\letterleftbracket
995\aliased\let\]\letterrightbracket
996\aliased\let\(\letterleftparenthesis
997\aliased\let\)\letterrightparenthesis
998\aliased\let\|\letterbar
999%aliased\let\/\letterslash % italic correction
1000
1001\popoverloadmode
1002
1003%D As we have overloaded \type {\left} and \type {\right} we also need a more
1004%D clever version of the following:
1005
1006% variants:
1007%
1008% 1: step 1
1009% 2: step 2
1010% 3: htdp * 1.33^n
1011% 4: size * 1.33^n
1012
1013\setnewconstant\bigmathdelimitervariant\plusthree
1014
1015\appendtoks
1016    \bigmathdelimitervariant\mathfenceparameter\c!alternative\relax % controls lua
1017\to \everysetupmathfence
1018
1019\setupmathfence[\c!alternative=5] % the rest will probably go
1020
1021\permanent\protected\def\choosemathbig
1022  {\mathortext\math_choosemathbig_math\math_choosemathbig_text}
1023
1024\protected\def\math_choosemathbig_math#1#2% so we accept \big{||} as well
1025  {\math_fenced_force_size\bigmathdelimitervariant{#1}\relax
1026   \Uvextensible
1027     \s!axis
1028     \s!exact
1029     #2%
1030   \relax
1031   \c_attr_mathsize\attributeunsetvalue}
1032
1033\protected\def\math_choosemathbig_text#1#2% so we accept \big{||} as well
1034  {\naturalhbox\bgroup
1035      \startimath
1036        \math_choosemathbig_math{#1}{#2}%
1037        \nulldelimiterspace\zeropoint
1038        \mathsurround\zeropoint
1039      \stopimath
1040    \egroup}
1041
1042\permanent\protected\def\mathdelimiterstep#1#2% not used, only in example
1043  {\begingroup
1044   \math_fenced_force_size\plusone{#1}%
1045   \Uvextensible
1046     \s!axis
1047     \s!exact
1048     #2%
1049   \relax
1050   \endgroup}
1051
1052\definemathcommand [big]  {\choosemathbig1}
1053\definemathcommand [Big]  {\choosemathbig2}
1054\definemathcommand [bigg] {\choosemathbig3}
1055\definemathcommand [Bigg] {\choosemathbig4}
1056
1057\definemathcommand [bigl]  [\s!open]     [one] {\big}
1058\definemathcommand [bigm]  [\s!relation] [one] {\big}    % why not just middle
1059\definemathcommand [bigr]  [\s!close]    [one] {\big}
1060\definemathcommand [Bigl]  [\s!open]     [one] {\Big}
1061\definemathcommand [Bigm]  [\s!relation] [one] {\Big}
1062\definemathcommand [Bigr]  [\s!close]    [one] {\Big}
1063\definemathcommand [biggl] [\s!open]     [one] {\bigg}
1064\definemathcommand [biggm] [\s!relation] [one] {\bigg}
1065\definemathcommand [biggr] [\s!close]    [one] {\bigg}
1066\definemathcommand [Biggl] [\s!open]     [one] {\Bigg}
1067\definemathcommand [Biggm] [\s!relation] [one] {\Bigg}
1068\definemathcommand [Biggr] [\s!close]    [one] {\Bigg}
1069
1070% \definemathfence [integral] [\c!left="222B]
1071%
1072% \protected\def\Lintegral  {\math_fenced_fenced_start{integral}}
1073% \protected\def\Rintegral  {\math_fenced_fenced_stop {integral}}
1074%
1075% \installmathfencepair \lintegral \Lintegral \rintegral \Rintegral
1076%
1077% \left\lintegral
1078%     \vrule height 3cm depth 3cm
1079% \right\rintegral
1080
1081%definemathfence [fancybracket] [bracket] [define=yes,color=red]
1082
1083%D The nested fences recovery code is needed for mathml and the original
1084%D code can still be found in the mkiv file.
1085
1086\definesystemattribute[mathautofence][public]
1087
1088\let\math_fences_normal_left  \left
1089\let\math_fences_normal_right \right
1090\let\math_fences_normal_middle\middle
1091\let\math_fences_normal_both  \relax  % undefined
1092
1093\protected\def\math_fences_auto_left  #1{\c_attr_mathautofence\plusone  #1\c_attr_mathautofence\attributeunsetvalue}
1094\protected\def\math_fences_auto_right #1{\c_attr_mathautofence\plustwo  #1\c_attr_mathautofence\attributeunsetvalue}
1095\protected\def\math_fences_auto_middle#1{\c_attr_mathautofence\plusthree#1\c_attr_mathautofence\attributeunsetvalue}
1096\protected\def\math_fences_auto_both  #1{\c_attr_mathautofence\plusfour #1\c_attr_mathautofence\attributeunsetvalue}
1097
1098\permanent\let\autofenceopen  \math_fences_auto_left    % for testing
1099\permanent\let\autofenceclose \math_fences_auto_right   % for testing
1100\permanent\let\autofenceleft  \math_fences_auto_left    % for testing
1101\permanent\let\autofenceright \math_fences_auto_right   % for testing
1102\permanent\let\autofencemiddle\math_fences_auto_middle  % for testing
1103\permanent\let\autofenceboth  \math_fences_auto_both    % for testing
1104
1105% fences are used not that often (i.e. no performance issue) so we can use a state
1106% instead of \let ... also some state variable can come in handy in the future
1107
1108\newconditional\c_math_fences_auto
1109
1110\permanent\protected\def\enableautofences
1111  {\clf_enableautofences
1112   \c_math_fences_auto\conditionalfalse
1113   \glet\clf_enableautofences\relax % onlyonce anyway
1114   \enforced\permanent\protected\gdef\enableautofences{\c_math_fences_auto\conditionaltrue}%
1115   \enableautofences}
1116
1117\permanent\protected\def\disableautofences
1118  {\c_math_fences_auto\conditionalfalse}
1119
1120\permanent\protected\def\math_fences_used_left
1121  {\ifconditional\c_math_fences_auto
1122     \expandafter\math_fences_auto_left
1123   \else
1124     \expandafter\math_fences_normal_left
1125   \fi}
1126
1127\permanent\protected\def\math_fences_used_right
1128  {\ifconditional\c_math_fences_auto
1129     \expandafter\math_fences_auto_right
1130   \else
1131     \expandafter\math_fences_normal_right
1132   \fi}
1133
1134\permanent\protected\def\math_fences_used_middle
1135  {\ifconditional\c_math_fences_auto
1136     \expandafter\math_fences_auto_middle
1137   \else
1138     \expandafter\math_fences_normal_middle
1139   \fi}
1140
1141\permanent\protected\def\math_fences_used_both
1142  {\ifconditional\c_math_fences_auto
1143     \expandafter\math_fences_auto_both
1144   \else
1145     \expandafter\math_fences_normal_both
1146   \fi}
1147
1148\aliased\let\left       \math_fences_used_left
1149\aliased\let\right      \math_fences_used_right
1150\aliased\let\middle     \math_fences_used_middle
1151\aliased\let\leftorright\math_fences_used_both
1152
1153% \appendtoks
1154%     \enforced\let\left       \math_fences_used_left
1155%     \enforced\let\right      \math_fences_used_right
1156%     \enforced\let\middle     \math_fences_used_middle
1157%     \enforced\let\leftorright\math_fences_used_both
1158% \to \everymathematics
1159
1160% wrappers
1161
1162\permanent\protected\def\startcheckedfences
1163  {\begingroup
1164   \enableautofences}
1165
1166\permanent\protected\def\stopcheckedfences
1167  {\endgroup}
1168
1169\appendtoks
1170    \ifempty\currentmathfence
1171        \ifcstok{\mathfenceparameter\c!state}\v!auto\enableautofences\else\disableautofences\fi
1172    \fi
1173\to \everysetupmathfence
1174
1175\permanent\protected\def\enableautofencemode {\mathcheckfencesmode\plusone}
1176\permanent\protected\def\disableautofencemode{\mathcheckfencesmode\zerocount}
1177
1178\appendtoks
1179    \ifempty\currentmathfence
1180        \ifcstok{\mathfenceparameter\c!method}\v!auto\enableautofencemode\else\disableautofencemode\fi
1181    \fi
1182\to \everysetupmathfence
1183
1184% some day default: \setupmathfences[\c!state=\v!auto]
1185
1186%D The next characters were used for constructing nicer extensibles but
1187%D nowadays we have real characters.
1188
1189\immutable\Umathchardef\braceld\zerocount \zerocount "FF07A
1190\immutable\Umathchardef\bracerd\zerocount \zerocount "FF07B
1191\immutable\Umathchardef\bracelu\zerocount \zerocount "FF07C
1192\immutable\Umathchardef\braceru\zerocount \zerocount "FF07D
1193
1194%D Some tracing:
1195
1196\definefont[mathindexfont][Mono sa .2]
1197
1198\def\math_fenced_trace_indeed
1199  {%
1200   \beginlocalcontrol
1201     \registerboxanchor
1202     \registeranchorbox
1203       \registeredboxanchor
1204       \plusone
1205       \hbox
1206          \s!anchors \boxanchorpresetcode{depth} \boxanchorpresetcode{height}
1207          \s!yoffset -.1\exheight
1208          \s!target \registeredboxanchor
1209          \s!to \zeropoint
1210          {\darkblue\hss\mathindexfont\ruledhbox{\the\c_math_fence_nesting}\hss}%
1211   \endlocalcontrol
1212   \s!source \registeredboxanchor
1213   }
1214
1215% \def\math_fenced_trace_indeed
1216%   {%
1217%    \beginlocalcontrol
1218%      \registerboxanchor
1219%      \registeranchorbox
1220%        \registeredboxanchor
1221%        \plusone
1222%        \ruledhbox
1223%           \s!anchors \boxanchorpresetcode{depth} \boxanchorpresetcode{height}
1224%           \s!yoffset -.1\exheight
1225%           \s!target \registeredboxanchor
1226%           \s!to \zeropoint
1227%           {\darkblue\hss\mathindexfont\ruledhbox{\the\c_math_fence_nesting B}\hss}%
1228%      \registeranchorbox
1229%        \registeredboxanchor
1230%        \plusone
1231%        \ruledhbox
1232%           \s!anchors \boxanchorpresetcode{height} \boxanchorpresetcode{depth}
1233%           \s!yoffset .1\exheight
1234%           \s!target \registeredboxanchor
1235%           \s!to \zeropoint
1236%           {\darkgreen\hss\mathindexfont\ruledhbox{\the\c_math_fence_nesting T}\hss}%
1237%      \registeranchorbox
1238%        \registeredboxanchor
1239%        \plusone
1240%        \ruledhbox
1241%           \s!anchors \boxanchorpresetcode{left} \boxanchorpresetcode{right}
1242%           \s!xoffset -.1\emwidth
1243%           \s!target \registeredboxanchor
1244%           \s!to \zeropoint
1245%           {\darkred\hss\mathindexfont\ruledhbox{\the\c_math_fence_nesting L}}%
1246%      \registeranchorbox
1247%        \registeredboxanchor
1248%        \plusone
1249%        \ruledhbox
1250%           \s!anchors \boxanchorpresetcode{right} \boxanchorpresetcode{left}
1251%           \s!xoffset .1\emwidth
1252%           \s!target \registeredboxanchor
1253%           \s!to \zeropoint
1254%           {\darkyellow\mathindexfont\ruledhbox{\the\c_math_fence_nesting R}\hss}%
1255%    \endlocalcontrol
1256%    \s!source \registeredboxanchor
1257%    }
1258
1259\installtextracker
1260   {math.fencenesting}
1261   {\let\math_fenced_trace\math_fenced_trace_indeed}
1262   {\let\math_fenced_trace\donothing}
1263
1264\mutable\integerdef\c_math_fence_level\minusone
1265
1266\appendtoks
1267    \integerdef\c_math_fence_level\minusone
1268    \c_math_fence_nesting\zerocount
1269\to \everymathematics
1270
1271%D Experiment:
1272
1273\permanent\protected\def\autofences
1274  {\setmathoptions\mathopencode\numexpression
1275      \setmathoptions\mathopencode bor \autoinjectclassoptioncode
1276   \relax
1277   \setmathoptions\mathclosecode\numexpression
1278     \setmathoptions\mathclosecode bor \autoinjectclassoptioncode
1279   \relax
1280   \setmathoptions\mathmiddlecode\numexpression
1281     \setmathoptions\mathmiddlecode bor \autoinjectclassoptioncode
1282   \relax}
1283
1284%D New (to be completed):
1285
1286% $x + \tupdownarrows{left}{right} + x$
1287% $x + \tdownuparrows{left}{right} + x$
1288% $x + \tupanddownarrows[color=red,leftcolor=green,rightcolor=blue]{left}{right} + x$
1289
1290\definemathfence [tupanddownarrows][\v!text][\c!left="2191,\c!right="2193]
1291\definemathfence [tupdownarrows]   [\v!text][\c!left="21C5,\c!right=0]
1292\definemathfence [tdownuparrows]   [\v!text][\c!middle="21F5]
1293\definemathfence [tuparrow]        [\v!text][\c!middle="2191]
1294\definemathfence [tdownarrow]      [\v!text][\c!middle="2193]
1295
1296\protect
1297