math-fen.mkiv /size: 35 Kb    last modification: 2020-07-01 14:35
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% maybe always "method=auto" for:
19%
20% \switchtobodyfont[cambria]
21% \ruledhbox{$f(x)$}
22% \ruledhbox{\mathdelimitersmode6$f\left(x\right)$}
23% \ruledhbox{\mathdelimitersmode7$f\left(x\right)$}
24% \ruledhbox{$f\left(\frac{1}{x}\right)$}
25
26% todo: mathstyle
27
28% \definemathfence [fancybracket] [bracket] [command=yes,color=blue]
29%
30% test $|x|$ test \par
31% test $||x||$ test (okay) \par
32% test $a\left|\frac{1}{b}\right|c$ test \par
33% test $a\left||\frac{1}{b}\right||c$ test (not okay) \par
34%
35% \setupmathfences [color=red]
36%
37% test $a\fenced[bar]{\frac{1}{b}}c$ test \par
38% test $a\fenced[doublebar]{\frac{1}{b}}c$ test \par
39% test $a\fenced[bracket]{\frac{1}{b}}c$ test \par
40% test $a\fancybracket{\frac{1}{b}}c$ test \par
41
42\installcorenamespace{mathfences}
43
44\installcommandhandler \??mathfences {mathfence} \??mathfences
45
46\let\setupmathfences\setupmathfence
47
48\setupmathfences
49  [\c!method=, % maybe always \v!auto
50   \c!left=,
51   \c!right=,
52   \c!middle=,
53   \c!mathstyle=,
54   \c!color=,
55   \c!command=,
56   \c!mathclass=,
57   \c!factor=\v!auto]
58
59\appendtoks
60    \edef\p_command{\mathfenceparameter\c!command}%
61    \ifx\p_command\v!yes
62        \setuevalue\currentmathfence{\math_fenced_fenced[\currentmathfence]}%
63    \fi
64\to \everydefinemathfence
65
66% we need the direct use of \Udelimiter because of { etc
67
68%D So we can do:
69%D
70%D \starttyping
71%D $ a + \fenced[bar][size=1]   {\frac {b} {c}} + d $
72%D $ a + \fenced[bar][size=2]   {\frac {b} {c}} + d $
73%D $ a + \fenced[bar][size=3]   {\frac {b} {c}} + d $
74%D $ a + \fenced[bar][size=4]   {\frac {b} {c}} + d $
75%D $ a + \fenced[bar][size=big] {\frac {b} {c}} + d $
76%D $ a + \fenced[bar][size=Big] {\frac {b} {c}} + d $
77%D $ a + \fenced[bar][size=bigg]{\frac {b} {c}} + d $
78%D $ a + \fenced[bar][size=Bigg]{\frac {b} {c}} + d $
79%D $ a + \fenced[bar][factor=1] {\frac {b} {c}} + d $
80%D $ a + \fenced[bar][factor=2] {\frac {b} {c}} + d $
81%D $ a + \fenced[bar][factor=4] {\frac {b} {c}} + d $
82%D $ a + \fenced[bar]           {\frac {b} {c}} + d $
83%D \stoptyping
84
85\newconditional\c_math_fenced_mirror \settrue \c_math_fenced_mirror
86\newconditional\c_math_fenced_sized  \setfalse\c_math_fenced_sized
87
88\installcorenamespace {mathfencesize}
89
90\setvalue{\??mathfencesize  big}{1}
91\setvalue{\??mathfencesize  Big}{2}
92\setvalue{\??mathfencesize bigg}{3}
93\setvalue{\??mathfencesize Bigg}{4}
94
95\def\math_fenced_force_size#1#2%
96  {\c_attr_mathsize\numexpr
97     #1*\plushundred
98    +\ifcsname\??mathfencesize#2\endcsname\lastnamedcs\else#2\fi
99   \relax}
100
101\unexpanded\def\math_fenced_inject#1#2#3#4%
102  {\ifx#1\empty
103     #2.%
104   \else
105     \edef\p_mathclass{\mathfenceparameter\c!mathclass}%
106     \ifconditional\c_math_fenced_sized
107       \let\p_factor\v!fixed
108     \else
109       \edef\p_factor{\mathfenceparameter\c!factor}%
110     \fi
111     \ifx\p_factor\empty
112       \ifx\p_mathclass\empty
113         #2%
114       \else
115         #3%
116         \s!class\p_mathclass
117       \fi
118     \else\ifx\p_factor\v!auto
119       \ifx\p_mathclass\empty
120         #2%
121       \else
122         #3%
123         \s!class\p_mathclass
124       \fi
125     \else\ifx\p_factor\v!none
126       #3%
127       \s!height\zeropoint
128       \s!depth\zeropoint
129       \ifx\p_mathclass\empty\else
130         \s!class\p_mathclass
131       \fi
132       \s!axis
133     % #2%
134     \else
135       \ifx\p_factor\v!fixed
136          \scratchdimen\scaledpoint
137       \else
138          \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax
139       \fi
140       #3%
141       \s!height\scratchdimen
142       \s!depth\scratchdimen
143       \ifx\p_mathclass\empty\else
144         \s!class\p_mathclass
145       \fi
146       \s!axis
147     \fi\fi\fi
148     \Udelimiter#4\fam#1\relax
149   \fi}
150
151\def\math_fenced_left
152  {\edef\p_left
153     {\ifconditional\c_math_fenced_mirror
154        \ifconditional\c_math_right_to_left
155          \mathfenceparameter\c!right
156        \else
157          \mathfenceparameter\c!left
158        \fi
159      \else
160        \mathfenceparameter\c!left
161      \fi}%
162   \math_fenced_color_push
163   \math_fenced_inject\p_left\normalleft\Uleft\plusfour
164   \math_fenced_color_pop}
165
166\def\math_fenced_middle
167  {\edef\p_middle
168     {\mathfenceparameter\c!middle}%
169   \mskip\thinmuskip
170   \math_fenced_color_push
171   \math_fenced_inject\p_middle\normalmiddle\Umiddle\plusfour
172   \math_fenced_color_pop
173   \mskip\thinmuskip}
174
175\def\math_fenced_right
176  {\edef\p_right
177     {\ifconditional\c_math_fenced_mirror
178        \ifconditional\c_math_right_to_left
179          \mathfenceparameter\c!left
180        \else
181          \mathfenceparameter\c!right
182        \fi
183      \else
184        \mathfenceparameter\c!right
185      \fi}%
186   \math_fenced_color_push
187   \math_fenced_inject\p_right\normalright\Uright\plusfive
188   \math_fenced_color_pop}
189
190\def\math_fenced_color_do_push{\pushcolor[\p_math_fenced_color]}
191\let\math_fenced_color_do_pop  \popcolor
192
193\let\math_fenced_color_push\donothing
194\let\math_fenced_color_pop \donothing
195
196\let\fence \relax
197\let\fenced\relax
198
199\newcount\c_math_fenced_nesting
200
201\unexpanded\def\math_fenced_fenced_common
202  {\startusemathstyleparameter\mathfenceparameter
203   \let\fence\math_fenced_middle
204   \edef\p_math_fenced_color{\mathfenceparameter\c!color}%
205   \ifx\p_math_fenced_color\empty
206     \let\math_fenced_color_push\donothing
207     \let\math_fenced_color_pop \donothing
208   \else
209     \let\math_fenced_color_push\math_fenced_color_do_push
210     \let\math_fenced_color_pop \math_fenced_color_do_pop
211   \fi}
212
213\unexpanded\def\math_fenced_fenced_start#1%
214  {\advance\c_math_fenced_nesting\plusone
215   \begingroup
216   \edef\currentmathfence{#1}%
217   \math_fenced_fenced_common
218   \math_fenced_left}
219
220\unexpanded\def\math_fenced_fenced_stop#1%
221  {\edef\currentmathfence{#1}%
222   \math_fenced_right
223   \stopusemathstyleparameter
224   \endgroup
225   \advance\c_math_fenced_nesting\minusone}
226
227\unexpanded\def\math_fenced_fenced[#1]%
228  {\advance\c_math_fenced_nesting\plusone
229   \begingroup
230   \edef\currentmathfence{#1}%
231   \dosingleempty\math_fenced_fenced_indeed}
232
233% \unexpanded\def\math_fenced_fenced_indeed[#1]#2%
234%   {\iffirstargument\setupcurrentmathfence[#1]\fi
235%    \math_fenced_fenced_common
236%    \edef\p_size{\mathfenceparameter\c!size}%
237%    \ifx\p_size\empty
238%       \setfalse\c_math_fenced_sized
239%    \else
240%       \settrue\c_math_fenced_sized
241%       \math_fenced_force_size\bigmathdelimitervariant\p_size
242%    \fi
243%    \math_fenced_left
244%    #2%
245%    \math_fenced_right
246%    \stopusemathstyleparameter
247%    \endgroup
248%    \advance\c_math_fenced_nesting\minusone}
249
250\unexpanded\def\math_fenced_fenced_indeed[#1]%
251  {\iffirstargument\setupcurrentmathfence[#1]\fi
252   \math_fenced_fenced_common
253   \edef\p_size{\mathfenceparameter\c!size}%
254   \ifx\p_size\empty
255     \expandafter\math_fenced_fenced_indeed_adapt
256   \else
257     \expandafter\math_fenced_fenced_indeed_fixed
258   \fi}
259
260\unexpanded\def\math_fenced_fenced_indeed_finish
261  {\stopusemathstyleparameter
262   \endgroup
263   \advance\c_math_fenced_nesting\minusone}
264
265\unexpanded\def\math_fenced_fenced_indeed_fixed#1%
266  {\math_fenced_force_size\bigmathdelimitervariant\p_size
267   \settrue\c_math_fenced_sized
268   \math_fenced_left
269   \setfalse\c_math_fenced_sized
270   #1%
271   \settrue\c_math_fenced_sized
272   \math_fenced_right
273   \setfalse\c_math_fenced_sized
274   \math_fenced_fenced_indeed_finish}
275
276\unexpanded\def\math_fenced_fenced_indeed_adapt#1%
277  {\setfalse\c_math_fenced_sized
278   \math_fenced_left
279   #1%
280   \setfalse\c_math_fenced_sized
281   \math_fenced_right
282   \math_fenced_fenced_indeed_finish}
283
284\appendtoks
285    \let\fenced\math_fenced_fenced
286\to \everymathematics
287
288% todo: | in mathmode letter
289%
290% \appendtoks
291%     \let\bar\letterbar
292% \to \everymathematics
293%
294% but then we don't have it in embedded text too so ...
295
296\definemathfence [parenthesis] [\c!left="0028,\c!right="0029]
297\definemathfence [bracket]     [\c!left="005B,\c!right="005D]
298\definemathfence [brace]       [\c!left="007B,\c!right="007D]
299\definemathfence [bar]         [\c!left="007C,\c!right="007C]
300\definemathfence [doublebar]   [\c!left="2016,\c!right="2016]
301\definemathfence [triplebar]   [\c!left="2980,\c!right="2980]
302\definemathfence [angle]       [\c!left="27E8,\c!right="27E9]
303\definemathfence [doubleangle] [\c!left="27EA,\c!right="27EB]
304\definemathfence [solidus]     [\c!left="2044,\c!right="2044]
305\definemathfence [ceiling]     [\c!left="2308,\c!right="2309]
306\definemathfence [floor]       [\c!left="230A,\c!right="230B]
307\definemathfence [moustache]   [\c!left="23B0,\c!right="23B1]
308\definemathfence [uppercorner] [\c!left="231C,\c!right="231D]
309\definemathfence [lowercorner] [\c!left="231E,\c!right="231F]
310\definemathfence [group]       [\c!left="27EE,\c!right="27EF]
311\definemathfence [openbracket] [\c!left="27E6,\c!right="27E7]
312
313\definemathfence [nothing]
314
315\definemathfence [mirrored] % \v!mirrored
316
317\definemathfence [mirroredparenthesis] [mirrored] [\c!right="0028,\c!left="0029]
318\definemathfence [mirroredbracket]     [mirrored] [\c!right="005B,\c!left="005D]
319\definemathfence [mirroredbrace]       [mirrored] [\c!right="007B,\c!left="007D]
320\definemathfence [mirroredbar]         [mirrored] [\c!right="007C,\c!left="007C]
321\definemathfence [mirroreddoublebar]   [mirrored] [\c!right="2016,\c!left="2016]
322\definemathfence [mirroredtriplebar]   [mirrored] [\c!right="2980,\c!left="2980]
323\definemathfence [mirroredangle]       [mirrored] [\c!right="27E8,\c!left="27E9]
324\definemathfence [mirroreddoubleangle] [mirrored] [\c!right="27EA,\c!left="27EB]
325\definemathfence [mirroredsolidus]     [mirrored] [\c!right="2044,\c!left="2044]
326\definemathfence [mirroredceiling]     [mirrored] [\c!right="2308,\c!left="2309]
327\definemathfence [mirroredfloor]       [mirrored] [\c!right="230A,\c!left="230B]
328\definemathfence [mirroredmoustache]   [mirrored] [\c!right="23B0,\c!left="23B1]
329\definemathfence [mirroreduppercorner] [mirrored] [\c!right="231C,\c!left="231D]
330\definemathfence [mirroredlowercorner] [mirrored] [\c!right="231E,\c!left="231F]
331\definemathfence [mirroredgroup]       [mirrored] [\c!right="27EE,\c!left="27EF]
332\definemathfence [mirroredopenbracket] [mirrored] [\c!right="27E6,\c!left="27E7]
333
334\definemathfence [mirrorednothing]     [mirrored]
335
336%D A bonus:
337
338\unexpanded\def\Lparenthesis         {\math_fenced_fenced_start{parenthesis}}          \unexpanded\def\Rparenthesis         {\math_fenced_fenced_stop {parenthesis}}
339\unexpanded\def\Lbracket             {\math_fenced_fenced_start{bracket}}              \unexpanded\def\Rbracket             {\math_fenced_fenced_stop {bracket}}
340\unexpanded\def\Lbrace               {\math_fenced_fenced_start{brace}}                \unexpanded\def\Rbrace               {\math_fenced_fenced_stop {brace}}
341\unexpanded\def\Langle               {\math_fenced_fenced_start{angle}}                \unexpanded\def\Rangle               {\math_fenced_fenced_stop {angle}}
342\unexpanded\def\Ldoubleangle         {\math_fenced_fenced_start{doubleangle}}          \unexpanded\def\Rdoubleangle         {\math_fenced_fenced_stop {doubleangle}}
343\unexpanded\def\Lbar                 {\math_fenced_fenced_start{bar}}                  \unexpanded\def\Rbar                 {\math_fenced_fenced_stop {bar}}
344\unexpanded\def\Ldoublebar           {\math_fenced_fenced_start{doublebar}}            \unexpanded\def\Rdoublebar           {\math_fenced_fenced_stop {doublebar}}
345\unexpanded\def\Ltriplebar           {\math_fenced_fenced_start{triplebar}}            \unexpanded\def\Rtriplebar           {\math_fenced_fenced_stop {triplebar}}
346\unexpanded\def\Lsolidus             {\math_fenced_fenced_start{solidus}}              \unexpanded\def\Rsolidus             {\math_fenced_fenced_stop {solidus}}
347\unexpanded\def\Lfloor               {\math_fenced_fenced_start{floor}}                \unexpanded\def\Rfloor               {\math_fenced_fenced_stop {floor}}
348\unexpanded\def\Lceiling             {\math_fenced_fenced_start{ceiling}}              \unexpanded\def\Rceiling             {\math_fenced_fenced_stop {ceiling}}
349\unexpanded\def\Lmoustache           {\math_fenced_fenced_start{moustache}}            \unexpanded\def\Rmoustache           {\math_fenced_fenced_stop {moustache}}
350\unexpanded\def\Luppercorner         {\math_fenced_fenced_start{uppercorner}}          \unexpanded\def\Ruppercorner         {\math_fenced_fenced_stop {uppercorner}}
351\unexpanded\def\Llowercorner         {\math_fenced_fenced_start{lowercorner}}          \unexpanded\def\Rlowercorner         {\math_fenced_fenced_stop {lowercorner}}
352\unexpanded\def\Lgroup               {\math_fenced_fenced_start{group}}                \unexpanded\def\Rgroup               {\math_fenced_fenced_stop {group}}
353\unexpanded\def\Lopenbracket         {\math_fenced_fenced_start{openbracket}}          \unexpanded\def\Ropenbracket         {\math_fenced_fenced_stop {openbracket}}
354\unexpanded\def\Lnothing             {\math_fenced_fenced_start{nothing}}              \unexpanded\def\Rnothing             {\math_fenced_fenced_stop {nothing}}
355
356\unexpanded\def\Lparenthesismirrored {\math_fenced_fenced_stop {mirroredparenthesis}}  \unexpanded\def\Rparenthesismirrored {\math_fenced_fenced_start{mirroredparenthesis}}
357\unexpanded\def\Lbracketmirrored     {\math_fenced_fenced_stop {mirroredbracket}}      \unexpanded\def\Rbracketmirrored     {\math_fenced_fenced_start{mirroredbracket}}
358\unexpanded\def\Lbracemirrored       {\math_fenced_fenced_stop {mirroredbrace}}        \unexpanded\def\Rbracemirrored       {\math_fenced_fenced_start{mirroredbrace}}
359\unexpanded\def\Langlemirrored       {\math_fenced_fenced_stop {mirroredangle}}        \unexpanded\def\Ranglemirrored       {\math_fenced_fenced_start{mirroredangle}}
360\unexpanded\def\Ldoubleanglemirrored {\math_fenced_fenced_stop {mirroreddoubleangle}}  \unexpanded\def\Rdoubleanglemirrored {\math_fenced_fenced_start{mirroreddoubleangle}}
361\unexpanded\def\Lbarmirrored         {\math_fenced_fenced_stop {mirroredbar}}          \unexpanded\def\Rbarmirrored         {\math_fenced_fenced_start{mirroredbar}}
362\unexpanded\def\Ldoublebarmirrored   {\math_fenced_fenced_stop {mirroreddoublebar}}    \unexpanded\def\Rdoublebarmirrored   {\math_fenced_fenced_start{mirroreddoublebar}}
363\unexpanded\def\Ltriplebarmirrored   {\math_fenced_fenced_stop {mirroredtriplebar}}    \unexpanded\def\Rtriplebarmirrored   {\math_fenced_fenced_start{mirroredtriplebar}}
364\unexpanded\def\Lsolidusmirrored     {\math_fenced_fenced_stop {mirroredsolidus}}      \unexpanded\def\Rsolidusmirrored     {\math_fenced_fenced_start{mirroredsolidus}}
365\unexpanded\def\Lfloormirrored       {\math_fenced_fenced_stop {mirroredfloor}}        \unexpanded\def\Rfloormirrored       {\math_fenced_fenced_start{mirroredfloor}}
366\unexpanded\def\Lceilingmirrored     {\math_fenced_fenced_stop {mirroredceiling}}      \unexpanded\def\Rceilingmirrored     {\math_fenced_fenced_start{mirroredceiling}}
367\unexpanded\def\Lmoustachemirrored   {\math_fenced_fenced_stop {mirroredmoustache}}    \unexpanded\def\Rmoustachemirrored   {\math_fenced_fenced_start{mirroredmoustache}}
368\unexpanded\def\Luppercornermirrored {\math_fenced_fenced_stop {mirroreduppercorner}}  \unexpanded\def\Ruppercornermirrored {\math_fenced_fenced_start{mirroreduppercorner}}
369\unexpanded\def\Llowercornermirrored {\math_fenced_fenced_stop {mirroredlowercorner}}  \unexpanded\def\Rlowercornermirrored {\math_fenced_fenced_start{mirroredlowercorner}}
370\unexpanded\def\Lgroupmirrored       {\math_fenced_fenced_stop {mirroredgroup}}        \unexpanded\def\Rgroupmirrored       {\math_fenced_fenced_start{mirroredgroup}}
371\unexpanded\def\Lopenbracketmirrored {\math_fenced_fenced_stop {mirroredopenbracket}}  \unexpanded\def\Ropenbracketmirrored {\math_fenced_fenced_start{mirroredopenbracket}}
372\unexpanded\def\Lnothingmirrored     {\math_fenced_fenced_stop {mirrorednothing}}      \unexpanded\def\Rnothingmirrored     {\math_fenced_fenced_start{mirrorednothing}}
373
374\definemathfence [interval]                     [\c!left="2997,\c!right="2998]
375\definemathfence [openinterval]      [interval] [\c!left="2998,\c!right="2998]
376\definemathfence [leftopeninterval]  [interval] [\c!left="2997,\c!right="2997]
377\definemathfence [rightopeninterval] [interval] [\c!left="2998,\c!right="2998]
378
379\unexpanded\def\Linterval            {\math_fenced_fenced_start{interval}}
380\unexpanded\def\Lointerval           {\math_fenced_fenced_start{openinterval}}
381\unexpanded\def\Llointerval          {\math_fenced_fenced_start{leftopeninterval}}
382\unexpanded\def\Lrointerval          {\math_fenced_fenced_start{rightopeninterval}}
383
384\unexpanded\def\Rinterval            {\math_fenced_fenced_stop {interval}}
385\unexpanded\def\Rointerval           {\math_fenced_fenced_stop {openinterval}}
386\unexpanded\def\Rlointerval          {\math_fenced_fenced_stop {leftopeninterval}}
387\unexpanded\def\Rrointerval          {\math_fenced_fenced_stop {rightopeninterval}}
388
389% \startformula
390% \left{ \frac{1}{a} \right}
391% \left[ \frac{1}{b} \right]
392% \left( \frac{1}{c} \right)
393% \left< \frac{1}{d} \right>
394% \left| \frac{1}{e} \right|
395% \stopformula
396
397\installcorenamespace{mathleft}
398\installcorenamespace{mathright}
399\installcorenamespace{mathmiddle}
400
401\unexpanded\def\left  {\afterassignment\math_left  \let\nexttoken}
402\unexpanded\def\right {\afterassignment\math_right \let\nexttoken}
403\unexpanded\def\middle{\afterassignment\math_middle\let\nexttoken}
404
405\let\leftorright\relax
406
407\newconditional\c_math_fenced_done
408\newconditional\c_math_fenced_unknown  \settrue\c_math_fenced_unknown
409
410% maybe use \detokenize ... todo \lastnamedcs
411
412% \setvalue{\??mathleft  \s!unknown}{\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalleft  \nexttoken\fi}
413% \setvalue{\??mathright \s!unknown}{\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalright \nexttoken\fi}
414% \setvalue{\??mathmiddle\s!unknown}{\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalmiddle\nexttoken\fi}
415%
416% \def\math_left
417%   {\settrue\c_math_fenced_done
418%    \edef\m_math_left{\normalmeaning\nexttoken}%
419%    \csname\??mathleft\ifcsname\??mathleft\m_math_left\endcsname\m_math_left\else\s!unknown\fi\endcsname}
420%
421% \def\math_right
422%   {\settrue\c_math_fenced_done
423%    \edef\m_math_right{\normalmeaning\nexttoken}%
424%    \csname\??mathright\ifcsname\??mathright\m_math_right\endcsname\m_math_right\else\s!unknown\fi\endcsname}
425%
426% \def\math_middle
427%   {\settrue\c_math_fenced_done
428%    \edef\m_math_middle{\normalmeaning\nexttoken}%
429%    \csname\??mathmiddle\ifcsname\??mathmiddle\m_math_middle\endcsname\m_math_middle\else\s!unknown\fi\endcsname}
430%
431% \unexpanded\def\lfence#1%
432%   {\settrue\c_math_fenced_done
433%    \let\nexttoken#1%
434%    \edef\m_math_left{\normalmeaning#1}%
435%    \csname\??mathleft\ifcsname\??mathleft\m_math_left\endcsname\m_math_left\else\s!unknown\fi\endcsname}
436%
437% \unexpanded\def\rfence#1%
438%   {\settrue\c_math_fenced_done
439%    \let\nexttoken#1%
440%    \edef\m_math_right{\normalmeaning#1}%
441%    \csname\??mathright\ifcsname\??mathright\m_math_right\endcsname\m_math_right\else\s!unknown\fi\endcsname}
442%
443% \unexpanded\def\mfence#1%
444%   {\settrue\c_math_fenced_done
445%    \let\nexttoken#1%
446%    \edef\m_math_middle{\normalmeaning#1}%
447%    \csname\??mathmiddle\ifcsname\??mathmiddle\m_math_middle\endcsname\m_math_middle\else\s!unknown\fi\endcsname}
448
449\unexpanded\def\installmathfencepair#1#2#3#4%
450  {\expandafter\let\csname\??mathleft \normalmeaning#1\endcsname#2%
451   \expandafter\let\csname\??mathright\normalmeaning#3\endcsname#4}
452
453\def\math_unknown_left  {\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalleft  \nexttoken\fi}
454\def\math_unknown_right {\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalright \nexttoken\fi}
455\def\math_unknown_middle{\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalmiddle\nexttoken\fi}
456
457\letvalue{\??mathleft  \s!unknown}\math_unknown_left
458\letvalue{\??mathright \s!unknown}\math_unknown_right
459\letvalue{\??mathmiddle\s!unknown}\math_unknown_middle
460
461\def\math_left
462  {\settrue\c_math_fenced_done
463   \ifcsname\??mathleft\normalmeaning\nexttoken\endcsname
464     \expandafter\lastnamedcs
465   \else
466     \expandafter\math_unknown_left
467   \fi}
468
469\def\math_right
470  {\settrue\c_math_fenced_done
471   \ifcsname\??mathright\normalmeaning\nexttoken\endcsname
472     \expandafter\lastnamedcs
473   \else
474     \expandafter\math_unknown_right
475   \fi}
476
477\def\math_middle
478  {\settrue\c_math_fenced_done
479   \ifcsname\??mathmiddle\normalmeaning\nexttoken\endcsname
480     \expandafter\lastnamedcs
481   \else
482     \expandafter\math_unknown_middle
483   \fi}
484
485\unexpanded\def\lfence#1%
486  {\settrue\c_math_fenced_done
487   \let\nexttoken#1%
488   \ifcsname\??mathleft\normalmeaning\nexttoken\endcsname
489     \expandafter\lastnamedcs
490   \else
491     \expandafter\math_unknown_left
492   \fi}
493
494\unexpanded\def\rfence#1%
495  {\settrue\c_math_fenced_done
496   \let\nexttoken#1%
497   \ifcsname\??mathright\normalmeaning\nexttoken\endcsname
498     \expandafter\lastnamedcs
499   \else
500     \expandafter\math_unknown_right
501   \fi}
502
503\unexpanded\def\mfence#1%
504  {\settrue\c_math_fenced_done
505   \let\nexttoken#1%
506   \ifcsname\??mathmiddle\normalmeaning\nexttoken\endcsname
507     \expandafter\lastnamedcs
508   \else
509     \expandafter\math_unknown_middle
510   \fi}
511
512\normalexpanded{\installmathfencepair {|\detokenize {|}} \Ldoublebar {|\detokenize {|}} \Rdoublebar}
513\normalexpanded{\installmathfencepair {|\detokenize{||}} \Ltriplebar {|\detokenize{||}} \Rtriplebar}
514
515\installmathfencepair \bgroup \Lbrace         \egroup \Rbrace
516\installmathfencepair \egroup \Rbracemirrored \bgroup \Lbracemirrored
517
518\installmathfencepair \letteropenbrace \Lbrace \letterclosebrace \Rbrace % as we escape in mp textexts
519
520\installmathfencepair . \Lnothing             . \Rnothing
521\installmathfencepair . \Rnothingmirrored     . \Lnothingmirrored
522
523\installmathfencepair [ \Lbracket             ] \Rbracket
524\installmathfencepair ] \Rbracketmirrored     [ \Lbracketmirrored
525
526\installmathfencepair ( \Lparenthesis         ) \Rparenthesis
527\installmathfencepair ) \Rparenthesismirrored ( \Lparenthesismirrored
528
529\installmathfencepair < \Langle               > \Rangle
530\installmathfencepair > \Ranglemirrored       < \Langlemirrored
531
532\installmathfencepair / \Lsolidus             / \Rsolidus
533%installmathfencepair / \Rsolidusmirrored     / \Lsolidusmirrored
534
535\installmathfencepair | \Lbar                 | \Rbar
536%installmathfencepair | \Rbarmirrored         | \Lbarmirrored
537
538\installmathfencepair  \Lfloor                \Rfloor
539\installmathfencepair  \Rfloormirrored        \Lfloormirrored
540\installmathfencepair  \Lceiling              \Rceiling
541\installmathfencepair  \Rceilingmirrored      \Lceilingmirrored
542
543\installmathfencepair  \Langle                \Rangle
544\installmathfencepair  \Ranglemirrored        \Langlemirrored
545
546\installmathfencepair  \Ldoubleangle          \Rdoubleangle
547\installmathfencepair  \Rdoubleanglemirrored  \Ldoubleanglemirrored
548
549\installmathfencepair  \Ldoublebar            \Rdoublebar
550%installmathfencepair ‖ \Rdoublebarmirrored   ‖ \Ldoublebarmirrored
551
552\installmathfencepair  \Ltriplebar            \Rtriplebar
553%installmathfencepair ⦀ \Rtriplebarmirrored   ⦀ \Ltriplebarmirrored
554
555% \installmathfencepair { \Lbrace             } \Rbrace
556% \installmathfencepair } \Rbracemirrored     { \Lbracemirrored
557
558\installmathfencepair  \Linterval             \Rinterval
559
560\appendtoks
561    \ignorediscretionaries % so $\mtext{a|b}$ works, this is ok because it's an \hbox
562\to \everymathematics
563
564% We unofficial support some synonyms as we need them for some fuzzy web related math.
565
566% The names in char-def.lua (historic mess):
567
568\let\lbrack      \lbracket
569\let\rbrack      \rbracket
570\let\lceiling    \lceil
571\let\rceiling    \rceil
572\let\lparenthesis\lparent
573\let\rparenthesis\rparent
574\let\lparen      \lparent
575\let\rparen      \rparent
576
577% Just defined:
578
579\let\Lceil  \Lceiling
580\let\Rceil  \Rceiling
581\let\Lparent\Lparenthesis
582\let\Rparent\Rparenthesis
583\let\Lparen \Lparenthesis
584\let\Rparen \Rparenthesis
585
586\installmathfencepair \lbrace       \Lbrace       \rbrace       \Rbrace
587\installmathfencepair \lbracket     \Lbracket     \rbracket     \Rbracket
588\installmathfencepair \lbrack       \Lbracket     \rbracket     \Rbracket
589\installmathfencepair \lparenthesis \Lparenthesis \rparenthesis \Rparenthesis
590\installmathfencepair \lparent      \Lparenthesis \rparent      \Rparenthesis
591\installmathfencepair \lparen       \Lparenthesis \rparen       \Rparenthesis
592\installmathfencepair \langle       \Langle       \rangle       \Rangle
593\installmathfencepair \llangle      \Ldoubleangle \rrangle      \Rdoubleangle
594%installmathfencepair \lbar         \Lbar         \rbar         \Rbar
595\installmathfencepair \lVert        \Ldoublebar   \rVert        \Rdoublebar
596\installmathfencepair \vert         \Lbar         \vert         \Rbar
597\installmathfencepair \solidus      \Lsolidus     \solidus      \Rsolidus
598\installmathfencepair \lfloor       \Lfloor       \rfloor       \Rfloor
599\installmathfencepair \lceiling     \Lceiling     \rceiling     \Rceiling
600\installmathfencepair \lceil        \Lceiling     \rceil        \Rceiling
601
602\installmathfencepair \ulcorner     \Luppercorner \urcorner     \Ruppercorner
603\installmathfencepair \llcorner     \Llowercorner \lrcorner     \Rlowercorner
604\installmathfencepair \lmoustache   \Lmoustache   \rmoustache   \Rmoustache
605\installmathfencepair \llbracket    \Lopenbracket \rrbracket    \Ropenbracket
606\installmathfencepair \lgroup       \Lgroup       \rgroup       \Rgroup
607
608\installmathfencepair \linterval    \Linterval    \rinterval    \Rinterval
609%installmathfencepair \linterv      \Linterval    \rinterv      \Rinterval
610\installmathfencepair \lointerval   \Linterval    \rointerval   \Rinterval
611\installmathfencepair \llointerval  \Llointerval  \rlointerval  \Rlointerval
612\installmathfencepair \lrointerval  \Lrointerval  \rrointerval  \Rrointerval
613
614\let\textlbar\lbar \let\mathlbar\Lbar
615\let\textrbar\lbar \let\mathrbar\Rbar
616
617\unexpanded\def\lbar{\mathortext\mathlbar\textlbar}
618\unexpanded\def\rbar{\mathortext\mathrbar\textrbar}
619
620% \setupmathfences[color=darkgreen]
621
622\unexpanded\def\{{\mathortext\lbrace      \letterleftbrace       } % or maybe a chardef
623\unexpanded\def\}{\mathortext\rbrace      \letterrightbrace      } % or maybe a chardef
624\unexpanded\def\[{\mathortext\lbracket    \letterleftbracket     } % or maybe a chardef
625\unexpanded\def\]{\mathortext\rbracket    \letterrightbracket    } % or maybe a chardef
626\unexpanded\def\({\mathortext\lparenthesis\letterleftparenthesis } % or maybe a chardef
627\unexpanded\def\){\mathortext\rparenthesis\letterrightparenthesis} % or maybe a chardef
628\unexpanded\def\|{\mathortext\vert        \letterbar             } % or maybe a chardef
629%unexpanded\def\/{\mathortext\solidus     \letterslash           } % or maybe a chardef
630
631\installmathfencepair \{ \Lbrace        \} \Rbrace
632\installmathfencepair \[ \Lbracket      \] \Rbracket
633\installmathfencepair \( \Lparenthesis  \) \Rparenthesis
634\installmathfencepair \< \Langle        \> \Rangle
635\installmathfencepair \| \Lbar          \| \Rbar
636
637%D As we have overloaded \type {\left} and \type {\right} we also need a more
638%D clever version of the following:
639
640% methods:
641%
642% 1: none
643% 2: lua
644% 3: tex
645
646% variants:
647%
648% 1: step 1
649% 2: step 2
650% 3: htdp * 1.33^n
651% 4: size * 1.33^n
652
653\setnewconstant\bigmathdelimitermethod \plusone
654\setnewconstant\bigmathdelimitervariant\plusthree
655
656\unexpanded\def\plainbigdelimiters % traditional method
657  {\bigmathdelimitermethod\plustwo}
658
659\plainbigdelimiters % is default for the moment but not so nice
660
661% \setconstant\bigmathdelimitermethod\plusone
662
663\installcorenamespace{mathbig}
664
665\setvalue{\??mathbig1}{0.85}
666\setvalue{\??mathbig2}{1.15}
667\setvalue{\??mathbig3}{1.45}
668\setvalue{\??mathbig4}{1.75}
669
670\unexpanded\def\choosemathbig#1#2% so we accept \big{||} as well
671  {{\naturalhbox\bgroup
672      \startimath
673        \ifcase\bigmathdelimitermethod
674          \math_fenced_step#2\relax
675        \or
676          \math_fenced_force_size\bigmathdelimitervariant{#1}\relax
677          \math_fenced_step#2\relax
678        \else
679          \math_fenced_step#2{\vpack to\csname\??mathbig#1\endcsname\bodyfontsize{}}%
680        \fi
681        \nulldelimiterspace\zeropoint\relax
682        \mathsurround\zeropoint
683      \stopimath
684    \egroup}}
685
686% needs testing:
687%
688% \unexpanded\def\choosemathbig#1#2% so we accept \big{||} as well
689%   {{\naturalhbox\bgroup
690%       \startimath
691%         \ifcase\bigmathdelimitermethod
692%           \Uvextensible#2\relax
693%         \or
694%           \math_fenced_force_size\bigmathdelimitervariant{#1}\relax
695%           \Uvextensible#2\relax
696%         \else
697%           \scratchdimen.5\dimexpr\csname\??mathbig\number#1\endcsname\bodyfontsize+1.1\exheight\relax
698%           \Uvextensible\s!axis \s!depth \scratchdimen \s!height \scratchdimen #2\relax
699%         \fi
700%         \nulldelimiterspace\zeropoint\relax
701%         \mathsurround\zeropoint
702%       \stopimath
703%     \egroup}}
704
705\def\math_fenced_step#1#2%
706  {\setfalse\c_math_fenced_unknown
707   \setfalse\c_math_fenced_done
708   \left#1\relax
709   \ifconditional\c_math_fenced_done
710     #2%
711     \right.\relax
712   \else
713     \left.\relax
714     #2%
715     \setfalse\c_math_fenced_done
716     \right#1\relax
717     \ifconditional\c_math_fenced_done
718     \else
719       \right.\relax
720     \fi
721   \fi}
722
723\unexpanded\def\mathdelimiterstep#1#2%
724  {\begingroup
725   \math_fenced_force_size\plusone{#1}%
726   \math_fenced_step#2\relax
727   \endgroup}
728
729\definemathcommand [big]  {\choosemathbig1}
730\definemathcommand [Big]  {\choosemathbig2}
731\definemathcommand [bigg] {\choosemathbig3}
732\definemathcommand [Bigg] {\choosemathbig4}
733
734\definemathcommand [bigl]  [open]  [one] {\big}
735\definemathcommand [bigm]  [rel]   [one] {\big}
736\definemathcommand [bigr]  [close] [one] {\big}
737\definemathcommand [Bigl]  [open]  [one] {\Big}
738\definemathcommand [Bigm]  [rel]   [one] {\Big}
739\definemathcommand [Bigr]  [close] [one] {\Big}
740\definemathcommand [biggl] [open]  [one] {\bigg}
741\definemathcommand [biggm] [rel]   [one] {\bigg}
742\definemathcommand [biggr] [close] [one] {\bigg}
743\definemathcommand [Biggl] [open]  [one] {\Bigg}
744\definemathcommand [Biggm] [rel]   [one] {\Bigg}
745\definemathcommand [Biggr] [close] [one] {\Bigg}
746
747% \definemathfence [integral] [\c!left="222B]
748%
749% \unexpanded\def\Lintegral  {\math_fenced_fenced_start{integral}}
750% \unexpanded\def\Rintegral  {\math_fenced_fenced_stop {integral}}
751%
752% \installmathfencepair \lintegral \Lintegral \rintegral \Rintegral
753%
754% \left\lintegral
755%     \vrule height 3cm depth 3cm
756% \right\rintegral
757
758%definemathfence [fancybracket] [bracket] [command=yes,color=red]
759
760% experimental accents:
761%
762% \definemathoverextensible [top] [hoed]  ["FE302]
763% \definemathoverextensible [top] [slang] ["FE303]
764
765%D This is needed for mathml (used in mrow, so it gets reset):
766
767% old code:
768
769% \let\math_fences_saved_left  \left
770% \let\math_fences_saved_middle\middle
771% \let\math_fences_saved_right \right
772%
773% % \def\math_fences_traced#1{\ruledhbox{\ttx#1\low{\the\c_math_fenced_nesting}}}
774%
775% \unexpanded\def\math_fences_checked_left
776%   {%\math_fences_traced L%
777%    \math_fences_saved_left}
778%
779% \unexpanded\def\math_fences_checked_middle
780%   {%\math_fences_traced M%
781%    \ifcase\c_math_fenced_nesting
782%      \expandafter\math_fences_saved_middle
783%    \else
784%      \expandafter\firstofoneargument
785%    \fi}
786%
787% \unexpanded\def\math_fences_checked_right
788%   {%\math_fences_traced R%
789%    \ifcase\c_math_fenced_nesting
790%      \expandafter\firstofoneargument
791%    \else
792%      \expandafter\math_fences_saved_right
793%    \fi}
794%
795% \newconditional\c_math_checked_done % only bars
796%
797% \unexpanded\def\math_fences_checked_left_or_right
798%   {%\math_fences_traced B%
799%    \ifcase\c_math_fenced_nesting
800%      \settrue\c_math_checked_done
801%      \expandafter\math_fences_saved_left
802%    \else\ifconditional\c_math_checked_done
803%      \setfalse\c_math_checked_done
804%      \doubleexpandafter\math_fences_saved_right
805%    \else
806%      \doubleexpandafter\math_fences_saved_middle
807%    \fi\fi}
808%
809% \unexpanded\def\math_fences_checked_start
810%   {\c_math_fenced_nesting\zerocount}
811%
812% \unexpanded\def\math_fences_checked_stop
813%   {\ifcase\c_math_fenced_nesting\else
814%      \right.\relax % error, todo: nil spacing
815%      \expandafter\math_fences_checked_stop
816%    \fi}
817%
818% \unexpanded\def\startcheckedfences
819%   {\begingroup
820%    \let\left  \math_fences_checked_left
821%    \let\middle\math_fences_checked_middle
822%    \let\right \math_fences_checked_right
823%    \math_fences_checked_start}
824%
825% \unexpanded\def\stopcheckedfences
826%   {\math_fences_checked_stop
827%    \endgroup}
828%
829% \let\leftorright\math_fences_checked_left_or_right % for bars
830
831\definesystemattribute[mathautofence][public]
832
833\let\math_fences_normal_left  \left
834\let\math_fences_normal_right \right
835\let\math_fences_normal_middle\middle
836\let\math_fences_normal_both  \leftorright
837
838\unexpanded\def\math_fences_auto_left  #1{\c_attr_mathautofence\plusone  #1\c_attr_mathautofence\attributeunsetvalue}
839\unexpanded\def\math_fences_auto_right #1{\c_attr_mathautofence\plustwo  #1\c_attr_mathautofence\attributeunsetvalue}
840\unexpanded\def\math_fences_auto_middle#1{\c_attr_mathautofence\plusthree#1\c_attr_mathautofence\attributeunsetvalue}
841\unexpanded\def\math_fences_auto_both  #1{\c_attr_mathautofence\plusfour #1\c_attr_mathautofence\attributeunsetvalue}
842
843\let\autofenceopen  \math_fences_auto_left    % for testing
844\let\autofenceclose \math_fences_auto_right   % for testing
845\let\autofenceleft  \math_fences_auto_left    % for testing
846\let\autofenceright \math_fences_auto_right   % for testing
847\let\autofencemiddle\math_fences_auto_middle  % for testing
848\let\autofenceboth  \math_fences_auto_both    % for testing
849
850% fences are used not that often (i.e. no performance issue) so we can use a state
851% instead of \let ... also some state variable can come in handy in the future
852
853\newconditional\c_math_fences_auto
854
855\unexpanded\def\enableautofences
856  {\clf_enableautofences
857   \glet\clf_enableautofences\relax % onlyonce anyway
858   \unexpanded\gdef\enableautofences{\settrue\c_math_fences_auto}%
859   \enableautofences}
860
861\unexpanded\def\disableautofences
862  {\setfalse\c_math_fences_auto}
863
864\unexpanded\def\math_fences_used_left
865  {\ifconditional\c_math_fences_auto
866     \expandafter\math_fences_auto_left
867   \else
868     \expandafter\math_fences_normal_left
869   \fi}
870\unexpanded\def\math_fences_used_right
871  {\ifconditional\c_math_fences_auto
872     \expandafter\math_fences_auto_right
873   \else
874     \expandafter\math_fences_normal_right
875   \fi}
876\unexpanded\def\math_fences_used_middle
877  {\ifconditional\c_math_fences_auto
878     \expandafter\math_fences_auto_middle
879   \else
880     \expandafter\math_fences_normal_middle
881   \fi}
882\unexpanded\def\math_fences_used_both
883  {\ifconditional\c_math_fences_auto
884     \expandafter\math_fences_auto_both
885   \else
886     \expandafter\math_fences_normal_both
887   \fi}
888
889\let\left       \math_fences_used_left
890\let\right      \math_fences_used_right
891\let\middle     \math_fences_used_middle
892\let\leftorright\math_fences_used_both
893
894% wrappers
895
896\unexpanded\def\startcheckedfences
897  {\begingroup
898   \enableautofences}
899
900\unexpanded\def\stopcheckedfences
901  {\endgroup}
902
903% \appendtoks
904   % maybe: safeguard against overloading
905   %
906   % \let\left       \math_fences_used_left
907   % \let\right      \math_fences_used_right
908   % \let\middle     \math_fences_used_middle
909   % \let\leftorright\math_fences_used_both
910% \to \everymathematics
911
912\appendtoks
913    \ifx\currentmathfence\empty
914        \doifelse{\mathfenceparameter\c!state}\v!auto\enableautofences\disableautofences
915    \fi
916\to \everysetupmathfence
917
918\newconstant\c_math_fences_delimiters_mode \c_math_fences_delimiters_mode"16 % \numexpr"02+"04+"10\relax
919
920%unexpanded\def\enableautofencemode {\mathdelimitersmode\plussix} % the shift (1) is too fragile
921\unexpanded\def\enableautofencemode {\mathdelimitersmode\c_math_fences_delimiters_mode}
922
923\unexpanded\def\disableautofencemode{\mathdelimitersmode\zerocount}
924
925\appendtoks
926    \ifx\currentmathfence\empty
927        \doifelse{\mathfenceparameter\c!method}\v!auto\enableautofencemode\disableautofencemode
928    \fi
929\to \everysetupmathfence
930
931% some day default: \setupmathfences[\c!state=\v!auto]
932
933%D The next characters were used for constructing nicer extensibles but
934%D nowadays we have real characters.
935
936\Umathchardef\braceld\zerocount \defaultmathfamily "FF07A
937\Umathchardef\bracerd\zerocount \defaultmathfamily "FF07B
938\Umathchardef\bracelu\zerocount \defaultmathfamily "FF07C
939\Umathchardef\braceru\zerocount \defaultmathfamily "FF07D
940
941\protect
942