strc-mat.mkxl /size: 66 Kb    last modification: 2024-01-16 09:03
1%D \module
2%D   [       file=strc-mat,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Math Numbering,
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 Structure Macros / Math Numbering}
15
16\registerctxluafile{strc-mat}{autosuffix}
17
18% -- we have potential for captions
19% -- this module will use the commandhandler
20% -- key/value pairs will be added (I have no time now)
21
22\unprotect
23
24\setupformulas
25  [%\c!way=,
26   %\c!blockway=,
27   %\c!sectionnumber=,
28   %\c!conversion=\v!numbers,
29   %\c!numberstyle=,
30   %\c!numbercolor=,
31   %\c!numbercommand=,
32   %\c!align=,
33   %\c!separator=,
34 % \c!splitmethod=\v!both, % first|last|both|<empty>
35   \c!snap=\v!no,
36   \c!snapstep=\v!medium,
37   \c!grid=\v!math,
38   \c!location=\v!right,
39   \c!left=(,
40   \c!right=),
41   \c!expansion=\v!yes, % maybe automatically
42   \c!spacebefore=\v!big,
43   \c!spaceafter=\formulaparameter\c!spacebefore,
44   \c!spaceinbetween=\v!quarterline,
45   \c!width=\hsize,
46   \c!margin=\zeropoint,
47   \c!leftmargin=\formulaparameter\c!margin,
48   \c!rightmargin=\formulaparameter\c!margin,
49   \c!indentnext=\v!no,
50   \c!alternative=\s!default,
51   \c!strut=\v!yes, % per 2022-04, was \v!no
52   \c!numberstrut=\v!yes, % \v!no \v!yes \v!always
53   \c!margindistance=\zeropoint,
54   \c!leftmargindistance=\formulaparameter\c!margindistance,
55   \c!rightmargindistance=\formulaparameter\c!margindistance,
56   \c!numberthreshold=\emwidth,
57   \c!numberdistance=2\emwidth]
58
59\setupformulaframed
60  [%c!location=<auto set>,
61   %c!width=<auto set>,
62   %c!align=<auto set>,
63   \c!offset=.5\exheight]
64
65\matheqnogapstep\zerocount % we no longer need this as we don't use displaymode
66
67% \mathdisplayskipmode\plusthree
68%
69% \hbox\bgroup
70%     \setbox0\vbox\bgroup
71%         xxxxxxxxx\par
72%         \vskip-\baselineskip
73%         $$a^2_2$$\par
74%         xxxxxxxxx\par
75%     \egroup
76%     \box0
77%     \vbox\bgroup
78%         xxxxxxxxx\par
79%         \vskip-\baselineskip
80%         $$a^2$$\par
81%         xxxxxxxxx\par
82%     \egroup
83%     \vbox\bgroup
84%         xxxxxxxxx
85% \vskip-\baselineskip
86%         $$a_2$$
87%         xxxxxxxxx
88%     \egroup
89% \egroup
90%
91% \hbox\bgroup
92%     \setbox0\vbox\bgroup
93%         xxxxxxxxx\par
94%         \ctxlua{tex.prevdepth=-1000 *65536}
95%         $$a^2_2$$\par
96%         xxxxxxxxx\par
97%     \egroup
98%     \box0
99%     \vbox\bgroup
100%         xxxxxxxxx\par
101%         \ctxlua{tex.prevdepth=-1000 *65536}
102%         $$a^2$$\par
103%         xxxxxxxxx\par
104%     \egroup
105%     \vbox\bgroup
106%         xxxxxxxxx
107%         \ctxlua{tex.prevdepth=-1000 *65536}
108%         $$a_2$$
109%         xxxxxxxxx
110%     \egroup
111% \egroup
112
113\setupsubformulas % subformulas could be last in chain
114  [\c!indentnext=\formulaparameter\c!indentnext]
115
116\definecounter % one ?
117  [\v!formula]
118
119\defineconversionset
120  [\v!formula]
121  [numbers,characters] % no \v! ?
122
123\installcounterassociation{formula} \registerformulacounter\v!formula % currently we only have one
124
125\appendtoks
126    \synchronizeformulacounters
127\to \everysetupformula
128
129% \appendtoks
130%     \synchronizeformulacounters
131% \to \everydefineformula
132
133\setupformulas
134  [\c!numberconversionset=\v!formula] % why forgotten
135
136\appendtoks
137    \normalexpanded{\definelist[\currentformula]}% is expansion needed?
138    \frozen\instance\protected\edefcsname\e!start\currentformula\v!formula\endcsname{\strc_formulas_start_formula{\currentformula}}%
139    \frozen\instance\protected\edefcsname\e!stop \currentformula\v!formula\endcsname{\strc_formulas_stop_formula}%
140\to \everydefineformula
141
142\definelist[\v!formula]
143
144\permanent\protected\defcsname\e!start\v!formula\endcsname{\strc_formulas_start_formula{}}
145\permanent\protected\defcsname\e!stop \v!formula\endcsname{\strc_formulas_stop_formula}
146
147\permanent\protected\def\startnamedformula[#1]%
148  {\strc_formulas_start_formula{#1}}
149
150\permanent\protected\def\stopnamedformula
151  {\strc_formulas_stop_formula}
152
153\let\strc_formulas_start_formula\relax % defined later
154\let\strc_formulas_stop_formula \relax % defined later
155
156\permanent\tolerant\protected\def\defineformulaalternative[#1]#*[#2]#*[#3]%
157  {\frozen\instance\protected\defcsname\e!start#1\v!formula\endcsname{#2}%
158   \frozen\instance\protected\defcsname\e!stop #1\v!formula\endcsname{#3}}
159
160% sp = single line paragraph sd = single line display
161% mp = multi  line paragraph md = multi  line display
162
163\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath]
164\defineformulaalternative[\s!single] [\startdisplaymath][\stopdisplaymath]
165\defineformulaalternative[\s!multi]  [\startdisplaymath][\stopdisplaymath]
166
167\defineformula
168  [sp]
169  [\c!spacebefore=\v!none,
170   \c!spaceafter=\v!none,
171   \c!indentnext=\v!no,
172   \c!alternative=\s!single]
173
174\defineformula
175  [sd]
176  [\c!spacebefore=\v!none,
177   \c!spaceafter=\v!none,
178   \c!indentnext=\v!yes,
179   \c!alternative=\s!single]
180
181\defineformula
182  [mp]
183  [\c!indentnext=\v!no,
184   \c!alternative=\s!multi]
185
186\defineformula
187  [md]
188  [\c!indentnext=\v!yes,
189   \c!alternative=\s!multi]
190
191\newtoks\everyresetformulas
192
193\appendtoks
194    \lettonothing\currentformula % to be checked:
195\to \everyresetformulas
196
197% implementation
198
199\protected\def\strc_formulas_store_number#1#2#3#4#5#6% ref, todo:str, \sync % todo: title etc (like float)
200  {\c_strc_formulas_handle_number\conditionaltrue
201   \strc_counters_register_component
202     {formula}%
203     \setupcurrentformula \formulaparameter \detokenizedformulaparameter
204     \relax \relax \relax
205     [\c!name=\v!formula,\s!counter=\v!formula,%
206      \s!hascaption=\v!yes,%
207      \s!hastitle=\v!yes,% maybe also a check
208      \s!hasnumber=\ifempty\namedformulaentry\v!yes\else\v!no\fi,%
209      \s!haslevel=#6,%
210      \c!reference=#1,%
211      \c!title=\namedformulaentry,
212      \c!list=\currentplaceformulalist,
213      \c!bookmark=\currentplaceformulabookmark]%
214     [#2]%
215   \glettonothing\namedformulaentry % \relax
216   \glet#3\m_strc_counters_last_registered_index
217   \glet#4\m_strc_counters_last_registered_synchronize
218   \glet#5\m_strc_counters_last_registered_attribute}
219
220% modes: 0=unset, 1=forced, 2=none, 3=reference
221
222\newconstant\c_strc_formulas_place_number_mode
223\newconstant\c_strc_formulas_number_mode
224\newconstant\c_strc_formulas_sub_number_mode
225\newconstant\c_strc_formulas_nested_number_mode
226\newconstant\c_strc_formulas_counter_level
227
228\let\strc_formulas_show_modes     \relax
229\let\strc_formulas_show_references\relax
230
231\installtextracker
232  {math.numbering}
233  {\let\strc_formulas_show_modes     \strc_formulas_show_modes_indeed
234   \let\strc_formulas_show_references\strc_formulas_show_references_indeed}
235  {\let\strc_formulas_show_modes     \relax
236   \let\strc_formulas_show_references\relax}
237
238\def\strc_formulas_mode_row#1#2#3#4%
239  {\NC #1%
240   \NC \ifcase#2\relax unset\or forced\or none\or reference\fi
241   \NC #3%
242   \NC #4%
243   \NC \NR}
244
245\protected\def\strc_formulas_show_modes_indeed
246  {\rlap{\enspace\vcenter to \zeropoint{\vss\ruledvcenter{%
247     \forgetall\smallinfofont\setupinterlinespace
248     \starttabulate[|l|l|l|l|]
249       \strc_formulas_mode_row{place}  \c_strc_formulas_place_number_mode  \currentplaceformulareference  \currentplaceformulasuffix
250       \strc_formulas_mode_row{main}   \c_strc_formulas_number_mode        \currentformulareference       \currentformulasuffix
251       \strc_formulas_mode_row{sub}    \c_strc_formulas_sub_number_mode    \currentsubformulareference    \currentsubformulasuffix
252       \strc_formulas_mode_row{nested} \c_strc_formulas_nested_number_mode \currentnestedformulareference \currentnestedformulasuffix
253     \stoptabulate
254     \vss}}}}
255
256\protected\def\strc_formulas_show_references_indeed
257  {\llap{\vcenter to \zeropoint{\vss\ruledvcenter{%
258     \forgetall\smallinfofont\setupinterlinespace
259     \starttabulate[|l|l|l|l|]
260       \NC place\NC
261         \ifnum\c_strc_formulas_place_number_mode=\plusthree
262           \ifconditional\c_strc_formulas_referenced
263             \textminus
264           \else
265             \textplus
266           \fi
267         \else
268           \textminus
269         \fi
270       \NC \NR
271       \NC formulas\NC
272         \ifnum\c_strc_formulas_number_mode=\plusthree
273           \textplus
274         \else
275           \textminus
276         \fi
277       \NC \NR
278       \NC nested\NC
279         \ifnum\c_strc_formulas_nested_number_mode=\plusthree
280           \textplus
281         \else
282           \textminus
283         \fi
284       \NC \NR
285     \stoptabulate
286     \vss}}}\enspace}
287
288\appendtoks
289    \c_strc_formulas_place_number_mode \zerocount
290    \c_strc_formulas_number_mode       \zerocount
291    \c_strc_formulas_sub_number_mode   \zerocount
292    \c_strc_formulas_nested_number_mode\zerocount
293\to \everyresetformulas
294
295\newconditional\c_strc_formulas_handle_number
296\newconditional\c_strc_formulas_inside_place
297\newconditional\c_strc_formulas_inside_place_sub
298\newconditional\c_strc_formulas_inside_formulas
299\newconditional\c_strc_formulas_inside_formulas_sub
300\newconditional\c_strc_formulas_incremented
301\newconditional\c_strc_formulas_referenced
302
303\appendtoks
304    \global\c_strc_formulas_inside_place\conditionalfalse
305    \global\c_strc_formulas_inside_place_sub\conditionalfalse
306\to \everyresetformulas
307
308\def\strc_formulas_place_number_noneed
309  {\ifcstok{\formulaparameter\c!numberstrut}\v!always
310     \strut
311   \fi}
312
313\def\strc_formulas_place_numbering % place formula
314  {\c_strc_formulas_handle_number\conditionaltrue
315   \strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference
316   \ifnum\c_strc_formulas_place_number_mode=\plustwo
317     \glet\strc_formulas_place_number\strc_formulas_place_number_noneed
318   \else
319     \glet\strc_formulas_place_number\strc_formulas_place_number_indeed
320   \fi
321   \glet\strc_formulas_place_number_nested\strc_formulas_place_number_nested_indeed}
322
323\def\strc_formulas_handle_number % formulas
324  {\strc_formulas_check_reference\c_strc_formulas_number_mode\currentformulasreference}
325
326\def\strc_formulas_handle_sub_number_indeed % sub formulas
327  {\strc_formulas_check_reference\c_strc_formulas_sub_number_mode\currentsubformulasreference
328   \strc_counters_increment\v!formula
329   \strc_formulas_store_number
330     \currentsubformulasreference
331     \empty
332     \currentsubformulasnumber
333     \currentsubformulassynchronize
334     \currentsubformulasattribute
335     \plustwo}
336
337\def\strc_formulas_handle_sub_number % sub formulas
338  {\iftrialtypesetting
339     \strc_counters_save\v!formula
340     \strc_formulas_handle_sub_number_indeed
341     \strc_counters_restore\v!formula
342   \else
343     \strc_formulas_handle_sub_number_indeed
344   \fi}
345
346\let\strc_formulas_reference_trace\relax
347\let\strc_formulas_reference_show \relax
348
349\permanent\protected\def\placecurrentformulanumber
350  {\begingroup
351   \rm % determines the distance and main font
352   \edef\p_location{\formulaparameter\c!location}%
353   \ifx\p_location\v!atrightmargin
354     \ifzeropt\s_strc_formulas_margin_right
355       \let\p_location\v!right
356     \fi
357   \orelse\ifx\p_location\v!atleftmargin
358     \ifzeropt\s_strc_formulas_margin_left
359       \let\p_location\v!left
360     \fi
361   \fi
362   \strc_formulas_show_references
363   \ifx\p_location\v!right
364      \strc_formulas_add_distance\plusone\v!left\formulaparameter
365   \fi
366   \begingroup
367   \useformulastyleandcolor\c!numberstyle\c!numbercolor
368   \formulaparameter\c!numbercommand
369     {\edef\p_strut{\formulaparameter\c!numberstrut}%
370      \ifx\p_strut\v!always
371         \strut
372      \orelse\ifx\p_strut\v!yes
373         \strut
374      \fi
375      \formulaparameter\c!left
376      \namedtaggedlabeltexts
377        \t!formulalabel \v!formula
378        \t!formulanumber\v!formula
379        {\ignorespaces\strc_formulas_place_current_number\removeunwantedspaces}%
380      \formulaparameter\c!right}%
381   \endgroup
382   \ifx\p_location\v!left
383      \strc_formulas_add_distance\plusone\v!right\formulaparameter
384   \fi
385   \strc_formulas_show_modes
386   \endgroup}
387
388\protected\def\strc_formulas_place_current_number
389  {\ifempty\namedformulaentry
390     \begingroup
391     \strc_formulas_handle_current_references
392     \labeltexts\currentformula{\convertedcounter[\v!formula][]}%
393     \endgroup
394   \else
395     \expandafter % hm, the next one reset \namedformulaentry
396     \strc_formulas_handle_current_references
397     \namedformulaentry
398   \fi}
399
400\permanent\def\theformuladestinationattribute#1%
401  {\iflocation\ifx#1\relax\orelse\ifempty#1\else
402     \c_attr_destination#1%
403     \glet#1\relax
404   \fi\fi}
405
406\mutable\let\currentplaceformulaattribute\relax
407\mutable\let\currentformulaattribute     \relax
408\mutable\let\currentsubformulaattribute  \relax
409\mutable\let\currentformulasattribute    \relax
410
411\mutable\let\currentplaceformulanumber\relax
412\mutable\let\currentformulanumber     \relax
413\mutable\let\currentsubformulanumber  \relax
414\mutable\let\currentformulasnumber    \relax
415
416\mutable\lettonothing\currentformulasreference
417\mutable\lettonothing\currentformulareference
418\mutable\lettonothing\currentsubformulareference
419\mutable\lettonothing\currentnestedformulanumber
420\mutable\lettonothing\currentnestedformulareference
421\mutable\lettonothing\currentnestedformulaattribute
422
423\appendtoks
424    \glettonothing\currentformulasreference
425    \glettonothing\currentformulareference
426    \glettonothing\currentsubformulareference
427    \glettonothing\currentnestedformulareference
428\to \everyresetformulas
429
430\mutable\lettonothing\currentformulassuffix
431\mutable\lettonothing\currentformulasuffix
432\mutable\lettonothing\currentsubformulasuffix
433\mutable\lettonothing\currentnestedformulasuffix
434
435\appendtoks
436    \glettonothing\currentformulassuffix
437    \glettonothing\currentformulasuffix
438    \glettonothing\currentsubformulasuffix
439    \glettonothing\currentnestedformulasuffix
440\to \everyresetformulas
441
442\mutable\let\currentplaceformulasynchronize \relax
443\mutable\let\currentformulassynchronize     \relax
444\mutable\let\currentsubformulasynchronize   \relax
445\mutable\let\currentnestedformulasynchronize\relax
446
447\appendtoks
448    \glet\currentplaceformulasynchronize \relax
449    \glet\currentformulassynchronize     \relax
450    \glet\currentsubformulassynchronize  \relax
451    \glet\currentnestedformulasynchronize\relax
452\to \everyresetformulas
453
454\mutable\lettonothing\currentsubformulasattribute
455\mutable\lettonothing\currentsubformulasnumber
456\mutable\lettonothing\currentsubformulasreference
457\mutable\lettonothing\currentsubformulassynchronize
458
459\c_strc_formulas_counter_level\plusone
460
461\def\strc_formulas_handle_current_references
462  {\strc_formulas_reference_show
463   \ifnum\c_strc_formulas_place_number_mode=\plusthree
464     \ifconditional\c_strc_formulas_referenced
465     \else
466       \strc_formulas_store_number
467         \currentplaceformulareference
468         \empty
469         \currentplaceformulanumber
470         \currentplaceformulasynchronize
471         \currentplaceformulaattribute
472         \c_strc_formulas_counter_level
473       \currentplaceformulasynchronize
474       \glet\currentplaceformulasynchronize\relax
475       \theformuladestinationattribute\currentplaceformulaattribute
476       \global\c_strc_formulas_referenced\conditionaltrue
477     \fi
478   \fi
479   \ifnum\c_strc_formulas_number_mode=\plusthree
480     \strc_formulas_store_number
481       \currentformulasreference
482       \empty
483       \currentformulasnumber
484       \currentformulassynchronize
485       \currentformulasattribute
486       \plustwo
487     \currentformulassynchronize
488     \glet\currentformulassynchronize\relax
489     \theformuladestinationattribute\currentformulasattribute
490   \fi
491   \ifnum\c_strc_formulas_sub_number_mode=\plusthree
492     \currentsubformulassynchronize
493     \glet\currentsubformulassynchronize\relax
494   \fi
495   \ifnum\c_strc_formulas_nested_number_mode=\plusthree
496     \strc_formulas_store_number
497       \currentnestedformulareference
498       \empty
499       \currentnestedformulanumber
500       \currentnestedformulasynchronize
501       \currentnestedformulaattribute
502       \plustwo
503     \currentnestedformulasynchronize
504     \glet\currentnestedformulasynchronize\relax
505     \theformuladestinationattribute\currentnestedformulaattribute
506   \fi}
507
508\def\strc_formulas_handle_numbering_indeed
509  {\ifempty\namedformulaentry
510     \iftext\currentnestedformulasuffix
511       \ifconditional\c_strc_formulas_incremented\else
512         \strc_counters_increment\v!formula
513       \fi
514       \global\c_strc_formulas_incremented\conditionaltrue
515       \ifcstok{+}\currentnestedformulasuffix
516         \strc_counters_increment_sub\v!formula\plustwo
517       \else
518         \strc_counters_setown_sub\v!formula\plustwo\currentnestedformulasuffix
519       \fi
520     \else
521       \ifempty\currentplaceformulasuffix\else
522         \let\currentnestedformulasuffix   \currentplaceformulasuffix
523         \let\currentnestedformulareference\currentplaceformulareference
524         \strc_formulas_place_number_nested_check
525       \fi
526       \strc_counters_increment\v!formula
527     \fi
528   \fi
529   \glettonothing\currentplaceformulasuffix
530   \glettonothing\currentnestedformulasuffix
531   \placecurrentformulanumber}
532
533\def\strc_formulas_handle_numbering
534  {\iftrialtypesetting
535     \strc_counters_save\v!formula
536     \strc_formulas_handle_numbering_indeed
537     \strc_counters_restore\v!formula
538   \else
539     \strc_formulas_handle_numbering_indeed
540   \fi}
541
542\def\strc_formulas_handle_sub_numbering_indeed
543  {\let\strc_formulas_handle_sub_numbering\relax % else error: see math/numbering-001.tex
544   \iftext\currentnestedformulasuffix
545     \strc_counters_setown_sub\v!formula\plustwo\currentnestedformulasuffix
546   \else
547     \strc_counters_increment_sub\v!formula\plustwo
548   \fi
549   \glettonothing\currentplaceformulasuffix
550   \glettonothing\currentnestedformulasuffix
551   \placecurrentformulanumber}
552
553\def\strc_formulas_handle_sub_numbering
554  {\iftrialtypesetting
555     \strc_counters_save\v!formula
556     \strc_formulas_handle_sub_numbering_indeed
557     \strc_counters_restore\v!formula
558   \else
559     \strc_formulas_handle_sub_numbering_indeed
560   \fi}
561
562\def\strc_formulas_number_indeed
563  {\ifconditional\c_strc_formulas_handle_number
564     \hbox\bgroup
565       % main counter
566       \ifconditional\c_strc_formulas_inside_formulas_sub
567         % nothing
568       \else
569         \ifcase\c_strc_formulas_number_mode
570           \ifcase\c_strc_formulas_place_number_mode
571             \strc_formulas_handle_numbering
572           \or
573             \strc_formulas_handle_numbering
574           \or
575             % nothing
576           \or
577             \strc_formulas_handle_numbering
578           \fi
579         \or
580           \strc_formulas_handle_numbering
581         \or
582           % nothing
583         \or
584           \strc_formulas_handle_numbering
585         \fi
586       \fi
587       % subcounter
588       \ifconditional\c_strc_formulas_inside_formulas_sub
589         \ifcase\c_strc_formulas_sub_number_mode
590           \strc_formulas_handle_sub_numbering % was nothing
591         \or
592           \strc_formulas_handle_sub_numbering
593         \or
594           % nothing
595         \or
596           \strc_formulas_handle_sub_numbering
597         \fi
598       \fi
599       \strc_formulas_reference_trace
600     \egroup
601   \fi}
602
603\installstructurelistprocessor\v!formula % to be checked ...
604  {\let\currentlistentrynumber    \structurelistgenericnumber
605   \let\currentlistentrytitle     \structurelistgenerictitle
606   \let\currentlistentrypagenumber\structurelistpagenumber
607   \strc_lists_apply_renderingsetup}
608
609\newif\ifinformula
610
611%D We need a hook into the plain math alignment macros
612%D
613%D \starttyping
614%D \displaylines
615%D \stoptyping
616%D
617%D Otherwise we get a missing \type {$$} error reported.
618
619\pushoverloadmode
620
621    \permanent\protected\def\normaleqno#1{\writestatus\m!system{no native (l/r)eqno equation number support}}
622
623    \aliased\let\normalleqno\normaleqno
624    \aliased\let\normalreqno\normaleqno
625    \aliased\let\normaleqno \normaleqno
626
627    \aliased\let\leqno      \normaleqno
628    \aliased\let\reqno      \normaleqno
629    \aliased\let\eqno       \normaleqno
630
631\popoverloadmode
632
633%D \macros
634%D   {startsubformulas}
635
636% \placeformula
637% \startsubformulas[Maxwell]
638%     \startformulas
639%      \startformula \startalign
640%        \NC \nabla\cdot\bf E  \NC = \frac{\rho}{\varepsilon_0} \NR[Maxwell 1]
641%        \NC \nabla\times\bf E \NC = - \frac{\partial\bf B}{\partial t} \NR[Maxwell II]
642%        \stopalign \stopformula
643%        \startformula \startalign
644%          \NC \nabla\cdot \bf B \NC = 0 \NR[Maxwell III]
645%          \NC \nabla\times\bf B \NC = \mu_0{\bf j}+\varepsilon_0\mu_0\frac{\partial\bf E}{\partial t} \NR[Maxwell IV]
646%        \stopalign \stopformula
647%    \stopformulas
648% \stopsubformulas
649%
650% Maxwell : \in [Maxwell] and II : \in [Maxwell II]
651
652%D Tricky stuff:
653
654\abovedisplayskip      \zeroskip
655\abovedisplayshortskip \zeroskip % evt. 0pt minus 3pt
656\belowdisplayskip      \zeroskip
657\belowdisplayshortskip \zeroskip % evt. 0pt minus 3pt
658
659\predisplaypenalty     \zerocount
660\postdisplaypenalty    \zerocount % -5000 goes wrong, see penalty at \section
661\mathdisplayskipmode   \plusthree %  because align also adds
662
663% \predisplaygapfactor \zerocount % default is 2000
664
665%D We no longer need to do this every time as we don't use display mode
666%D at all, so:
667
668% \protected\def\strc_formulas_forget_display_skips
669%   {\mathdisplayskipmode  \plusthree
670%    \abovedisplayskip     \zeroskip
671%    \belowdisplayskip     \zeroskip
672%    \abovedisplayshortskip\zeroskip
673%    \belowdisplayshortskip\zeroskip}
674
675%D Became this, where setting the mode is now also irrelevant but the engine still
676%D has it, so:
677
678\mathdisplayskipmode  \plusthree
679\abovedisplayskip     \zeroskip
680\belowdisplayskip     \zeroskip
681\abovedisplayshortskip\zeroskip
682\belowdisplayshortskip\zeroskip
683
684\newdimension\d_strc_formulas_display_width
685
686%D In \LMTX\ we have three ways of rendering formulas:
687%D
688%D \startitemize
689%D \startitem line: a single boxed   line  \stopitem
690%D \startitem text: multiple boxed   lines \stopitem
691%D \startitem page: multiple unboxed lines \stopitem
692%D \stopitemize
693%D
694%D So, yes has become text
695
696\newconstant\c_strc_math_split_mode
697
698\mutable\lettonothing\m_strc_math_split
699
700\aliased\let\c_strc_math_line_mode\zerocount
701\aliased\let\c_strc_math_flow_mode\plusone
702\aliased\let\c_strc_math_wrap_mode\plusthree
703
704\newconditional\c_strc_formulas_tight
705\newconditional\c_strc_formulas_packed
706\newconditional\c_strc_formulas_depth
707\newbox        \b_strc_formulas_number
708\newdimen      \d_strc_formulas_number
709
710\def\strc_formulas_display_space_before_normal
711  {% not ok, try \stopformula\par\startformula vs \stopformula\startformula
712   \lettonothing\m_spacebefore
713   \ifvmode
714     \ifdim\lastskip>\zeropoint\else
715       \ifdim\prevdepth<\zeropoint\else
716         \ifdim\prevdepth<\strutdp
717           % maybe add a tracing option here
718           \ifgridsnapping
719             \let\m_spacebefore\v!depth
720           \else
721             \edef\m_spacebefore{\the\dimexpr\strutdp-\prevdepth\relax}%
722           \fi
723         \fi
724       \fi
725     \fi
726     \nointerlineskip
727   \fi
728   \whitespace % added, test with spacebefore=small
729   \ifempty\m_spacebefore
730     \ifx\p_spacebefore\v!none
731       % nothing
732     \orelse\ifempty\p_spacebefore
733       \directvspacing\currentvspacing
734     \else
735       \directvspacing\p_spacebefore
736     \fi
737   \else
738     \ifx\p_spacebefore\v!none
739       \directvspacing{\m_spacebefore}%
740     \orelse\ifempty\p_spacebefore
741       \directvspacing{\m_spacebefore,\currentvspacing}%
742     \else
743       \directvspacing{\m_spacebefore,\p_spacebefore}%
744     \fi
745   \fi}
746
747\def\strc_formulas_display_space_after_common
748  {\whitespace % needs testing
749   \ifx\p_spaceafter\v!none
750     % nothing
751   \orelse\ifempty\p_spaceafter
752     \directvspacing\currentvspacing
753   \else
754     \directvspacing\p_spaceafter
755   \fi}
756
757\def\strc_formulas_display_space_after_normal
758  {\prevdepth\strutdp % \directvspacing\v!depth
759   \strc_formulas_display_space_after_common}
760
761\def\strc_formulas_display_space_before_depth
762  {% not ok, try \stopformula\par\startformula vs \stopformula\startformula
763   \ifvmode
764     \ifinner
765       \strc_formulas_display_space_before_normal
766       \c_strc_formulas_depth\conditionalfalse
767     \else
768       \forcestrutdepth
769       \nointerlineskip
770       \ifx\p_spacebefore\v!none
771         % nothing
772       \orelse\ifempty\p_spacebefore
773         \directvspacing\currentvspacing
774       \else
775         \directvspacing\p_spacebefore
776       \fi
777     \fi
778   \else
779     \strc_formulas_display_space_before_normal
780   \fi}
781
782\def\strc_formulas_display_space_after_depth
783  {\ifconditional\c_strc_formulas_depth
784     \forcestrutdepth
785     \strc_formulas_display_space_after_common
786   \else
787     \strc_formulas_display_space_after_depth_normal
788   \fi}
789
790\def\strc_formulas_display_space_before
791  {\ifconditional\c_strc_formulas_depth
792     \strc_formulas_display_space_before_depth
793   \else
794     \strc_formulas_display_space_before_normal
795   \fi}
796
797\def\strc_formulas_display_space_after
798  {\ifconditional\c_strc_formulas_depth
799     \strc_formulas_display_space_after_depth
800   \else
801     \strc_formulas_display_space_after_normal
802   \fi}
803
804% \newtoks\everybeforedisplay
805% \appendtoks\page_sides_check_floats_indeed\to\everybeforedisplay
806
807\permanent\protected\def\beforedisplayspace
808  {\ifhmode
809     \par
810   \fi
811   \ifvmode
812     \ifconditional\c_strc_formulas_packed
813       \lettonothing\p_spacebefore
814     \else
815       \edef\p_spacebefore{\formulaparameter\c!spacebefore}%
816     \fi
817   % \begincsname\??mathdisplayspacemodel\v!before:\the\c_strc_formulas_space_model\endcsname
818     \strc_formulas_display_space_before
819   \fi
820   \ifhmode
821     \par
822   \fi
823   \page_sides_check_floats_indeed} % probably needs more
824
825\permanent\protected\def\afterdisplayspace
826  {\ifhmode
827     \par
828   \fi
829   \ifvmode
830     \ifconditional\c_strc_formulas_packed
831       \lettonothing\p_spaceafter
832     \else
833       \edef\p_spaceafter{\formulaparameter\c!spaceafter}%
834     \fi
835   % \begincsname\??mathdisplayspacemodel\v!after:\the\c_strc_formulas_space_model\endcsname
836     \strc_formulas_display_space_after
837   \fi
838   \ifhmode
839     \par
840   \fi}
841
842\ifdefined\setdisplaydimensions \else
843    \let\setdisplaydimensions\relax % this one will be defined in math-ali
844\fi
845
846% \newgluespec\formulastrutht
847% \newgluespec\formulastrutdp
848
849%D \startbuffer
850%D \startformula[9pt] x = 1 \stopformula
851%D \startformula[7pt] x = 1 \stopformula
852%D \stopbuffer
853%D
854%D \typebuffer \getbuffer
855
856%D Some tracing of distances and thresholds:
857
858\def\strc_formulas_add_distance_normal#1#2#3% maybe a skip with stretch/shrink
859  {\kern#3\c!numberdistance\relax}
860
861\def\strc_formulas_add_distance_traced#1#2#3%
862  {\begingroup
863   \scratchdimenone  #3\c!numberdistance\relax
864   \scratchdimentwo  \ifconditional\c_strc_formulas_tight\formulaparameter\c!numberthreshold\else\zeropoint\fi\relax
865   \scratchdimenthree.5\exheight
866   \ifcase\scratchdimentwo\else\ifx#2\v!left
867     \darkred
868     \kern-\scratchdimentwo
869     \vrule
870       \s!height\scratchdimenthree
871       \s!depth \scratchdimenthree
872       \s!width \scratchdimentwo
873   \fi\fi
874   \ifcase\scratchdimenone\else
875     \ifcase#1\or\darkgreen\else\darkblue\fi
876     \vrule
877       \s!height\scratchdimenthree
878       \s!depth \scratchdimenthree
879       \s!width \scratchdimenone
880   \fi
881   \ifcase\scratchdimentwo\else\ifx#2\v!right
882     \darkred
883     \vrule
884       \s!height\scratchdimenthree
885       \s!depth \scratchdimenthree
886       \s!width \scratchdimentwo
887     \kern-\scratchdimentwo
888   \fi\fi
889   \endgroup}
890
891\installtextracker
892  {math.numberdistance}
893  {\let\strc_formulas_add_distance\strc_formulas_add_distance_traced}
894  {\let\strc_formulas_add_distance\strc_formulas_add_distance_normal}
895
896\let\strc_formulas_add_distance \strc_formulas_add_distance_normal
897
898\defcsname\??formulaoption\v!packed\endcsname
899  {\c_strc_formulas_packed\conditionaltrue}
900
901\defcsname\??formulaoption\v!tight\endcsname
902  {\c_strc_formulas_tight\conditionaltrue}
903
904\defcsname\??formulaoption\v!middle\endcsname
905  {}
906
907\defcsname\??formulaoption\v!depth\endcsname
908  {\c_strc_formulas_depth\conditionaltrue}
909
910\defcsname\??formulaoption\v!line\endcsname
911  {\ifgridsnapping
912     \setformulaparameter\c!grid{\v!math:\v!line}%
913   \fi}
914
915\defcsname\??formulaoption\v!halfline\endcsname
916  {\ifgridsnapping
917     \setformulaparameter\c!grid{\v!math:\v!halfline}%
918   \fi}
919
920\defcsname\??formulaoption-\v!line\endcsname
921  {\ifgridsnapping
922     \setformulaparameter\c!grid{\v!math:-\v!line}%
923   \fi}
924
925\defcsname\??formulaoption-\v!halfline\endcsname
926  {\ifgridsnapping
927     \setformulaparameter\c!grid{\v!math:-\v!halfline}%
928   \fi}
929
930% when we have 1.0.6 we wil use \mathpenaltiesmode
931%
932% \prebinoppenalty -100
933% \prerelpenalty   -100
934
935% \placeformula[eq:a]
936% \startformula[split=text]
937%     m(b-a)\leq\int_a^b f(x)\dd x\leq M(b-a).
938% \stopformula
939%
940% \placeformula[eq:b]
941% \startformula[split=line]
942%     m(b-a)\leq\int_a^b f(x)\dd x\leq M(b-a).
943% \stopformula
944%
945% \placeformula[eq:c]
946% \startformula[split=line,numberlocation=overlay]
947%     m(b-a)\leq\int_a^b f(x)\dd x\leq M(b-a).
948% \stopformula
949
950\def\strc_math_set_split
951  {\edef\m_strc_math_split{\formulaparameter\c!split}%
952   \ifx\m_strc_math_split\v!line
953     \global\c_strc_math_split_mode\c_strc_math_line_mode
954   \orelse\ifx\m_strc_math_split\v!no
955     \global\c_strc_math_split_mode\c_strc_math_line_mode
956   \orelse\ifx\m_strc_math_split\v!box
957     \global\c_strc_math_split_mode\c_strc_math_wrap_mode
958 % \orelse\ifx\m_strc_math_split\v!page
959 %   \global\c_strc_math_split_mode\c_strc_math_flow_mode
960 % \orelse\ifx\m_strc_math_split\v!text
961 %   \global\c_strc_math_split_mode\c_strc_math_flow_mode
962 % \orelse\ifx\m_strc_math_split\v!yes
963 %   \global\c_strc_math_split_mode\c_strc_math_flow_mode
964 % \orelse\ifx\m_strc_math_split\v!paragraph
965 %   \global\c_strc_math_split_mode\c_strc_math_flow_mode
966   \else
967     \global\c_strc_math_split_mode\c_strc_math_flow_mode
968   \fi
969   \mathpenaltiesmode\plusone
970   \global\d_strc_math_indent\zeropoint}
971
972\def\strc_math_set_number_location
973  {\ifcstok{\formulaparameter\c!numberlocation}\v!overlay
974     \c_strc_formulas_overlay_number\conditionaltrue
975   \else
976     \c_strc_formulas_overlay_number\conditionalfalse
977   \fi
978   \ifcstok{\formulaparameter\c!numbermethod}\v!down
979     \c_math_align_overflow_mode\conditionaltrue
980   \else
981     \c_math_align_overflow_mode\conditionalfalse
982   \fi}
983
984\setupformula
985% [\c!split=\v!no,
986  [\c!split=\v!yes,
987   \c!numberlocation=,
988   \c!textdistance=\zeropoint,
989   \c!interlinespace=1.125\lineheight, % back again, to be tuned
990   \c!textmargin=2\emwidth,
991   \c!numbermethod=\v!down]
992
993% for the moment (when testing) we use a penalty 1
994
995%D Alignment in vertically rendered formulas using \type {\alignhere} and friends
996%D has been an experimental \MKIV\ features for quite a while but probably very few
997%D users were aware of it. It works quite well and little code is needed. With
998%D \LMTX\ defaulting to multiline display math it was time to add a couple of
999%D features and tracing. It can actually often replace math alignments and thereby
1000%D not only save coding but also keep formulas as formulas instead of snippets.
1001%D
1002%D There can of course be more tricks applied but most already were rejected when I
1003%D wrote the original version which is actually not that far from what we do now
1004%D (like deeply burried align points). The main difference between the following
1005%D variant and the \MKIV\ one is that we try to honour the new inter|-|atom spacing
1006%D and adapt to the general alignment settings.
1007
1008\def\strc_math_pickup_again
1009% {\mathatom \s!leftclass \mathendcode \s!rightclass \mathbegincode{}\noatomruling}
1010  {\mathatom \s!class \mathbegincode{}\noatomruling}
1011
1012% maybe: \newboundary \c_strc_math_align_boundary
1013
1014\defineboundary[mathalign] % this one is also used at the lua end
1015
1016\newconditional\c_strc_math_trace_hang
1017\newdimension  \d_strc_math_hang_state
1018
1019\installtextracker
1020  {math.autohang}
1021  {\c_strc_math_trace_hang\conditionaltrue}
1022  {\c_strc_math_trace_hang\conditionalfalse}
1023
1024\newconditional\c_strc_math_aligned_here
1025
1026\def\strc_math_trace_okay#1#2%
1027  {\mathghost{\llap{\backgroundline[#1]{\white\tttf#2}}}}
1028
1029\protected\def\strc_math_align_here
1030  {\ifmmode
1031     \global\c_strc_math_aligned_here\conditionaltrue
1032     % we can have a more dedicated value, and also maybe store the class so that we can
1033     % pick it up at the engine end (second pass)
1034     \ifconditional\c_strc_math_trace_hang
1035       \strc_math_trace_okay{darkred}{A}%
1036     \fi
1037     \boundary\c_bndr_mathalign
1038   \fi}
1039
1040\newboundary\c_bndr_skiphere
1041
1042\tolerant\protected\def\strc_math_skip_here[#1]%
1043  {% no strut as it will influence fences
1044   \ifconditional\c_strc_math_trace_hang
1045     \strc_math_trace_okay{darkblue}{S #1}%
1046   \fi
1047   \scratchdimen\dimexpr\formulaparameter\c!textmargin\relax
1048   \ifchkdimension#1\or
1049     \d_strc_math_hang_state\lastchkdimension
1050   \orelse\ifchknum#1\or
1051     \d_strc_math_hang_state#1\scratchdimen
1052   \orelse\iftok{#1}{+}%
1053     \advanceby\d_strc_math_hang_state\scratchdimen
1054   \orelse\iftok{#1}{-}%
1055     \advanceby\d_strc_math_hang_state-\scratchdimen
1056   \else
1057     \d_strc_math_hang_state\scratchdimen
1058   \fi
1059   \boundary\c_bndr_skiphere
1060   \kern\d_strc_math_hang_state
1061   \strc_math_pickup_again}
1062
1063% \blank[line] \ruledhbox{zzzz} \blank[line]
1064%
1065% xxxx \vadjust
1066%     depth check
1067%     depth after -\thousandpoint
1068%     {\blue xxxx +}
1069% xxxx \vadjust
1070%     pre
1071%     {\red xxxx -}
1072% xxxx
1073%
1074% \blank[line] \ruledhbox{zzzz} \blank[line]
1075
1076\definelocalboxes
1077  [\v!lefttext]
1078  [\c!command=\localmarginlefttext\zeropoint,
1079   \c!repeat=\v!no,
1080   \c!distance=\zeropoint,
1081   \c!location=\v!middle]
1082
1083\definelocalboxes
1084  [\v!righttext]
1085  [\c!command=\localmarginrighttext\zeropoint,
1086   \c!repeat=\v!no,
1087   \c!distance=\zeropoint,
1088   \c!location=\v!middle]
1089
1090\installcorenamespace{mathtexthere}
1091\installcorenamespace{mathbreakhere}
1092
1093\def\strc_math_text_here_right#1% a nasty interplay with the lua end  (!!! TODO)
1094  {\localbox[\v!righttext]{\llap{#1}}} %\kern\rightskip}}}
1095
1096\def\strc_math_text_here_left#1%
1097  {\localbox[\v!lefttext]{\rlap{\kern\leftskip#1}}}
1098
1099\def\strc_math_text_here_before#1%
1100  {\vadjust pre \bgroup
1101     \hbox to \displaywidth \bgroup
1102        \strut
1103        \kern\leftskip
1104         #1\hss
1105        \kern\rightskip
1106        \strut
1107     \egroup
1108   \egroup}
1109
1110\def\strc_math_text_here_after#1%
1111  {\vadjust \bgroup
1112     \hbox to \displaywidth \bgroup
1113        \strut
1114        \kern\leftskip
1115        #1\hss
1116        \kern\rightskip
1117        \strut
1118     \egroup
1119   \egroup}
1120
1121\letcsname\??mathtexthere\v!left  \endcsname\strc_math_text_here_left
1122\letcsname\??mathtexthere\v!right \endcsname\strc_math_text_here_right
1123\letcsname\??mathtexthere\v!before\endcsname\strc_math_text_here_before
1124\letcsname\??mathtexthere\v!after \endcsname\strc_math_text_here_after
1125
1126\defcsname\??mathbreakhere\v!left\endcsname#1%
1127  {\ifnum\lastboundary=\c_math_begin_boundary\else
1128     \strc_math_line_here
1129   \fi
1130   \strc_math_text_here_left{#1}%
1131   \strc_math_pickup_again}
1132
1133\defcsname\??mathbreakhere\v!right\endcsname#1%
1134  {\strc_math_text_here_right{#1}%
1135   \strc_math_line_here
1136   \strc_math_pickup_again}
1137
1138\defcsname\??mathbreakhere\v!before\endcsname#1%
1139  {\ifnum\lastboundary=\c_math_begin_boundary\else
1140     \strc_math_line_here
1141   \fi
1142   \strc_math_text_here_before{#1}%
1143   \strc_math_pickup_again}
1144
1145\defcsname\??mathbreakhere\v!after\endcsname#1%
1146  {\ifnum\lastboundary=\c_math_begin_boundary\else
1147     \strc_math_line_here
1148   \fi
1149   \strc_math_text_here_after{#1}%
1150   \strc_math_pickup_again}
1151
1152\tolerant\protected\def\strc_math_break_here[#1]#:#*#=%
1153  {\ifparameter#2\or
1154     \ifcsname\??mathbreakhere#1\endcsname
1155       \expandafter\lastnamedcs
1156     \else
1157       \csname\??mathbreakhere\v!after\expandafter\endcsname
1158     \fi{#2}%
1159   \orelse\ifcstok{#1}\v!page
1160     \strc_math_page_here
1161   \orelse\ifcstok{#1}\v!samepage
1162     \strc_math_same_here
1163   \else
1164     \strc_math_line_here
1165   \fi}
1166
1167\tolerant\protected\def\strc_math_text_here[#1]#:#*#=%
1168  {\ifparameter#2\or
1169     \ifcsname\??mathtexthere#1\endcsname
1170       \expandafter\lastnamedcs
1171     \else
1172       \csname\??mathtexthere\v!after\expandafter\endcsname
1173     \fi{#2}%
1174   \fi}
1175
1176\def\strc_math_break_here_indeed
1177  {\strut\break}
1178
1179\protected\def\strc_math_page_here
1180  {\ifmmode
1181     \ifconditional\c_strc_math_trace_hang
1182       \strc_math_trace_okay{darkyellow}{B P}%
1183     \fi
1184     \strc_math_break_here_indeed
1185     \vadjust pre {\vfill\penalty-100000}%
1186     \strc_math_pickup_again
1187   \fi}
1188
1189\protected\def\strc_math_same_here
1190  {\ifmmode
1191     \ifconditional\c_strc_math_trace_hang
1192       \strc_math_trace_okay{darkyellow}{B S}%
1193     \fi
1194     \strc_math_break_here_indeed
1195     \vadjust pre {\penalty\plustenthousand}%
1196     \strc_math_pickup_again
1197   \fi}
1198
1199\protected\def\strc_math_line_here
1200  {\ifmmode
1201     \ifconditional\c_strc_math_trace_hang
1202       \strc_math_trace_okay{darkgreen}{B}%
1203     \fi
1204     \strc_math_break_here_indeed
1205     \strc_math_pickup_again
1206   \fi}
1207
1208\ifdefined\alignhere \else \aliased\let\alignhere\relax \fi
1209\ifdefined\texthere  \else \aliased\let\texthere \relax \fi
1210\ifdefined\skiphere  \else \aliased\let\skiphere \relax \fi
1211\ifdefined\breakhere \else \aliased\let\breakhere\relax \fi
1212
1213\appendtoks % must move to alignment
1214    \enforced\let\alignhere\strc_math_align_here
1215    \enforced\let\breakhere\strc_math_break_here
1216    \enforced\let\skiphere \strc_math_skip_here
1217    \enforced\let\texthere \strc_math_text_here
1218  % \global\c_strc_math_aligned_here\conditionalfalse
1219\to \everymathematics
1220
1221\installcorenamespace{mathtextalign}
1222
1223\newconstant   \c_strc_math_ragged_status
1224\newconstant   \c_strc_math_split_status
1225\newconditional\c_strc_math_number_swapped
1226
1227\prependtoks
1228    \c_strc_math_ragged_status\plustwo   % middle
1229    \c_strc_math_split_status \zerocount
1230\to \everymathematics
1231
1232\prependtoks
1233    % we need to keep an eye on this
1234    \mathgluemode\ifcase\raggedstatus\plusthree\else\zerocount\fi
1235\to \everymathematics
1236
1237\defcsname\??mathtextalign\v!flushleft\endcsname
1238  {\raggedright
1239   \mathgluemode\plustwo
1240   \c_strc_math_ragged_status\plusone
1241   \c_strc_math_number_swapped\conditionalfalse
1242   \updateparagraphproperties} % not needed
1243
1244\defcsname\??mathtextalign\v!middle\endcsname
1245  {\raggedcenter
1246   \mathgluemode\plustwo
1247   \c_strc_math_ragged_status\plustwo
1248   \c_strc_math_number_swapped\conditionalfalse
1249   \updateparagraphproperties} % not needed
1250
1251\defcsname\??mathtextalign\v!flushright\endcsname
1252  {\raggedleft
1253   \mathgluemode\plustwo
1254   \c_strc_math_ragged_status\plusthree
1255   \c_strc_math_number_swapped\conditionalfalse
1256   \updateparagraphproperties} % not needed
1257
1258\defcsname\??mathtextalign\v!slanted\endcsname % maybe move bottom to number location
1259  {\raggedslanted
1260  %\mathgluemode\plustwo
1261   \c_strc_math_ragged_status\plustwo
1262   \edef\p_distance{\formulaparameter\c!leftmargindistance}%
1263   \parinitleftskip \ifx\p_distance\v!number \wd\b_strc_formulas_number \else \p_distance \fi
1264   \edef\p_distance{\formulaparameter\c!rightmargindistance}%
1265   \parfillrightskip\ifx\p_distance\v!number \wd\b_strc_formulas_number \else \p_distance \fi
1266   \updateparagraphproperties} % not needed
1267
1268\def\strc_math_setup_align
1269  {\ifcsname\??mathtextalign\formulaparameter\c!align\endcsname
1270     \lastnamedcs\else\begincsname\??mathtextalign\v!middle\endcsname
1271     \math_check_limit
1272   \fi}
1273
1274\def\math_check_limit
1275  {\ifcstok{\mathematicsparameter\c!limit}\v!yes
1276     \bitwiseflip\mathgluemode\plusfour
1277   \fi}
1278
1279\appendtoks
1280    \math_check_limit
1281\to \everymathematics
1282
1283% split : wrap (box) and flow (yes)
1284
1285\defcsname\??mathtextalign\v!flushleft:\v!auto\endcsname
1286  {\raggedright
1287   \mathgluemode\plustwo
1288   \c_strc_math_ragged_status\plusone
1289   \strc_math_analyze_box}
1290
1291\defcsname\??mathtextalign\v!middle:\v!auto\endcsname
1292  {\raggedright                       % needed for the lua magick (stage 1)
1293   \mathgluemode\plustwo              % only shrink (otherwise inconsistent)
1294   \c_strc_math_ragged_status\plustwo % needed for the lua magick (stage 2)
1295   \strc_math_analyze_box}            % lua magick
1296
1297\defcsname\??mathtextalign\v!flushright:\v!auto\endcsname
1298  {\raggedright
1299   \mathgluemode\plustwo % only shrink
1300   \c_strc_math_ragged_status\plusthree
1301   \strc_math_analyze_box}
1302
1303\defcsname\??mathtextalign\v!slanted:\v!auto\endcsname
1304  {\raggedright
1305   \mathgluemode\plustwo
1306   \c_strc_math_ragged_status\plustwo
1307   \strc_math_analyze_box}
1308
1309\def\strc_math_setup_align_auto
1310  {\ifcsname\??mathtextalign\formulaparameter\c!align:\v!auto\endcsname
1311     \lastnamedcs\else\begincsname\??mathtextalign\v!middle:\v!auto\endcsname
1312   \fi}
1313
1314\letcsname\??mathtextalign\v!right        \expandafter\endcsname\csname\??mathtextalign\v!flushleft         \endcsname
1315\letcsname\??mathtextalign\v!left         \expandafter\endcsname\csname\??mathtextalign\v!flushright        \endcsname
1316\letcsname\??mathtextalign\v!right:\v!auto\expandafter\endcsname\csname\??mathtextalign\v!flushleft :\v!auto\endcsname
1317\letcsname\??mathtextalign\v!left :\v!auto\expandafter\endcsname\csname\??mathtextalign\v!flushright:\v!auto\endcsname
1318
1319\startsetups[math:penalties:\v!text]
1320    \interlinepenalty \plustenthousand
1321    \shapingpenalty   \plustenthousand
1322\stopsetups
1323
1324% or (test):
1325%
1326% \startsetups[math:penalties:\v!text]
1327%     \shapingpenaltiesmode \zerocount
1328%     \interlinepenalty     \plustenthousand
1329% \stopsetups
1330
1331\startsetups[math:penalties:\v!page]
1332    \shapingpenaltiesmode \zerocount
1333    \widowpenalties \plusthree \plustenthousand \plustenthousand \zerocount
1334    \clubpenalties  \plusthree \plustenthousand \plustenthousand \zerocount
1335\stopsetups
1336
1337\setupformula
1338  [\c!penalties=math:penalties:\formulaparameter\c!split] % math:penalties:\m_strc_math_split
1339
1340\def\strc_math_setup_penalties
1341  {\directsetup{\formulaparameter\c!penalties}}
1342
1343% a limitation is that this only works in a regular setting, so no shapes
1344
1345\appendtoks
1346    \global\d_strc_math_indent      \zeropoint
1347    \global\c_strc_math_n_of_lines  \zerocount
1348    \global\d_strc_math_first_height\zeropoint
1349    \global\d_strc_math_first_left  \zeropoint
1350    \global\d_strc_math_first_right \zeropoint
1351    \global\d_strc_math_last_left   \zeropoint
1352    \global\d_strc_math_last_right  \zeropoint
1353    \global\d_strc_math_last_depth  \zeropoint
1354    \global\d_strc_math_max_right   \zeropoint
1355    \global\d_strc_math_max_left    \zeropoint
1356    \global\d_math_strc_hangindent  \zeropoint
1357    \global\c_math_strc_hangafter   \zeropoint
1358\to \everyresetformulas
1359
1360\newbox\b_strc_math_display % most code is in math-ali (for historical reasons)
1361
1362\newgluespec\s_strc_formulas_margin_left  % maybe just dimen
1363\newgluespec\s_strc_formulas_margin_right % idem
1364
1365\def\strc_formulas_set_paragraph
1366  {%\setlocalhsize
1367   %\hsize\localhsize
1368   %
1369   \d_strc_formulas_display_width\formulaparameter\c!width\relax
1370%    \s_strc_formulas_margin_left \leftskip
1371%    \s_strc_formulas_margin_right\rightskip
1372   \edef\p_margin{\formulaparameter\c!leftmargin}%
1373   \ifempty\p_margin \else
1374     \doadaptleftskip\p_margin
1375   \fi
1376   \edef\p_margin{\formulaparameter\c!rightmargin}%
1377   \ifempty\p_margin \else
1378     \doadaptrightskip\p_margin
1379   \fi
1380%    \edef\p_margin{\formulaparameter\c!margin}%
1381%    \ifempty\p_margin \else
1382%      \doadaptleftskip\p_margin
1383%      \doadaptrightskip\p_margin
1384%    \fi
1385   \s_strc_formulas_margin_left \leftskip
1386   \s_strc_formulas_margin_right\rightskip
1387   \edef\p_interlinespace{\formulaparameter\c!interlinespace}%
1388   \ifempty\p_interlinespace\else\baselineskip\p_interlinespace\fi
1389   \global\c_strc_math_aligned_here\conditionalfalse
1390   \hsize\d_strc_formulas_display_width
1391   \displaywidth\hsize
1392   \displayindent\zeropoint}
1393
1394\def\strc_math_analyze_box
1395  {\clf_handlemathhang
1396     stage       \plusone
1397     alignstate  \c_strc_math_ragged_status
1398     box         \b_strc_math_display
1399     distance    \formulaparameter\c!textdistance
1400     leftmargin  \the\dimexpr\s_strc_formulas_margin_left\relax
1401     rightmargin \the\dimexpr\s_strc_formulas_margin_right\relax
1402   \relax
1403  %\holdingmigrations\zerocount
1404   \setbox\b_strc_math_display\vbox\bgroup % \vtop
1405     % beware: everypar is doing sidefloats here so we then have hang values set
1406     % but we have no local leftskip and rightskip as they are reflected in hsize
1407     \strc_formulas_trigger_side_box
1408     \ifconditional\c_strc_math_aligned_here
1409       \ifzeropt\d_strc_math_indent\else
1410         \advanceby\leftskip\d_strc_math_indent % which is why we see a leftskip reported !
1411         \hskip-\d_strc_math_indent
1412       \fi
1413     \else
1414       \strc_math_setup_align
1415     \fi
1416   % \strc_math_setup_spacing\formulaparameter
1417     \strc_math_setup_penalties
1418     \unhbox\b_strc_math_display
1419   \egroup
1420   \clf_handlemathhang
1421     stage      \ifconditional\c_strc_math_aligned_here \plustwo \else \plusthree \fi
1422   % alignstate \c_strc_math_ragged_status
1423   % box        \b_strc_math_display
1424   % distance   \formulaparameter\c!textdistance
1425   \relax
1426   %
1427   \begingroup
1428     \edef\v_spac_whitespace_current{\formulaparameter\c!spaceinbetween}%
1429     \spac_whitespace_setup
1430     \clf_handlemathhang
1431       stage       \plusfour
1432       inbetween   1\parskip
1433       height      \strutht
1434       depth       \strutdp
1435       splitmethod {\formulaparameter\c!splitmethod}%
1436     \relax
1437   \endgroup}
1438
1439\let\strc_math_inject_show_margins_here\relax
1440
1441\integerdef\c_strc_math_positioning\zerocount
1442
1443%D For practical reasons this one is kept extern:
1444
1445\newconditional\c_strc_math_ignore_number % for testing space compatibility
1446
1447\fetchmodulecommand \showmathmargins \f!math_run
1448
1449\installtextracker
1450  {math.showmargins}
1451  {\def\strc_math_show_margins{\showmathmargins[\v!all]}%
1452   \let\strc_math_flush_number_box\strc_math_flush_number_box_visual}
1453  {\let\strc_math_show_margins\relax
1454   \let\strc_math_flush_number_box\strc_math_flush_number_box_normal}
1455
1456\installtextracker
1457  {math.showmargins.less}
1458  {\def\strc_math_show_margins{\showmathmargins}%
1459   \let\strc_math_flush_number_box\strc_math_flush_number_box_visual}
1460  {\let\strc_math_show_margins\relax
1461   \let\strc_math_flush_number_box\strc_math_flush_number_box_normal}
1462
1463\let\strc_math_show_margins\relax
1464
1465%D Till here.
1466
1467\def\strc_math_set_options#1%
1468  {\c_strc_formulas_tight\conditionalfalse
1469   \c_strc_formulas_packed\conditionalfalse
1470   \c_strc_formulas_depth\conditionalfalse
1471   \ifempty{#1}%
1472     \edef\p_option{\formulaparameter\c!option}%
1473   \orelse\ifhastok={#1}% this is new, so that we can also set the grid
1474     \setupcurrentformula[#1]%
1475     \edef\p_option{\formulaparameter\c!option}%
1476   \else
1477     \edef\p_option{\formulaparameter\c!option}%
1478     \edef\p_option{\ifempty\p_option\else\p_option,\fi#1}%
1479   \fi
1480   \ifempty\p_option \else
1481     \rawprocesscommacommand[\p_option]\strc_formulas_option
1482   \fi}
1483
1484% This is an experiment!
1485
1486% \lettonothing\strc_formulas_start_side_box
1487% \lettonothing\strc_formulas_stop_side_box
1488% \lettonothing\strc_formulas_check_side_box
1489% \lettonothing\strc_formulas_trigger_side_box
1490
1491\newdimen\d_strc_math_side_width
1492
1493\def\strc_formulas_check_side_box
1494  {\doifelsesidefloat
1495     {\d_strc_math_side_width\d_page_sides_width}%
1496     {\d_strc_math_side_width\zeropoint}}
1497
1498\def\strc_formulas_start_side_box
1499  {\ifzeropt\d_strc_math_side_width\else
1500     \advance\displaywidth-\d_strc_math_side_width
1501     \ifnum\c_page_sides_checks_done<\plustwo
1502       % see \strc_formulas_display_space_before_normal
1503       \vkern-\strutht % quite a hack
1504     \fi
1505     \dontleavehmode\dbox
1506   \fi
1507   \bgroup}
1508
1509\def\strc_formulas_stop_side_box
1510  {\egroup}
1511
1512\def\strc_formulas_trigger_side_box
1513  {\ifzeropt\d_strc_math_side_width\else
1514     \advance\hsize-\d_strc_math_side_width
1515     \forgeteverypar
1516     \dontleavehmode
1517   \fi}
1518
1519% End of experiment.
1520
1521\tolerant\protected\def\strc_formulas_start_formula#1#:#*[#S#2]% setting leftskip adaption is slow !
1522  {\strc_formulas_check_side_box
1523   \ifhmode
1524     \par
1525   \fi
1526   \bgroup % HERE
1527   \iftrialtypesetting\else
1528     \global\advanceby\c_strc_formulas_n\plusone
1529   \fi
1530   \cdef\currentformula{#1}%
1531   \usesetupsparameter\formulaparameter % new
1532   \dostarttaggedchained\t!formula\currentformula\??formula
1533   \strc_math_set_options{#2}%
1534   \strc_math_set_split
1535   \strc_math_set_number_location
1536   \strc_formulas_set_paragraph
1537   \let\strc_formulas_start_formula\strc_formulas_start_formula_nested
1538   \expand\everybeforedisplayformula
1539   \strc_math_setup_align
1540   \ifcstok{\formulaparameter\c!strut}\v!yes
1541     \let\strc_formulas_begstrut\begstrut
1542     \let\strc_formulas_endstrut\endstrut
1543   \else
1544     \let\strc_formulas_begstrut\relax
1545     \let\strc_formulas_endstrut\relax
1546   \fi
1547   \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname}
1548
1549\protected\def\strc_formulas_start_formula_nested#1%
1550  {\bgroup
1551   \let\strc_formulas_stop_formula\strc_formulas_stop_formula_nested
1552   \dostarttagged\t!subformula\empty}
1553
1554\protected\def\strc_formulas_stop_formula_nested
1555  {\dostoptagged
1556   \egroup}
1557
1558% the application of the above is in math-ali.mkxl: \strc_math_flush_aligned
1559
1560% tagging of formulanumbers is not ok (we get two display maths blobs)
1561
1562\newinteger\c_strc_formulas_n
1563
1564\ifdefined\dotagregisterformula \else \aliased\let\dotagregisterformula\gobbleoneargument \fi
1565
1566\protected\def\strc_formulas_stop_formula
1567  {\strc_formulas_place_number % in case it hasn't happened yet
1568   \strc_formulas_flush_number % in case we are in native mode
1569   \dostarttagged\t!formulacontent\empty
1570   \dotagregisterformula\c_strc_formulas_n
1571   \csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname
1572   \dostoptagged
1573   \dostoptagged
1574   \nonoindentation
1575   \useindentnextparameter\formulaparameter
1576   \egroup
1577   \hangafter\minusone   % added for side floats
1578   \hangindent\zeropoint % added for side floats
1579   \c_strc_formulas_handle_number\conditionalfalse
1580   \expand\everyresetformulas
1581   \dorechecknextindentation} % here ?
1582
1583% experiment:
1584
1585\def\strc_formulas_set_grid_snapping
1586  {\edef\p_grid{\formulaparameter\c!grid}%
1587   \ifempty\p_grid \else
1588     \spac_grids_snap_value_auto\p_grid
1589   \fi}
1590
1591\appendtoks
1592    \ifgridsnapping
1593        \strc_formulas_set_grid_snapping
1594    \fi
1595\to \everybeforedisplayformula
1596
1597\tolerant\permanent\protected\def\formula[#1]#;#2% todo: tagged
1598  {\begingroup
1599   \ifparameters#1\else
1600     \rawprocesscommacommand[#1]\strc_formulas_option
1601   \fi
1602   \useformulastyleandcolor\c!style\c!color
1603   \mathematics{#2}%
1604   \endgroup}
1605
1606\aliased\letcsname\v!formula\endcsname\formula
1607
1608%D \starttyping
1609%D % test \par       % no preceding hlist
1610%D % $$x$$           % preceding hlist
1611%D % \noindent $$x$$ % no preceding hlist
1612%D \startformula x \stopformula % now has \noindent (in mkii we messed with baselineskip)
1613%D \stoptyping
1614
1615\let\strc_formulas_begstrut\relax
1616\let\strc_formulas_endstrut\relax
1617
1618\newboundary\c_math_begin_boundary
1619
1620\permanent\protected\def\startdisplaymath
1621  {\ifhmode
1622     \par
1623   \fi
1624   \bgroup
1625   \informulatrue
1626   \beforedisplayspace
1627   \startinnermath
1628   \ifrelax\strc_formulas_begstrut\else
1629     \strc_formulas_begstrut
1630     \boundary\c_math_begin_boundary
1631   \fi
1632   \begingroup} % less interference with upcoming a \over b
1633
1634\permanent\protected\def\stopdisplaymath
1635  {\endgroup    % less interference with upcoming a \over b
1636%    \ifrelax\strc_formulas_begstrut\else
1637     \strc_formulas_endstrut
1638%    \fi
1639   \stopinnermath
1640   \afterdisplayspace
1641   \egroup}
1642
1643% already defined
1644%
1645% \lettonothing\startinnermath
1646% \lettonothing\stopinnermath
1647
1648% \defineformulaalternative[multi][\begindmath][\enddmath]
1649%
1650% \fakewords{20}{40}\epar
1651% \placeformula {a} $$              \fakespacingformula $$
1652% \fakewords{20}{40}\epar
1653% \placeformula {b} \startformule   \fakespacingformula \stopformule
1654% \placeformula {b} \startformule   \fakespacingformula \stopformule
1655% \fakewords{20}{40}\epar
1656% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
1657% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
1658% \fakewords{20}{40}\epar
1659% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
1660% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
1661% \fakewords{20}{40}\epar
1662% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
1663% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
1664% \fakewords{20}{40}\epar
1665% \placeformula {f} \startspformule \fakespacingformula \stopspformule
1666% \placeformula {f} \startspformule \fakespacingformula \stopspformule
1667% \fakewords{20}{40}
1668
1669\tolerant\permanent\protected\def\startsubformulas[#1]%
1670  {\edef\currentsubformulasreference{#1}%
1671   \global\c_strc_formulas_inside_formulas_sub\conditionaltrue
1672   \strc_formulas_handle_sub_number}
1673
1674\permanent\protected\def\stopsubformulas
1675  {\nonoindentation
1676   \useindentnextparameter\subformulaparameter
1677   \expand\everyresetformulas % to be checked
1678   \global\c_strc_formulas_inside_formulas_sub\conditionalfalse
1679   \dorechecknextindentation} % here ?
1680
1681%D Named subformulas (to be redone)
1682
1683\tolerant\permanent\protected\def\startnamedsubformulas[#1]#2%
1684  {\setformulalistentry{#2}%
1685   \startsubformulas[#1]}
1686
1687\permanent\protected\def\stopnamedsubformulas
1688  {\stopsubformulas}
1689
1690%D Experimental goodie:
1691%D
1692%D \startbuffer
1693%D \placelist[formula][criterium=text] \blank[2*big]
1694%D \placenamedformula[one]{first}  \startformula a = 1 \stopformula \endgraf
1695%D \placeformula                   \startformula a = 2 \stopformula \endgraf
1696%D \placenamedformula     {second} \startformula a = 3 \stopformula \endgraf
1697%D \stopbuffer
1698%D
1699%D \typebuffer \getbuffer
1700
1701\permanent\protected\def\startformulas{\strc_formulas_start_formulas}
1702
1703\permanent\letcsname\e!stop\v!formulas\endcsname\relax
1704
1705\tolerant\protected\def\strc_formulas_nested_formula_start[#S#1]%
1706  {\begingroup
1707   \ifparameter#1\or
1708      \setupformula[\c!width=\d_strc_formulas_display_width,#1]%
1709      \d_strc_formulas_display_width\formulaparameter\c!width\relax
1710   \fi
1711   \vcenter \bgroup
1712   \hsize \d_strc_formulas_display_width
1713   \displaywidth\d_strc_formulas_display_width
1714   \raggedcenter
1715   \dostarttagged\t!formulacontent\empty
1716   \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname}
1717
1718\protected\def\strc_formulas_nested_formula_stop
1719  {\csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname
1720   \dostoptagged
1721   \egroup
1722   \hss
1723   \endgroup}
1724
1725\normalexpanded{\tolerant\def\noexpand\strc_formulas_start_formulas[#1]#:#2\csname\e!stop\v!formulas\endcsname}%
1726  {\startformula
1727   \dostarttagged\t!formulaset\empty
1728   \global\c_strc_formulas_inside_formulas\conditionaltrue
1729   \edef\currentformulasreference{#1}%
1730   \strc_formulas_handle_number
1731   \lettonothing\currentformula
1732 % \strc_formulas_forget_display_skips
1733   \enforced\protected\def\startformula
1734     {\advanceby\scratchcounter\plusone
1735      \expandafter\ignoreupto\csname\e!stop\v!formula\endcsname}%
1736   \scratchcounter\zerocount
1737   #2% preroll
1738   \hbox to \d_strc_formulas_display_width \bgroup
1739     \ifcase\scratchcounter\else
1740       \divideby\d_strc_formulas_display_width\scratchcounter
1741     \fi
1742     \hss
1743     \enforced\let\startformula\strc_formulas_nested_formula_start
1744     \enforced\let\stopformula \strc_formulas_nested_formula_stop
1745     #2%
1746   \egroup
1747   \global\c_strc_formulas_inside_formulas\conditionalfalse
1748   \dostoptagged
1749   \stopformula
1750   \expand\everyresetformulas
1751   \hangafter\minusone    % added for side floats
1752   \hangindent\zeropoint} % added for side floats
1753
1754% place
1755
1756\def\m_strc_formulas_flag_inhibit{-}
1757\def\m_strc_formulas_flag_force  {+}
1758
1759\def\strc_formulas_check_reference#1#2%
1760  {#1\unless\ifempty\namedformulaentry % \relax % new 29/8/2010
1761     \plusthree
1762   \orelse\ifempty#2%
1763     \zerocount
1764   \orelse\ifx#2\m_strc_formulas_flag_force
1765     \plusone
1766   \orelse\ifx#2\m_strc_formulas_flag_inhibit
1767     \plustwo
1768   \else
1769     \plusthree
1770   \fi}
1771
1772\tolerant\permanent\protected\def\formulanumber[#1]%
1773  {\def\currentformulareference{#1}%
1774   \strc_formulas_place_number_in_box}
1775
1776\permanent\protected\def\placeformula   {\global\c_strc_formulas_inside_place\conditionaltrue    \strc_formulas_place}
1777\permanent\protected\def\placesubformula{\global\c_strc_formulas_inside_place_sub\conditionaltrue\strc_formulas_place}
1778
1779\tolerant\protected\def\strc_formulas_place[#1]%
1780  {\xdef\currentplaceformulareference{#1}%
1781   \glettonothing\currentplaceformulasuffix
1782   \glettonothing\currentnestedformulasuffix
1783   \global\c_strc_formulas_incremented\conditionalfalse
1784   \global\c_strc_formulas_referenced\conditionalfalse
1785   \global\c_strc_formulas_inside_place\conditionaltrue
1786   \doifelsenextbgroup\strc_formulas_place_yes\strc_formulas_place_nop} % [ref]{}
1787
1788\protected\def\strc_formulas_place_yes#1%
1789  {\xdef\currentplaceformulasuffix{#1}%
1790   \strc_formulas_place_nop}
1791
1792%D We no longer pickup $$ as this is now equivalent to inline:
1793
1794% \protected\def\strc_formulas_place_nop
1795%   {\doifelsenextchar$\strc_formulas_place_pickup\strc_formulas_place_indeed} % [ref]$$ [ref]\start
1796%
1797% \protected\def\strc_formulas_place_indeed
1798%   {\strc_formulas_place_numbering}
1799%
1800% \protected\def\strc_formulas_place_pickup$$#1$$%
1801%   {\strc_formulas_place_numbering
1802%    \strc_formulas_start_formula{}#1\strc_formulas_stop_formula}
1803
1804\protected\def\strc_formulas_place_nop
1805  {\strc_formulas_place_numbering}
1806
1807% \let\startplaceformula\placeformula
1808% \let\stopplaceformula \relax
1809
1810% \startplaceformula                 \startformula e=mc^2 \stopformula \stopplaceformula
1811% \startplaceformula[-]              \startformula e=mc^2 \stopformula \stopplaceformula
1812% \startplaceformula[x]              \startformula e=mc^2 \stopformula \stopplaceformula
1813% \startplaceformula[reference=foo]  \startformula e=mc^2 \stopformula \stopplaceformula
1814% \startplaceformula[title=whatever] \startformula e=mc^2 \stopformula \stopplaceformula
1815% \startplaceformula[suffix=x]       \startformula e=mc^2 \stopformula \stopplaceformula
1816
1817\mutable\lettonothing\currentplaceformulatitle
1818\mutable\lettonothing\currentplaceformulareference
1819\mutable\lettonothing\currentplaceformulasuffix
1820\mutable\lettonothing\currentplaceformulabookmark
1821\mutable\lettonothing\currentplaceformulalist
1822
1823\permanent\tolerant\protected\def\startplaceformula[#S#1]%
1824  {\begingroup
1825   \global\c_strc_formulas_incremented\conditionalfalse
1826   \global\c_strc_formulas_referenced\conditionalfalse
1827   \global\c_strc_formulas_inside_place\conditionaltrue
1828   \ifparameter#1\or
1829     \expandafter\strc_formulas_start_place_yes
1830   \else
1831     \expandafter\strc_formulas_start_place_nop
1832   \fi[#1]}
1833
1834\def\strc_formulas_start_place_nop[#S#1]%
1835  {\glettonothing\currentplaceformulareference
1836   \glettonothing\currentplaceformulasuffix
1837   \strc_formulas_place_nop}
1838
1839\def\strc_formulas_start_place_yes[#S#1]% todo
1840  {\doifassignmentelse{#1}
1841     {\strc_formulas_set_place_parameters{#1}%
1842      \doifelsenextbgroup\strc_formulas_place_yes\strc_formulas_place_nop}% [ref]{}
1843     {\xdef\currentplaceformulareference{#1}%
1844      \glettonothing\currentplaceformulasuffix
1845      \strc_formulas_place_nop}}
1846
1847\def\strc_formulas_set_place_parameters#1% maybe a dedicated setup handler
1848  {\resetdummyparameter\c!title
1849   \resetdummyparameter\c!reference
1850   \resetdummyparameter\c!bookmark
1851   \resetdummyparameter\c!list
1852   \resetdummyparameter\c!suffix
1853   \getdummyparameters[#1]%
1854   \edef\currentplaceformulatitle    {\dummyparameter\c!title}%
1855   \edef\currentplaceformulareference{\dummyparameter\c!reference}%
1856   \edef\currentplaceformulabookmark {\dummyparameter\c!bookmark}%
1857   \edef\currentplaceformulalist     {\dummyparameter\c!list}%
1858   \edef\currentplaceformulasuffix   {\dummyparameter\c!suffix}%
1859   \ifempty\currentplaceformulatitle\else
1860     \normalexpanded{\setformulalistentry{\currentplaceformulatitle}}%
1861   \fi}
1862
1863\permanent\protected\def\stopplaceformula
1864  {\relax
1865   \endgroup}
1866
1867%D This is new in \LMTX\ (and described in the manual):
1868%D
1869%D \starttyping
1870%D \startformula
1871%D     \startsubnumberinghere
1872%D         x \alignhere = a + 1  \numberhere[ref:c1]
1873%D           \breakhere = b + 2  \numberhere
1874%D           \breakhere = c + 3n \numberhere[ref:c2]
1875%D     \stopsubnumberinghere
1876%D \stopformula
1877%D
1878%D \startformula
1879%D     x \alignhere = a + 1n \numberhere[ref:a]
1880%D       \breakhere = b + 2  \numberhere
1881%D       \breakhere = c + 3  \numberhere
1882%D \stopformula
1883%D
1884%D \startformula
1885%D     \startsubnumberinghere
1886%D         x \alignhere = a + 1  \numberhere
1887%D           \breakhere = b + 2  \numberhere
1888%D           \breakhere = c + 3  \numberhere
1889%D     \stopsubnumberinghere
1890%D           \breakhere = d + 4n \numberhere[ref:d]
1891%D \stopformula
1892%D \stoptyping
1893
1894\newconditional \c_strc_formulas_in_sub
1895
1896\permanent\protected\def\startsubnumberinghere
1897  {\begingroup
1898   \c_strc_formulas_in_sub\conditionaltrue
1899   \strc_counters_increment\v!formula}
1900
1901\permanent\protected\def\stopsubnumberinghere
1902  {\c_strc_formulas_in_sub\conditionalfalse
1903   \endgroup}
1904
1905\permanent\tolerant\protected\def\numberhere[#1]%
1906  {\begingroup
1907   \global\c_strc_formulas_incremented\conditionalfalse
1908   \global\c_strc_formulas_referenced\conditionaltrue
1909   \global\c_strc_formulas_inside_place\conditionalfalse
1910   \global\c_strc_formulas_place_number_mode\zerocount
1911   %
1912   \glettonothing\currentplaceformulareference
1913   \glettonothing\currentplaceformulasuffix
1914   %
1915   \ifparameter#1\orelse\ifhastok={#1}%
1916     \strc_formulas_set_place_parameters{#1}%
1917   \else
1918     \xdef\currentplaceformulareference{#1}%
1919   \fi
1920   \iftrialtypesetting
1921   \orelse\ifempty\currentplaceformulareference
1922   \else
1923     \global\c_strc_formulas_referenced\conditionalfalse % maybe always anyway (title etc)
1924     \ifconditional\c_strc_formulas_in_sub
1925       \c_strc_formulas_counter_level\plustwo % we use normal numbering here
1926     \fi
1927     \strc_formulas_check_reference
1928       \c_strc_formulas_place_number_mode
1929       \currentplaceformulareference
1930   \fi
1931   \texthere
1932     [\ifcstok{\formulaparameter\c!location}\v!left\v!left\else\v!right\fi]%
1933     {\ifconditional\c_strc_formulas_in_sub
1934        \strc_formulas_handle_sub_numbering
1935      \else
1936        \strc_formulas_handle_numbering
1937      \fi}%
1938   \endgroup}
1939
1940% to be checked
1941
1942\let\strc_formulas_place_number       \relax
1943\let\strc_formulas_place_number_nested\gobbletwoarguments
1944
1945\def\strc_formulas_place_number_nested_indeed#1#2%
1946  {\ifhastok={#1}%
1947     \setupcurrentmathalignment[#1]%
1948     \xdef\currentnestedformulareference{\mathalignmentparameter\c!reference}%
1949     \xdef\currentnestedformulasuffix   {\mathalignmentparameter\c!suffix}%
1950     \global\d_math_eqalign_number_threshold\mathalignmentparameter\c!numberthreshold\relax
1951   \orelse\ifhastok+{#1}%
1952     \glettonothing\currentnestedformulareference
1953     \xdef\currentnestedformulasuffix   {+}%
1954   \orelse\ifempty\currentplaceformulareference
1955     \xdef\currentnestedformulareference{#1}%
1956     \xdef\currentnestedformulasuffix   {#2}%
1957   \else
1958     \glettonothing\currentnestedformulareference
1959     \xdef\currentnestedformulasuffix   {#1}%
1960   \fi
1961   \strc_formulas_place_number_nested_check}
1962
1963\def\strc_formulas_place_number_nested_check
1964  {\ifempty\currentnestedformulareference
1965     \ifempty\currentnestedformulasuffix \else
1966       \c_strc_formulas_nested_number_mode\plusthree
1967     \fi
1968   \else
1969     \strc_formulas_check_reference\c_strc_formulas_nested_number_mode\currentnestedformulareference
1970   \fi
1971   \ifcase\c_strc_formulas_nested_number_mode
1972     % nothing
1973   \or
1974     \glet\strc_formulas_place_number\relax
1975     \strc_formulas_place_number_in_box
1976   \or
1977     % nothing
1978   \or
1979     \glet\strc_formulas_place_number\relax
1980     \strc_formulas_place_number_in_box
1981   \fi}
1982
1983\def\strc_formulas_place_number_indeed
1984  {\strc_formulas_place_number_in_box}
1985
1986% \startplaceformula
1987%     \startformula
1988%         \startalign
1989%         \NC a \NC = p \NR[eq:one]
1990%         \NC b \NC = q \NR
1991%         \NC c \NC = r \NR[eq:two]
1992%         \NC d \NC = s \NR[eq:three]
1993%         \stopalign
1994%     \stopformula
1995% \stopplaceformula
1996% \stoptext
1997
1998% Relaxing in the macro is really needed because otherwise we get spurious
1999% numbers probably due to some % interference with other local variables
2000
2001\def\strc_formulas_place_number_in_box
2002  {\dostarttagged\t!formulacaption\empty
2003   \glet\strc_formulas_place_number       \relax
2004  %\glet\strc_formulas_place_number_nested\gobbletwoarguments
2005   \global\setbox\b_strc_formulas_number\naturalhbox{\strc_formulas_number_indeed}%
2006   \global\d_strc_formulas_number\wd\b_strc_formulas_number
2007   \dostoptagged}
2008
2009\let\strc_formulas_flush_number\relax
2010
2011% todo
2012
2013\permanent\tolerant\protected\def\placenamedformula[#1]%
2014  {\ifarguments
2015     \expandafter\strc_formulas_place_named_nop
2016   \else
2017     \expandafter\strc_formulas_place_named_yes
2018   \fi[#1]}
2019
2020\def\strc_formulas_place_named_yes[#1]#2%
2021  {\setformulalistentry{#2}%
2022   \placeformula[#1]}
2023
2024\def\strc_formulas_place_named_nop[#1]#2%
2025  {\setformulalistentry{#2}%
2026   \placeformula}
2027
2028\def\strc_math_flush_aligned_boxed_direct_yes
2029  {\dontleavehmode % NO!
2030   \hskip-\leftskip % bah
2031   \box\b_strc_math_display
2032   \llap{\box\b_strc_formulas_number}}
2033
2034\def\strc_math_flush_aligned_boxed_direct_nop
2035  {\dontleavehmode % NO!
2036   \hskip-\leftskip % bah
2037   \box\b_strc_math_display}
2038
2039\mutable\lettonothing\namedformulaentry % \relax % this will become a key/value so that we can do bookmarks
2040
2041\permanent\protected\def\setformulalistentry#1%
2042  {\xdef\namedformulaentry{#1}}
2043
2044%D New:
2045%D
2046%D \setupformula[snap=yes,snapstep=medium]
2047%D
2048%D \startbuffer
2049%D We test \dorecurse{20}{$x^{#1}$ and $\frac{1}{#1}^x$ and $\sqrt[#1]{x}$ and }that's it.
2050%D \stopbuffer
2051%D
2052%D \startcombination[nx=2,ny=3,location=top]
2053%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=no]                 \showboxes            \enabletrackers [math.snapping=darkred] \getbuffer}} {}
2054%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=no]                                       \disabletrackers[math.snapping]         \getbuffer}} {}
2055%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=small] \showboxes \darkgreen \enabletrackers [math.snapping=darkred] \getbuffer}} {}
2056%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=small]            \darkgreen \disabletrackers[math.snapping]         \getbuffer}} {}
2057%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=big]   \showboxes \darkblue  \enabletrackers [math.snapping=darkred] \getbuffer}} {}
2058%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=big]              \darkblue  \disabletrackers[math.snapping]         \getbuffer}} {}
2059%D \stopcombination
2060
2061\definesystemattribute[mathsnap][public]
2062
2063\appendtoks
2064    \ifcstok{\formulaparameter\c!snap}\v!yes
2065      \setmathsnapping{\formulaparameter\c!snapstep}%
2066    \else
2067      \setmathsnapping\v!reset
2068    \fi
2069\to \everysetupformula
2070
2071%D Also new, handy for articles and manuals:
2072
2073% \starttext
2074%     \showmakeup[line]
2075%     \input tufte \startformula                e = mc^2 \stopformula
2076%     \input tufte \startformula[bodyfont=10pt] e = mc^2 \stopformula
2077%     \input tufte \startformula[bodyfont=24pt] e = mc^2 \stopformula
2078%     \input tufte
2079% \stoptext
2080
2081\prependtoks
2082   \usebodyfontparameter\formulaparameter
2083\to \everymathematics
2084
2085\protect \endinput
2086
2087% \abovedisplayshortskip0pt \belowdisplayshortskip0pt \abovedisplayskip0pt \belowdisplayskip0pt \forgetall
2088%
2089% test       \par                      $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2090% test       \par                      $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2091% test plus  \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2092% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2093%
2094% \parskip\baselineskip
2095%
2096% test       \par                      $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2097% test       \par                      $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2098% test plus  \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2099% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
2100