math-rad.mklx /size: 12 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=math-rad,
3%D        version=2013.07.13,
4%D          title=\CONTEXT\ Math Macros,
5%D       subtitle=Radicals,
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 / Radicals}
15
16\registerctxluafile{math-rad}{autosuffix}
17
18\unprotect
19
20%D \starttyping
21%D $\sqrt[3]{10}$
22%D \stoptyping
23
24%D The real thing. If needed one can control matters with one of the many
25%D \type {\Umath...} parameters.
26%D
27%D \starttyping
28%D \def\R {\Umathradicaldegreeafter\textstyle0pt}
29%D \def\RR{\Umathradicaldegreeafter\textstyle\dimexpr
30%D    \Umathradicaldegreeafter\textstyle+.1em\relax}
31%D \def\RRR{\frozen\Umathradicaldegreeafter\textstyle\dimexpr
32%D    \Umathradicaldegreeafter\textstyle+.2em\relax}
33%D
34%D $    \sqrt[3]{5}   \RR\sqrt[3]{5}  \sqrt[3]{5} $\par
35%D $    \sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
36%D $ \RR\sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
37%D
38%D \def\R  {\Umathradicaldegreeafter\textstyle
39%D            0pt}
40%D \def\RR {\Umathradicaldegreeafter\textstyle
41%D            0.95\Umathradicaldegreeafter\textstyle}
42%D \def\RRR{\frozen\Umathradicaldegreeafter\textstyle
43%D            0.9\Umathradicaldegreeafter\textstyle}
44%D
45%D $    \sqrt[3]{5}   \RR\sqrt[3]{5}  \sqrt[3]{5} $\par
46%D $    \sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
47%D $ \RR\sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
48%D
49%D \def\RR {\mathopenupparameter\Umathradicaldegreeafter{.1}}
50%D
51%D $ \sqrt[3]{5}  \RR\sqrt[3]{5}  \sqrt[3]{5} $\par
52%D $ \sqrt[3]{5} {\RR\sqrt[3]{5}} \sqrt[3]{5} $\par
53%D \stoptyping
54%D
55%D And:
56%D
57%D \starttyping
58%D \definemathradical[lsqrt][strut=yes]
59%D \definemathradical[msqrt][strut=math]
60%D \definemathradical[xsqrt][height=3ex,depth=2ex]
61%D
62%D $\sqrt[strut=no][3]{y}$
63%D $\sqrt[strut=no,n=5]{y}$
64%D $\sqrt[strut=no,n=5][6]{y}$
65%D $\sqrt[strut=math]{y}$
66%D $\sqrt[3]{y}$
67%D \stoptyping
68
69\installcorenamespace{mathradical}
70\installcorenamespace{mathradicalalternative}
71
72\installcommandhandler \??mathradical {mathradical} \??mathradical
73
74\setupmathradical
75  [\c!alternative=\v!normal,
76   \c!mpoffset=.25\exheight,
77   \c!height=\zeropoint,
78   \c!depth=\zeropoint,
79   \c!strut=\v!height,
80 % \c!mindepth=\zeropoint,
81   \c!mindepth=.20\exheight, % a reasonable default for: \im { \sqrt{1+x} + \sqrt{1-x} }
82   \c!source=\zerocount,
83   \c!left="221A,
84   \c!symbolcolor=\mathradicalparameter\c!color,
85   \c!textcolor=\mathradicalparameter\c!color,
86   \c!numbercolor=\mathradicalparameter\c!color,
87   \c!mathstyle=\v!normal,
88   \c!right=\zerocount,
89   \c!leftmargin=\zeropoint,
90   \c!rightmargin=\zeropoint]
91
92\appendtoks
93    \frozen\protected\instance\edefcsname\currentmathradical\endcsname{\math_radical_handle{\currentmathradical}}
94\to \everydefinemathradical
95
96\mutable\lettonothing\currentmathradical
97\mutable\lettonothing\currentmathradicaldegree
98
99\setmathignore\Umathradicaldegreebefore\plusone
100
101\installcorenamespace{mathwhateverstrut}
102
103\defcsname\??mathwhateverstrut\v!height\endcsname{\mathheightstrut}
104\defcsname\??mathwhateverstrut\v!depth \endcsname{\mathdepthstrut}
105\defcsname\??mathwhateverstrut\v!math  \endcsname{\mathstrut}
106\defcsname\??mathwhateverstrut\v!yes   \endcsname{\strut}
107%letcsname\??mathwhateverstrut\v!no    \endcsname\relax
108
109\tolerant\protected\def\math_radical_handle#tag#*[#S#settings]#*[#degree]#:#body%
110  {\begingroup
111   \cdef\currentmathradical{#tag}%
112   \ifhastok={#settings}%
113     \lettonothing\currentmathradicaldegree
114     \setupcurrentmathradical[#settings]%
115     \ifparameter#degree\or
116        \edef\currentmathradicaldegree{#degree}%
117     \else
118        \edef\currentmathradicaldegree{\mathradicalparameter\c!n}%
119     \fi
120   \else
121     \edef\currentmathradicaldegree{#settings}%
122   \fi
123   \ifempty\currentmathradicaldegree
124     \let\currentmathradicaldegree\m_math_no_degree
125   \fi
126   \ifcase\mathradicalparameter\c!right\else
127     \let\currentmathradicaldegree\m_math_no_degree
128   \fi
129   \edef\p_mp{\mathradicalparameter\c!mp}%
130   \ifcstok{\mathradicalparameter\c!plugin}\v!mp
131     \ifempty\p_mp\else
132       \clf_set_extensible_data
133          mp    {\p_mp}
134          left  {\mathradicalparameter\c!left}%
135          right {\mathradicalparameter\c!left}%
136       \relax
137     \fi
138     \scratchcounter\zerocount
139   \orelse\ifcstok{\mathradicalparameter\c!rule}\v!symbol
140     \lettonothing\p_mp
141     \scratchcounter\mathradicalparameter\c!top\relax
142   \else
143     \lettonothing\p_mp
144     \scratchcounter\zerocount
145   \fi
146   \ifcstok{\mathradicalparameter\c!mathstyle}\s!identity
147     \frozen\Umathradicalvariant\allmathstyles\mathstylevariantidentity
148    %\frozen\Umathdegreevariant \allmathstyles\mathstylevariantidentity
149     \resetmathradicalparameter\c!mathstyle
150   \fi
151   \Urooted
152     \s!height{\ifcstok{\mathradicalparameter\c!height}\v!none\scaledpoint\else\mathradicalparameter\c!height\fi}
153     \s!depth {\ifcstok{\mathradicalparameter\c!depth }\v!none\scaledpoint\else\mathradicalparameter\c!depth \fi}
154     \s!source{\namedboxanchor{\mathradicalparameter\c!source}}%
155     \s!style \normalmathstyle % not needed
156     \ifzeronum\scratchcounter\else
157       \s!top\relaxedspace
158     \fi
159     \usedsymbolcolorparameterattributes{\mathradicalparameter\c!symbolcolor}%
160     \ifempty\p_mp\else
161       \s!usecallback\relaxedspace
162     \fi
163     \ifcstok{\mathradicalparameter\c!rule}\v!no
164       \s!norule\relaxedspace
165     \orelse\ifcstok{\lastnamedcs}\v!bottom
166       \s!reflected\relaxedspace
167     \fi
168     \zerocount \mathradicalparameter\c!left
169     \zerocount \mathradicalparameter\c!right
170     \ifzeronum\scratchcounter\else
171        \zerocount\scratchcounter
172     \fi
173     \relax
174   {\usemathradicalcolorparameter\c!numbercolor
175    \mathstrut\currentmathradicaldegree}%
176   {\usemathradicalcolorparameter\c!textcolor
177    % we need to also adapt the strut
178    \usemathstyleparameter\mathradicalparameter\c!mathstyle
179    \begincsname\??mathwhateverstrut\mathradicalparameter\c!strut\endcsname
180    \scratchdimen{\mathradicalparameter\c!leftmargin}%
181    \ifzeropt\scratchdimen\else
182      \kern\scratchdimen
183    \fi
184    \scratchdepth{\mathradicalparameter\c!mindepth}
185    \ifzerodim\scratchdepth\else
186      \srule
187        \s!depth \scratchdepth
188        \s!height\zeropoint
189        \s!width \zeropoint
190      \relax % in addition to strut
191    \fi
192    #body%
193    \scratchdimen{\mathradicalparameter\c!rightmargin}%
194    \ifzeropt\scratchdimen\else
195      \kern\scratchdimen
196    \fi}%
197   \endgroup}
198
199\def\m_math_no_degree{{}}
200
201% for every font
202%
203% \appendtoks
204%    \Umathradicaldegreebefore\allmathstyles\zeropoint
205% \to \everymathematics
206%
207% We use a strut in the degree because not all fonts have the right gaps set up but
208% as struts are sort of predictable we can now fix all fonts in the lfg file.
209%
210% style width [options: left middle right]
211
212%D \starttyping
213%D \definemathradical[esqrt][sqrt][height=\maxdimen,depth=\maxdimen]
214%D \definemathradical[fsqrt][sqrt][height=3ex,depth=2ex]
215%D \definemathradical[ssqrt][sqrt][height=-.5pt,depth=-.5pt]
216%D
217%D \def\TestSqrt#1%
218%D   {test $      #1{x}           + #1{\sin(x)}                         $ test\par
219%D    test $      #1{x}           + #1{\sin(x)} + #1{\frac{1}{x}}       $ test\par
220%D    test $      #1{x} + #1{x^2}                                       $ test\par
221%D    test $\left(#1{x} + #1{x^2}                                \right)$ test\par}
222%D
223%D \TestSqrt\sqrt \blank % dynamic
224%D \TestSqrt\esqrt\blank % equal
225%D \TestSqrt\fsqrt\blank % fixed
226%D \TestSqrt\ssqrt\blank % squeezed
227%D \stoptyping
228
229% todo: spacing .. this is just an experiment (article driven)
230
231% We used to look back, but a look ahead avoids picking up arguments.
232%
233%    \clf_set_radical_properties
234%        color {\p_color}
235%        mp    {\mathradicalparameter\c!mp}
236%   \relax}
237
238\pushoverloadmode
239
240\definemathradical[root]
241\definemathradical[sqrt][root]
242
243\popoverloadmode
244
245% \setupmathradical[sqrt][alternative=normal,color=darkblue]
246% \setupmathradical[sqrt][alternative=mp,color=darkgreen]
247
248%D Because I wanted to illustrate some more fun stuff another mechanism
249%D is provided as well ... let's put some dangerous tools in the hand of
250%D math jugglers like Aditya.
251
252\installcorenamespace{mathornament}
253\installcorenamespace{mathornamentalternative}
254
255\installcommandhandler \??mathornament {mathornament} \??mathornament
256
257\setupmathornament
258  [\c!alternative=\v!mp, % currently mp only .. maybe some day layer too
259   \c!mpoffset=.25\exheight]
260
261\appendtoks
262    \frozen\protected\instance\edefcsname\currentmathornament\endcsname
263      {\math_ornament_handle{\currentmathornament}}%
264\to \everydefinemathornament
265
266\protected\def\math_ornament_handle#tag#body%
267  {\begingroup
268   \cdef\currentmathornament{#tag}%
269   \csname\??mathornamentalternative\mathornamentparameter\c!alternative\endcsname{#body}%
270   \endgroup}
271
272\defcsname\??mathornamentalternative\v!mp\endcsname#body% we could use dowithnextbox
273  {\begingroup
274   \scratchoffset{\mathornamentparameter\c!mpoffset}%
275   \setbox\nextbox\mathstylehbox{#body}%
276   \d_overlay_width    \wd\nextbox
277   \d_overlay_height   \ht\nextbox
278   \d_overlay_depth    \dp\nextbox
279   \d_overlay_offset   \scratchoffset
280   \d_overlay_linewidth\linewidth
281   \edef\overlaylinecolor{\mathornamentparameter\c!color}%
282   \edef\p_mp{\mathornamentparameter\c!mp}%
283   % the width of the graphic determines the width of the final result
284   \setbox\scratchbox\hpack{\uniqueMPgraphic{\p_mp}}% todo: add code key + tag
285   \hpack to \wd\scratchbox{\hss\box\nextbox\hss}%
286   \kern-\wd\scratchbox
287   \box\scratchbox
288   \endgroup}
289
290% \startMPextensions
291%     vardef math_ornament_hat(expr w,h,d,o,l) =
292%         image ( path p ; p :=
293%             (w/2,h + 10l) --
294%             (o + w,h + o) --
295%             (w/2,h + 7l) --
296%             (-o,h + o) --
297%             cycle ;
298%             fill p ;
299%             setbounds currentpicture to (-o,0) -- (w+o,0) -- (w+o,h+2o) -- (-o,h+2o) -- cycle ;
300%         )
301%     enddef ;
302% \stopMPextensions
303%
304% \startuniqueMPgraphic{math:ornament:hat}
305%     draw
306%         math_ornament_hat(
307%             OverlayWidth,
308%             OverlayHeight,
309%             OverlayDepth,
310%             OverlayOffset,
311%             OverlayLineWidth
312%         )
313%     withpen
314%         pencircle
315%             xscaled (2OverlayLineWidth)
316%             yscaled (3OverlayLineWidth/4)
317%             rotated 30
318%     withcolor
319%         OverlayLineColor ;
320%         draw boundingbox currentpicture;
321% \stopuniqueMPgraphic
322%
323% \definemathornament [mathhat] [mp=math:ornament:hat]
324%
325% \dorecurse{8}{$\mathhat{\blackrule[width=#1ex,color=gray]}$ }
326
327% \annuity {(x+1)} \tocharacter"20E7
328
329\integerdef\radicalbarextenderuc\privatecharactercode{radical bar extender}
330
331\integerdef\delimitedleftannuitylonguc  \privatecharactercode{delimited left annuity long}
332\integerdef\delimitedleftannuityshortuc \privatecharactercode{delimited left annuity short}
333\integerdef\delimitedrightannuitylonguc \privatecharactercode{delimited right annuity long}
334\integerdef\delimitedrightannuityshortuc\privatecharactercode{delimited right annuity short}
335
336\integerdef\delimitedbottomleftannuitylonguc  \privatecharactercode{delimited bottom left annuity long}
337\integerdef\delimitedbottomleftannuityshortuc \privatecharactercode{delimited bottom left annuity short}
338\integerdef\delimitedbottomrightannuitylonguc \privatecharactercode{delimited bottom right annuity long}
339\integerdef\delimitedbottomrightannuityshortuc\privatecharactercode{delimited bottom right annuity short}
340
341%D We now default to nice bars:
342
343\setupmathradical
344  [\c!rule=\v!symbol,
345   \c!top=\radicalbarextenderuc]
346
347\definemathradical
348  [rannuity]
349  [\c!rule=\v!yes,
350   \c!left=\zerocount,
351   \c!right=\delimitedrightannuitylonguc,
352   \c!rightmargin=.05\emwidth]
353
354\definemathradical
355  [lannuity]
356  [\c!rule=\v!yes,
357   \c!left=\delimitedleftannuitylonguc,
358   \c!right=\zerocount,
359   \c!leftmargin=.05\emwidth]
360
361\definemathradical
362  [lrannuity]
363  [\c!rule=\v!yes,
364   \c!left=\delimitedleftannuityshortuc,
365   \c!right=\delimitedrightannuitylonguc,
366   \c!leftmargin=.05\emwidth,
367   \c!rightmargin=.05\emwidth]
368
369\definemathradical
370  [rlannuity]
371  [\c!rule=\v!yes,
372   \c!left=\delimitedleftannuitylonguc,
373   \c!right=\delimitedrightannuityshortuc,
374   \c!leftmargin=.05\emwidth,
375   \c!rightmargin=.05\emwidth]
376
377\definemathradical
378  [annuity]
379  [rannuity]
380
381\definemathradical
382  [lbannuity]
383  [lannuity]
384  [\c!rule=\v!bottom,
385   \c!left=\delimitedbottomleftannuitylonguc]
386
387\definemathradical
388  [rbannuity]
389  [rannuity]
390  [\c!rule=\v!bottom,
391   \c!right=\delimitedbottomrightannuitylonguc]
392
393\definemathradical
394  [rlbannuity]
395  [rlannuity]
396  [\c!rule=\v!bottom,
397   \c!left=\delimitedbottomleftannuityshortuc,
398   \c!right=\delimitedbottomrightannuitylonguc]
399
400\definemathradical
401  [lrbannuity]
402  [lrannuity]
403  [\c!rule=\v!bottom,
404   \c!left=\delimitedbottomleftannuitylonguc,
405   \c!right=\delimitedbottomrightannuityshortuc]
406
407\protect \endinput
408