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