spac-ali.mkxl /size: 61 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=spac-ali,
3%D        version=2009.10.16, % 1997.03.31, was core-spa.tex
4%D          title=\CONTEXT\ Spacing Macros,
5%D       subtitle=Alignments,
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 Spacing Macros / Alignments}
15
16\unprotect
17
18%D The \type {new} and \type {old} methods are gone as we now have \type {flush*}
19%D variants. Starting at the last day of 2011 both methods are merged into one and
20%D caching has been added, which makes switching twice as fast.
21
22\registerctxluafile{spac-ali}{autosuffix}
23
24% Used once so ... replace it or use if more frequently ...
25
26\installcorenamespace {alignswitch}
27
28% maybe \setconstantvalue or so
29
30\expandafter\integerdef\csname\??alignswitch\v!left  \endcsname\zerocount
31\expandafter\integerdef\csname\??alignswitch\v!middle\endcsname\plusone
32\expandafter\integerdef\csname\??alignswitch\v!right \endcsname\plustwo
33
34\mutable\integerdef\alignmentswitch\zerocount
35
36\permanent\protected\def\setalignmentswitch#1%
37  {\integerdef\alignmentswitch\csname\??alignswitch\ifcsname\??alignswitch#1\endcsname#1\else\v!left\fi\endcsname}
38
39% till here
40
41\definesystemattribute[realign]   [public] % might be combined with the next one
42\definesystemattribute[alignstate][public] % will make a single attributes for several states
43
44\appendtoks
45    \c_attr_realign   \attributeunsetvalue
46    \c_attr_alignstate\attributeunsetvalue
47\to \everyforgetall
48
49\permanent\protected\def\signalinnerrealign{\clf_setrealign\plustwo}
50\permanent\protected\def\signalouterrealign{\clf_setrealign\plusone}
51
52\installcorenamespace{aligncommand}
53\installcorenamespace{alignhorizontal}
54\installcorenamespace{alignvertical}
55
56% \installcorenamespace{alignmentnormalcache}
57% \installcorenamespace{alignmentraggedcache}
58
59% nasty hack:
60
61\installcorenamespace{alignmentnormalcacheodd}
62\installcorenamespace{alignmentnormalcacheeven}
63
64\installcorenamespace{alignmentraggedcacheodd}
65\installcorenamespace{alignmentraggedcacheeven}
66
67\immutable\def\??alignmentnormalcache{\ifodd\realpageno\??alignmentnormalcacheodd\else\??alignmentnormalcacheeven\fi}
68\immutable\def\??alignmentraggedcache{\ifodd\realpageno\??alignmentraggedcacheodd\else\??alignmentraggedcacheeven\fi}
69
70\newtoks\everyresetalign % todo
71
72% This will become a more advanced layout controller soon:
73
74\newconditional\layoutlefttoright   \layoutlefttoright\conditionaltrue
75\newconditional\displaylefttoright  \displaylefttoright\conditionaltrue
76\newconditional\inlinelefttoright   \inlinelefttoright\conditionaltrue
77
78\permanent\protected\def\lefttoright
79  {\ifvmode
80     \spac_directions_lefttoright_vmode
81   \else
82     \spac_directions_lefttoright_hmode
83   \fi}
84
85\permanent\protected\def\righttoleft
86  {\ifvmode
87     \spac_directions_righttoleft_vmode
88   \else
89     \spac_directions_righttoleft_hmode
90   \fi}
91
92\protected\def\spac_directions_lefttoright_vmode
93  {\displaylefttoright\conditionaltrue
94   \inlinelefttoright\conditionaltrue
95   \textdirection\directionlefttoright
96   \pardirection \directionlefttoright}
97
98\protected\def\spac_directions_righttoleft_vmode
99  {\displaylefttoright\conditionalfalse
100   \inlinelefttoright\conditionalfalse
101   \textdirection\directionrighttoleft
102   \pardirection \directionrighttoleft}
103
104\protected\def\spac_directions_lefttoright_hmode
105  {\linedirection\directionlefttoright % linedir keeps subtype of skip
106   \inlinelefttoright\conditionaltrue}
107
108\protected\def\spac_directions_righttoleft_hmode
109  {\linedirection\directionrighttoleft % linedir keeps subtype of skip
110   \inlinelefttoright\conditionalfalse}
111
112\permanent\protected\def\synchronizelayoutdirection
113  {\ifconditional\layoutlefttoright
114     \spac_directions_synchronize_lr
115   \else
116     \spac_directions_synchronize_rl
117   \fi}
118
119\permanent\protected\def\synchronizedisplaydirection
120  {\ifconditional\displaylefttoright
121     \spac_directions_synchronize_lr
122   \else
123     \spac_directions_synchronize_rl
124   \fi}
125
126\def\spac_directions_synchronize_lr
127  {\inlinelefttoright\conditionaltrue
128   \textdirection\directionlefttoright
129   \pardirection \directionlefttoright}
130
131\def\spac_directions_synchronize_rl
132  {\inlinelefttoright\conditionalfalse
133   \textdirection\directionrighttoleft
134   \pardirection \directionrighttoleft}
135
136\permanent\protected\def\synchronizeinlinedirection
137  {% why not \linedirection here
138   \textdirection\ifconditional\inlinelefttoright\directionlefttoright\else\directionrighttoleft\fi}
139
140\permanent\protected\def\checkedlefttoright
141  {\ifvmode
142     \spac_directions_lefttoright_vmode
143   \else
144     \spac_directions_lefttoright_hmode_checked
145   \fi}
146
147\permanent\protected\def\checkedrighttoleft
148  {\ifvmode
149     \spac_directions_righttoleft_vmode
150   \else
151     \spac_directions_righttoleft_hmode_checked
152   \fi}
153
154\protected\def\spac_directions_lefttoright_hmode_checked
155  {\ifconditional\inlinelefttoright\else
156     \lefttoright
157   \fi}
158
159\protected\def\spac_directions_righttoleft_hmode_checked
160  {\ifconditional\inlinelefttoright
161     \righttoleft
162   \fi}
163
164\installcorenamespace{bidi}
165
166\letcsname\??bidi\v!left \endcsname\checkedlefttoright \letcsname\??bidi l2r\endcsname\checkedlefttoright
167\letcsname\??bidi\v!right\endcsname\checkedrighttoleft \letcsname\??bidi r2l\endcsname\checkedrighttoleft
168
169\permanent\protected\def\usebidiparameter#1%
170  {\begincsname\??bidi#1\c!bidi\endcsname}
171
172\permanent\protected\def\showdirections
173  {\dontleavehmode
174   \begingroup\infofont\textdirection\directionlefttoright[\space
175   layout:  \ifconditional\layoutlefttoright  l2r\else r2l\fi\space
176   display: \ifconditional\displaylefttoright l2r\else r2l\fi\space
177   inline:  \ifconditional\inlinelefttoright  l2r\else r2l\fi\space
178   ]\endgroup}
179
180\permanent\protected\def\righttolefthbox#1#{\reversehbox#1\bgroup\righttoleft\let\next} \aliased\let\rtlhbox\righttolefthbox
181\permanent\protected\def\lefttorighthbox#1#{\naturalhbox#1\bgroup\lefttoright\let\next} \aliased\let\ltrhbox\lefttorighthbox
182\permanent\protected\def\righttoleftvbox#1#{\reversevbox#1\bgroup\righttoleft\let\next} \aliased\let\rtlvbox\righttoleftvbox
183\permanent\protected\def\lefttorightvbox#1#{\naturalvbox#1\bgroup\lefttoright\let\next} \aliased\let\ltrvbox\lefttorightvbox
184\permanent\protected\def\righttoleftvtop#1#{\reversevtop#1\bgroup\righttoleft\let\next} \aliased\let\rtlvtop\righttoleftvtop
185\permanent\protected\def\lefttorightvtop#1#{\naturalvtop#1\bgroup\lefttoright\let\next} \aliased\let\ltrvtop\lefttorightvtop
186
187\permanent\protected\def\autodirhbox#1#{\hbox#1\bgroup\synchronizeinlinedirection\let\next}
188\permanent\protected\def\autodirvbox#1#{\vbox#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vbox
189\permanent\protected\def\autodirvtop#1#{\vtop#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vtop
190
191\permanent\protected\def\leftorrighthbox{\ifconditional\displaylefttoright\expandafter\lefttorighthbox\else\expandafter\righttolefthbox\fi}
192\permanent\protected\def\leftorrightvbox{\ifconditional\displaylefttoright\expandafter\lefttorightvbox\else\expandafter\righttoleftvbox\fi}
193\permanent\protected\def\leftorrightvtop{\ifconditional\displaylefttoright\expandafter\lefttorightvtop\else\expandafter\righttoleftvtop\fi}
194
195\permanent\protected\def\rtltext{\groupedcommand{\dontleavehmode\righttoleft\ignorespaces}\removeunwantedspaces}
196\permanent\protected\def\ltrtext{\groupedcommand{\dontleavehmode\lefttoright\ignorespaces}\removeunwantedspaces}
197
198% Tolerance and hyphenation
199
200\ifdefined\lesshyphens \else \let\lesshyphens\relax \fi
201\ifdefined\morehyphens \else \let\morehyphens\relax \fi
202\ifdefined\nohyphens   \else \let\nohyphens  \relax \fi
203\ifdefined\dohyphens   \else \let\dohyphens  \relax \fi
204
205% \pretolerance 100
206% \tolerance    200
207
208\newconstant\c_spac_tolerance_default  \c_spac_tolerance_default  200
209\newconstant\c_spac_tolerance_minimum  \c_spac_tolerance_minimum 1500
210\newconstant\c_spac_tolerance_normal   \c_spac_tolerance_normal  3000
211\newconstant\c_spac_tolerance_extreme  \c_spac_tolerance_extreme 4500
212
213\def\spac_align_set_raggedness_left  {\plustwo\bodyfontsize}
214\def\spac_align_set_raggedness_right {\plustwo\bodyfontsize}
215\def\spac_align_set_raggedness_middle{\plussix\bodyfontsize} % overloaded below
216
217% oeps, hsize can be 0pt in which case we get a strange division
218% was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
219
220\def\spac_align_set_raggedness_middle{\ifzeropt\hsize\plussix\bodyfontsize\else.5\hsize\fi}
221
222\permanent\protected\def\setraggedness#1% tricky .. we keep the global tolerance otherwise ... to be reconsidered
223  {\ifnum\tolerance<\c_spac_tolerance_minimum
224     \tolerance\c_spac_tolerance_minimum % small values have unwanted side effects
225   \else
226     % todo: take set value or none .. better done elsewhere (200 is normal)
227   \fi
228   \ifrelax\dohyphens % was 2.5 in old implementation using scratch registers
229     \hyphenpenalty\dimexpr2.8\hsize/\dimexpr#1\relax\relax % 50 in raggedright/raggedleft
230  %\else
231     % no need to do something as we're in \nohyphens
232   \fi}
233
234\protected\def\spac_align_set_tolerant
235  {\tolerance\c_spac_tolerance_normal}
236
237\protected\def\spac_align_set_very_tolerant
238  {\tolerance\c_spac_tolerance_extreme}
239
240\protected\def\spac_align_set_stretch
241  {\emergencystretch\bodyfontsize}
242
243\protected\def\spac_align_set_extreme_stretch
244  {\emergencystretch10\bodyfontsize}
245
246% Vertical
247
248\newconstant\c_spac_align_state_vertical
249\newconstant\c_spac_align_state_spread
250
251\protected\def\spac_align_set_vertical_none
252  {\enforced\let\raggedtopcommand   \relax
253   \enforced\let\raggedbottomcommand\relax}
254
255\protected\def\spac_align_set_vertical_lohi
256  {\enforced\let\raggedtopcommand   \vfilll
257   \enforced\let\raggedbottomcommand\vfilll}
258
259\protected\def\spac_align_set_vertical_low
260  {\enforced\let\raggedtopcommand   \vfilll
261   \enforced\let\raggedbottomcommand\relax}
262
263\protected\def\spac_align_set_vertical_high
264  {\enforced\let\raggedtopcommand   \relax
265   \enforced\let\raggedbottomcommand\vfilll}
266
267\def\spac_align_flush_vertical
268  {\ifcase\c_spac_align_state_vertical
269     \spac_align_set_vertical_none
270   \or
271     \spac_align_set_vertical_lohi
272   \or
273     \spac_align_set_vertical_low
274   \or
275     \spac_align_set_vertical_high
276   \fi
277   \baselineskip
278     1\baselineskip
279     \ifcase\c_spac_align_state_spread\else
280       \s!plus \onepoint
281     \fi
282   \relax}
283
284% Horizontal
285
286\ifdefined\raggedonelinerstate \else
287    \newconditional\raggedonelinerstate  % public
288\fi
289
290% \appendtoks
291%     \raggedonelinerstate\conditionalfalse
292% \to \everyforgetall
293
294\newconstant\raggedstatus     % public
295\newconstant\raggedhangstatus % public
296
297\newconstant\c_spac_align_state_horizontal
298\newconstant\c_spac_align_state_broad
299\newconstant\c_spac_align_state_par_fill
300
301\def\v_spac_align_fill_amount          {\plusone  fil}
302\def\v_spac_align_fill_amount_hard     {\plusone fill}
303\def\v_spac_align_fill_amount_extreme  {\plustenthousand  filll}
304\def\v_spac_align_fill_amount_negative {\minusone fil}
305\def\v_spac_align_fill_amount_double   {\plustwo  fil}
306\def\v_spac_align_fill_amount_space    {\plustwo  fil} % can be added to xspace if we have a key
307\def\v_spac_align_fill_amount_half             {.5fil}
308\let\v_spac_align_space_amount        \interwordspace
309\def\v_spac_align_space_amount_x          {.5\emwidth}
310
311\newgluespec\s_zero_plus_one_fil  \s_zero_plus_one_fil  = 0pt plus 1fil
312\newgluespec\s_zero_plus_one_fill \s_zero_plus_one_fill = 0pt plus 1fill
313\newgluespec\s_zero_plus_zero     \s_zero_plus_zero     = 0pt plus 0pt
314
315% \s!plus ... slower than inline
316
317\permanent\protected\def\spac_align_set_horizontal_none % should also relax \updateraggedskips
318  {\raggedstatus     \zerocount
319   \raggedhangstatus \zerocount
320   \c_attr_alignstate\attributeunsetvalue
321   \leftskip         \plusone\leftskip
322   \rightskip        \plusone\rightskip
323   \spaceskip        \zeroskip
324   \xspaceskip       \zeroskip
325   \parinitleftskip  \zeroskip
326   \parinitrightskip \zeroskip
327   \parfillleftskip  \zeroskip
328   \parfillrightskip \s_zero_plus_one_fil % new
329   \raggedonelinerstate\conditionalfalse % now here
330   \enforced\aliased\let\updateraggedskips\relax}          % no need for adaption
331
332\permanent\protected\def\spac_align_set_horizontal_left
333  {\setraggedness    \spac_align_set_raggedness_left
334   \raggedstatus     \plusone
335   \raggedhangstatus \zerocount
336   \c_attr_alignstate\plusone
337   \leftskip         \plusone\leftskip \s!plus\spac_align_set_raggedness_left
338   \rightskip        \plusone\rightskip\s!plus\zeropoint
339   \spaceskip        \v_spac_align_space_amount
340   \xspaceskip       \v_spac_align_space_amount_x
341   \parinitleftskip  \zeroskip
342   \parinitrightskip \zeroskip
343 % \parfillleftskip  \zeroskip
344 % \parfillrightskip \s_zero_plus_zero
345 % needs testing:
346   \parfillleftskip  \s_zero_plus_one_fil
347   \parfillrightskip \zeroskip
348   \parindent        \zeropoint
349   \relax}
350
351\permanent\protected\def\spac_align_set_horizontal_center
352  {\setraggedness    \spac_align_set_raggedness_middle
353   \raggedstatus     \plustwo
354   \raggedhangstatus \zerocount
355   \c_attr_alignstate\plustwo
356   \leftskip         \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
357   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
358   \spaceskip        \v_spac_align_space_amount
359   \xspaceskip       \v_spac_align_space_amount_x
360   \parinitleftskip  \zeroskip
361   \parinitrightskip \zeroskip
362   \parfillleftskip  \zeroskip
363   \parfillrightskip \s_zero_plus_zero
364   \parindent        \zeropoint
365   \relax}
366
367\permanent\protected\def\spac_align_set_horizontal_right
368  {\setraggedness    \spac_align_set_raggedness_right
369   \raggedstatus     \plusthree
370   \raggedhangstatus \zerocount
371   \c_attr_alignstate\plusthree
372   \leftskip         \plusone\leftskip \s!plus\zeropoint
373   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_right
374   \spaceskip        \v_spac_align_space_amount
375   \xspaceskip       \v_spac_align_space_amount_x
376   \parinitleftskip  \zeroskip
377   \parinitrightskip \zeroskip
378   \parfillleftskip  \zeroskip
379   \parfillrightskip \s_zero_plus_one_fil
380  %\parindent        \parindent
381   \relax}
382
383\permanent\protected\def\spac_align_set_horizontal_very_left
384  {\raggedstatus     \plusone
385   \raggedhangstatus \zerocount
386   \c_attr_alignstate\plusone
387   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount
388   \rightskip        \plusone\rightskip\s!plus\zeropoint
389   \spaceskip        \v_spac_align_space_amount
390   \xspaceskip       \v_spac_align_space_amount_x
391   \parinitleftskip  \zeroskip
392   \parinitrightskip \zeroskip
393 % \parfillleftskip  \zeroskip
394 % \parfillrightskip \s_zero_plus_zero
395 % needs testing:
396   \parfillleftskip  \s_zero_plus_zero
397   \parfillrightskip \zeroskip
398   \parindent        \zeropoint
399   \relax}
400
401\permanent\protected\def\spac_align_set_horizontal_very_center
402  {\raggedstatus     \plustwo
403   \raggedhangstatus \zerocount
404   \c_attr_alignstate\plustwo
405   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount
406   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount
407   \spaceskip        \v_spac_align_space_amount
408   \xspaceskip       \v_spac_align_space_amount_x
409   \parinitleftskip  \zeroskip
410   \parinitrightskip \zeroskip
411   \parfillleftskip  \zeroskip
412   \parfillrightskip \s_zero_plus_zero
413   \parindent        \zeropoint
414   \relax}
415
416\permanent\protected\def\spac_align_set_horizontal_very_right
417  {\raggedstatus     \plusthree
418   \raggedhangstatus \zerocount
419   \c_attr_alignstate\plusthree
420   \leftskip         \plusone\leftskip \s!plus\zeropoint
421   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount
422   \spaceskip        \v_spac_align_space_amount
423   \xspaceskip       \v_spac_align_space_amount_x
424   \parinitleftskip  \zeroskip
425   \parinitrightskip \zeroskip
426   \parfillleftskip  \zeroskip
427   \parfillrightskip \s_zero_plus_zero
428  %\parindent        \parindent
429   \relax}
430
431\permanent\protected\def\spac_align_set_horizontal_wide_center
432  {\setraggedness    \spac_align_set_raggedness_middle
433   \raggedstatus     \plustwo
434   \raggedhangstatus \zerocount
435   \c_attr_alignstate\plustwo
436   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount_half
437   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount_half
438   \spaceskip        \v_spac_align_space_amount
439   \xspaceskip       \v_spac_align_space_amount_x
440   \parinitleftskip  \zeroskip
441   \parinitrightskip \zeroskip
442   \parfillleftskip  \zeroskip
443   \parfillrightskip \s_zero_plus_zero
444   \parindent        \zeropoint
445   \relax}
446
447\permanent\protected\def\spac_align_set_horizontal_centered_last_line
448  {\raggedstatus     \zerocount
449   \raggedhangstatus \zerocount
450   \c_attr_alignstate\attributeunsetvalue
451   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
452   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
453   \spaceskip        \zeroskip
454   \xspaceskip       \zeroskip
455   \parinitleftskip  \zeroskip
456   \parinitrightskip \zeroskip
457   \parfillleftskip  \zeroskip
458   \parfillrightskip \zeropoint\s!plus\v_spac_align_fill_amount_double\relax
459   \parindent        \zeropoint
460   \relax}
461
462\permanent\protected\def\spac_align_set_horizontal_flushedright_last_line
463  {\raggedstatus     \zerocount
464   \raggedhangstatus \zerocount
465   \c_attr_alignstate\attributeunsetvalue
466   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
467   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
468   \spaceskip        \zeroskip
469   \xspaceskip       \zeroskip
470   \parinitleftskip  \zeroskip
471   \parinitrightskip \zeroskip
472   \parfillleftskip  \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
473   \parfillrightskip \zeroskip
474   \parindent        \zeropoint
475   \relax}
476
477\permanent\protected\def\spac_align_set_horizontal_right_tt % a plain command
478  {\tttf % brrr
479   \raggedstatus     \plusthree
480   \raggedhangstatus \zerocount
481   \c_attr_alignstate\plusthree
482   \leftskip         \plusone\leftskip \s!plus\zeropoint\relax
483   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_right\relax
484   \spaceskip        \zeroskip
485   \xspaceskip       \zeroskip
486   \parinitleftskip  \zeroskip
487   \parinitrightskip \zeroskip
488   \parfillleftskip  \zeroskip
489   \parfillrightskip \s_zero_plus_zero
490  %\parindent        \parindent
491   \relax}
492
493\permanent\protected\def\spac_align_set_horizontal_slanted
494  {\raggedstatus     \zerocount
495   \raggedhangstatus \zerocount
496  %\c_attr_alignstate\attributeunsetvalue
497   \c_attr_alignstate\plustwo
498   \leftskip         \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
499   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
500   \spaceskip        \zeroskip
501   \xspaceskip       \zeroskip
502   \parinitleftskip  \zeroskip
503   \parinitrightskip \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
504   \parfillleftskip  \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
505   \parfillrightskip \zeroskip
506   \parindent        \zeropoint
507   \relax}
508
509\permanent\protected\def\spac_align_set_horizontal_extra
510  {\xspaceskip\zeropoint\s!plus\v_spac_align_fill_amount_space\relax}
511
512\def\spac_align_flush_horizontal
513  {\ifcase\c_spac_align_state_horizontal
514     % 0
515     \spac_align_set_horizontal_none
516   \or
517     % 1 center
518     \ifcase\c_spac_align_state_broad
519       \spac_align_set_horizontal_center
520     \or
521       \spac_align_set_horizontal_very_center
522     \or
523       \spac_align_set_horizontal_wide_center
524     \fi
525   \or
526     % 2 flush left
527     \ifcase\c_spac_align_state_broad
528       \ifcase\c_spac_align_state_tight
529         \spac_align_set_horizontal_right
530       \else
531         \spac_align_set_horizontal_center
532         \leftskip1\leftskip
533       \fi
534     \else
535       \spac_align_set_horizontal_very_right
536     \fi
537   \or
538     % 3 flush right
539     \ifcase\c_spac_align_state_broad
540       \ifcase\c_spac_align_state_tight
541         \spac_align_set_horizontal_left
542       \else
543         \spac_align_set_horizontal_center
544         \rightskip1\rightskip
545       \fi
546     \else
547       \spac_align_set_horizontal_very_left
548     \fi
549   \or
550     % 4 inner
551     \ifdoublesided
552       \signalinnerrealign
553     \fi
554     \rightorleftpageaction\spac_align_set_horizontal_right\spac_align_set_horizontal_left
555   \or
556     % 5 outer
557     \ifdoublesided
558       \signalouterrealign
559     \fi
560     \rightorleftpageaction\spac_align_set_horizontal_left\spac_align_set_horizontal_right
561   \or
562     % 6 oneliner
563     \ifcase\c_spac_align_state_broad
564       \spac_align_set_horizontal_right
565     \else
566       \spac_align_set_horizontal_very_right
567     \fi
568    %\parfillleftskip \zeroskip
569     \parfillrightskip\zeroskip
570   \or
571     % 7 centered last line
572     \spac_align_set_horizontal_centered_last_line
573   \or
574     % 8 right aligned last line
575     \spac_align_set_horizontal_flushedright_last_line
576   \or
577     % 9 paragraph
578    %\parfillleftskip \zeroskip
579     \parfillrightskip\zeroskip
580   \or
581     % 10 slanted
582     \spac_align_set_horizontal_slanted
583   \or
584     % 11 hangleft
585     \spac_align_set_horizontal_hang_left
586   \or
587     % 12 hangright
588     \spac_align_set_horizontal_hang_right
589   \or
590     % 13 hangleft range, private
591     \spac_align_set_horizontal_hang_left_range
592   \or
593     % 14 hangright range, private
594     \spac_align_set_horizontal_hang_right_range
595   \fi
596   \relax}
597
598% Page spacing:
599
600\newconstant\c_spac_align_state_page
601
602% \mutable\def\bottomalignlimit{\plusthree\lineheight}
603
604\newconstant\bottomraggednessmode % 0=ragged 1=normal/align 2=baseline 3=depth 4=weird-line
605
606\permanent\protected\def\raggedbottom
607  {\bottomraggednessmode\zerocount
608   \settopskip}
609
610\permanent\protected\def\alignbottom
611  {\bottomraggednessmode\plusone
612   \settopskip}
613
614\permanent\protected\def\baselinebottom
615  {\bottomraggednessmode\plustwo
616   \settopskip}
617
618\permanent\protected\def\depthlinebottom
619  {\bottomraggednessmode\plusthree
620   \settopskip}
621
622\aliased\let\normalbottom\alignbottom % downward compatible
623
624\permanent\protected\def\setbottomalignmode#1%
625  {\bottomraggednessmode#1%
626   \settopskip}
627
628\def\spac_align_flush_page
629  {\ifcase\c_spac_align_state_page
630     % keep state
631   \or
632     \raggedbottom
633   \or
634     \alignbottom
635   \or
636     \baselinebottom
637   \or
638     \depthlinebottom
639   \fi}
640
641% Directions
642
643\newconstant\c_spac_align_state_direction
644
645\def\spac_align_flush_direction
646  {\ifcase\c_spac_align_state_direction
647    % keep state
648   \or
649     \lefttoright
650   \or
651     \righttoleft
652   \fi}
653
654% Trick
655
656%D \starttyping
657%D \framed[width=5.5cm,align={flushleft}]       {This is a test sentence to see if it aligns okay.}
658%D \framed[width=5.5cm,align={flushright}]      {This is a test sentence to see if it aligns okay.}
659%D \framed[width=5.5cm,align={flushleft,tight}] {This is a test sentence to see if it aligns okay.}
660%D \framed[width=5.5cm,align={flushright,tight}]{This is a test sentence to see if it aligns okay.}
661%D \framed[width=5.5cm,align={flushleft,broad}] {This is a test sentence to see if it aligns okay.}
662%D \framed[width=5.5cm,align={flushright,broad}]{This is a test sentence to see if it aligns okay.}
663%D \stoptyping
664
665\newconstant\c_spac_align_state_tight
666
667% Interesting is that the non cached version is also pretty efficient
668% and as we cache we seldom call that one now so one can debate the
669% speedup.
670
671\newtoks\t_spac_align_collected
672\newtoks\t_spac_align_applied
673\newtoks\t_spac_align_presets
674
675\aliased\let\raggedcommand    \relax
676\aliased\let\updateraggedskips\relax
677
678\def\spac_align_add_to_cache
679  {\enforced\let\raggedbox\relax % why
680   % we inherit hyphenation and tolerance
681   \expand\t_spac_align_presets
682%    \lastlinefit\zerocount
683   \ifcsname\??aligncommand\m_spac_align_named\endcsname
684     \lastnamedcs
685   \else
686     \rawprocesscommacommand[\m_spac_align_asked]\spac_align_collect
687   \fi
688   \etoks\t_spac_align_collected
689     {\raggedonelinerstate\conditionalfalse % bad
690      \expand\t_spac_align_collected
691      \expand\t_spac_align_applied}%
692   \enforced\permanent\protected\edef\raggedcommand    {\expand\t_spac_align_collected}%
693   \enforced\permanent\protected\edef\updateraggedskips{\spac_align_flush_horizontal}%
694   \enforced\aliased\gletcsname\??alignmentnormalcache\m_spac_align_named\endcsname\raggedcommand
695   \enforced\aliased\gletcsname\??alignmentraggedcache\m_spac_align_named\endcsname\updateraggedskips}
696
697\appendtoks
698  \spac_align_flush_horizontal
699  \spac_align_flush_vertical
700  \spac_align_flush_direction
701  \spac_align_flush_page
702  \spac_align_flush_parfill
703\to \t_spac_align_applied
704
705\appendtoks
706   \t_spac_align_collected       \emptytoks
707   \c_spac_align_state_broad     \zerocount
708   \c_spac_align_state_horizontal\zerocount
709   \c_spac_align_state_vertical  \zerocount
710   \c_spac_align_state_spread    \zerocount
711   \c_spac_align_state_direction \zerocount % what is default ?
712   \c_spac_align_state_tight     \zerocount
713   \c_spac_align_state_page      \zerocount
714   \c_spac_align_state_par_fill  \zerocount
715\to \t_spac_align_presets
716
717\mutable\def\m_spac_align_named{\m_spac_align_asked}
718
719\def\spac_align_collect#1%
720  {\csname\??aligncommand#1\endcsname}
721
722\permanent\protected\tolerant\def\definealign[#1]#*[#2]%
723  {\pushmacro\raggedcommand
724   \pushmacro\updateraggedskips
725   \edef\m_spac_align_named{#1}%
726   \edef\m_spac_align_asked{#2}%
727   \spac_align_add_to_cache
728   \popmacro\updateraggedskips
729   \popmacro\raggedcommand}
730
731% The local (key driven) setter:
732
733\permanent\protected\def\spac_align_prepare#1% deferred
734  {\edef\m_spac_align_asked{#1}%
735   \enforced\aliased\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
736   \ifrelax\raggedcommand
737     \spac_align_add_to_cache
738   \else
739     \enforced\aliased\expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
740   \fi}
741
742\aliased\let\dosetraggedcommand\spac_align_prepare % sort of public
743
744% The regular align setter:
745
746\permanent\tolerant\protected\def\setupalign[#1]% immediate
747  {\edef\m_spac_align_asked{#1}%
748   \enforced\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
749   \ifrelax\raggedcommand
750     \spac_align_add_to_cache
751   \else
752     \enforced\aliased\expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
753   \fi
754   \raggedcommand}
755
756\permanent\protected\def\usealignparameter#1% faster local variant
757  {\edef\m_spac_align_asked{#1\c!align}%
758   \ifempty\m_spac_align_asked\else
759     \spac_align_use_indeed
760   \fi}
761
762\permanent\protected\def\dousealignparameter#1% faster local variant
763  {\edef\m_spac_align_asked{#1}%
764   \ifempty\m_spac_align_asked\else
765     \spac_align_use_indeed
766   \fi}
767
768\def\spac_align_use_indeed
769  {\enforced\aliased\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
770   \ifrelax\raggedcommand
771     \spac_align_add_to_cache
772   \else
773     \enforced\aliased\expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
774   \fi
775   \raggedcommand}
776
777% experiment
778
779\protected\def\spac_align_use_later#1%
780  {\begingroup
781   \edef\m_spac_align_asked{#1}%
782   \enforced\aliased\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
783   \ifrelax\raggedcommand
784     \spac_align_add_to_cache
785   \fi
786   \endgroup}
787
788\protected\def\spac_align_use_now#1%
789  {\csname\??alignmentnormalcache#1\endcsname}
790
791% Maybe we need something different in columns.
792
793\permanent\protected\def\installalign#1#2% beware: commands must be unexpandable!
794  {\ifcsname\??aligncommand#1\endcsname \else  % : so maybe we should use \etoksapp
795     \defcsname\??aligncommand#1\endcsname{\toksapp\t_spac_align_collected{#2}}%
796   \fi}
797
798% The keywords:
799
800\letcsname\??aligncommand\empty            \endcsname\empty
801\defcsname\??aligncommand\v!broad          \endcsname{\c_spac_align_state_broad     \plusone  }
802\defcsname\??aligncommand\v!wide           \endcsname{\c_spac_align_state_broad     \plustwo  }
803
804\defcsname\??aligncommand\v!bottom         \endcsname{\c_spac_align_state_page      \plusone  }
805\defcsname\??aligncommand\v!height         \endcsname{\c_spac_align_state_page      \plustwo  }
806\defcsname\??aligncommand\v!depth          \endcsname{\c_spac_align_state_page      \plusfour }
807\defcsname\??aligncommand\v!line           \endcsname{\c_spac_align_state_page      \plusthree
808                                                      % this will become another keyword (undocumented anyway)
809                                                      \toksapp\t_spac_align_collected{\raggedonelinerstate\conditionaltrue}}
810
811\defcsname\??aligncommand\v!high           \endcsname{\c_spac_align_state_vertical  \plusthree}
812\defcsname\??aligncommand\v!low            \endcsname{\c_spac_align_state_vertical  \plustwo  }
813\defcsname\??aligncommand\v!lohi           \endcsname{\c_spac_align_state_vertical  \plusone  }
814
815\defcsname\??aligncommand\v!spread         \endcsname{\c_spac_align_state_spread    \plusone  }
816
817\defcsname\??aligncommand\v!flushright     \endcsname{\c_spac_align_state_horizontal\plusthree}
818\defcsname\??aligncommand\v!flushleft      \endcsname{\c_spac_align_state_horizontal\plustwo  }
819\defcsname\??aligncommand\v!middle         \endcsname{\c_spac_align_state_horizontal\plusone  }
820\defcsname\??aligncommand\v!no             \endcsname{\c_spac_align_state_horizontal\plustwo  }
821\defcsname\??aligncommand\v!yes            \endcsname{\c_spac_align_state_horizontal\zerocount}
822\defcsname\??aligncommand\v!width          \endcsname{\c_spac_align_state_horizontal\zerocount}
823\defcsname\??aligncommand\v!normal         \endcsname{\c_spac_align_state_horizontal\zerocount}
824\defcsname\??aligncommand\v!reset          \endcsname{\c_spac_align_state_page      \zerocount
825                                                      \c_spac_align_state_horizontal\zerocount}
826\defcsname\??aligncommand\v!inner          \endcsname{\c_spac_align_state_horizontal\plusfour }
827\defcsname\??aligncommand\v!outer          \endcsname{\c_spac_align_state_horizontal\plusfive }
828\defcsname\??aligncommand\v!flushinner     \endcsname{\c_spac_align_state_horizontal\plusfour }
829\defcsname\??aligncommand\v!flushouter     \endcsname{\c_spac_align_state_horizontal\plusfive }
830\defcsname\??aligncommand\v!right          \endcsname{\c_spac_align_state_horizontal\plustwo  }
831\defcsname\??aligncommand\v!left           \endcsname{\c_spac_align_state_horizontal\plusthree}
832\defcsname\??aligncommand\v!center         \endcsname{\c_spac_align_state_horizontal\plusone
833                                                      \c_spac_align_state_broad     \plustwo  }
834\defcsname\??aligncommand\v!disable        \endcsname{\c_spac_align_state_horizontal\plussix  }
835\defcsname\??aligncommand\v!last           \endcsname{\c_spac_align_state_horizontal\plusseven}
836\defcsname\??aligncommand\v!end            \endcsname{\c_spac_align_state_horizontal\pluseight}
837\defcsname\??aligncommand\v!paragraph      \endcsname{\c_spac_align_state_horizontal\plusnine}
838
839\defcsname\??aligncommand\v!lefttoright    \endcsname{\c_spac_align_state_direction \plusone  }
840\defcsname\??aligncommand\v!righttoleft    \endcsname{\c_spac_align_state_direction \plustwo  }
841\defcsname\??aligncommand               l2r\endcsname{\c_spac_align_state_direction \plusone  }
842\defcsname\??aligncommand               r2l\endcsname{\c_spac_align_state_direction \plustwo  }
843
844\defcsname\??aligncommand\v!tight          \endcsname{\c_spac_align_state_tight     \plusone}
845
846\defcsname\??aligncommand\v!slanted        \endcsname{\c_spac_align_state_horizontal\plusten
847                                                      \c_spac_align_state_broad     \plustwo  }
848
849
850\defcsname\??aligncommand\v!table          \endcsname{\c_spac_align_state_vertical  \plusthree
851                                                      \c_spac_align_state_broad     \plusone
852                                                      \c_spac_align_state_horizontal\plustwo  }
853
854\defcsname\??aligncommand\v!lesshyphenation\endcsname{\toksapp\t_spac_align_collected{\lesshyphens}}
855\defcsname\??aligncommand\v!morehyphenation\endcsname{\toksapp\t_spac_align_collected{\morehyphens}}
856
857\defcsname\??aligncommand\v!hanging        \endcsname{\toksapp\t_spac_align_collected{\font_protruding_enable }}
858\defcsname\??aligncommand\v!hangingboth    \endcsname{\toksapp\t_spac_align_collected{\font_protruding_enable_b}}
859\defcsname\??aligncommand\v!nothanging     \endcsname{\toksapp\t_spac_align_collected{\font_protruding_disable}}
860\defcsname\??aligncommand\v!hz             \endcsname{\toksapp\t_spac_align_collected{\font_expansion_enable  }}
861\defcsname\??aligncommand\v!fullhz         \endcsname{\toksapp\t_spac_align_collected{\font_expansion_enable_k}}
862\defcsname\??aligncommand\v!nohz           \endcsname{\toksapp\t_spac_align_collected{\font_expansion_disable }}
863%defcsname\??aligncommand\v!spacing        \endcsname{\toksapp\t_spac_align_collected{\normalspacing\zerocount}} % not yet
864%defcsname\??aligncommand\v!nospacing      \endcsname{\toksapp\t_spac_align_collected{\normalspacing\plusone}}   % not yet
865\defcsname\??aligncommand\v!hyphenated     \endcsname{\toksapp\t_spac_align_collected{\dohyphens}}
866\defcsname\??aligncommand\v!nothyphenated  \endcsname{\toksapp\t_spac_align_collected{\nohyphens}}
867\defcsname\??aligncommand\v!collapsed      \endcsname{\toksapp\t_spac_align_collected{\dohyphencollapsing}}
868\defcsname\??aligncommand\v!notcollapsed   \endcsname{\toksapp\t_spac_align_collected{\nohyphencollapsing}}
869\defcsname\??aligncommand\v!explicit       \endcsname{\toksapp\t_spac_align_collected{\nohyphens\doexplicithyphens}}
870
871\defcsname\??aligncommand\v!tolerant       \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_tolerant}}
872\defcsname\??aligncommand\v!verytolerant   \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_very_tolerant}}
873\defcsname\??aligncommand\v!stretch        \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_stretch}}
874\defcsname\??aligncommand\v!extremestretch \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_extreme_stretch}}
875
876\defcsname\??aligncommand          \v!final\endcsname{\c_spac_align_state_par_fill\plusone}
877\defcsname\??aligncommand        1*\v!final\endcsname{\c_spac_align_state_par_fill\plusone}
878\defcsname\??aligncommand        2*\v!final\endcsname{\c_spac_align_state_par_fill\plustwo}      % hardcoded multiplier
879\defcsname\??aligncommand        3*\v!final\endcsname{\c_spac_align_state_par_fill\plusthree}
880\defcsname\??aligncommand        4*\v!final\endcsname{\c_spac_align_state_par_fill\plusfour}
881
882% a one shot (only usefull in e.g. framed, also needs tolerance and stretch)
883
884\defcsname\??aligncommand          \v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}}
885\defcsname\??aligncommand        1*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}}
886\defcsname\??aligncommand        2*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plustwo}}
887
888% for verbatim overflow
889
890\defcsname\??aligncommand\v!hangleft      \endcsname{\c_spac_align_state_horizontal\pluseleven}
891\defcsname\??aligncommand\v!hangright     \endcsname{\c_spac_align_state_horizontal\plustwelve}
892
893\permanent\protected\def\spac_align_set_horizontal_hang_right
894  {\spac_align_set_horizontal_very_left
895   \parinitrightskip\s_zero_plus_one_fill
896   \raggedhangstatus \plusone
897   \relax}
898
899\permanent\protected\def\spac_align_set_horizontal_hang_left
900  {\spac_align_set_horizontal_very_right
901   \parinitleftskip \s_zero_plus_one_fill
902   \raggedhangstatus \plustwo
903   \relax}
904
905% idem but better: experimental !
906
907\defcsname\??aligncommand\v!hangleft  range\endcsname{\c_spac_align_state_horizontal\plusthirteen}
908\defcsname\??aligncommand\v!hangright range\endcsname{\c_spac_align_state_horizontal\plusfourteen}
909
910\permanent\protected\def\spac_align_set_horizontal_hang_right_range % special purpose
911  {\spac_align_set_horizontal_very_left
912  %\rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_left
913   \rightskip        \plusone\rightskip\s!plus.5\hsize % if we change this then we need a *_right_range_tt variant
914   \parinitrightskip \s_zero_plus_one_fill
915   \parfillleftskip  \s_zero_plus_zero
916   \raggedhangstatus \plusthree
917   \relax}
918
919\permanent\protected\def\spac_align_set_horizontal_hang_left_range % special purpose
920  {\spac_align_set_horizontal_very_right
921  %\leftskip        \plusone\leftskip \s!plus\spac_align_set_raggedness_left %
922   \leftskip        \plusone\leftskip \s!plus.5\hsize % if we change this then we need a *_right_range_tt variant
923   \parinitleftskip \s_zero_plus_one_fill
924   \raggedhangstatus\plusfour
925   \relax}
926
927\newconditional\c_spac_align_hang_done
928
929\permanent\protected\def\starthangrange
930  {\c_spac_align_hang_done\conditionalfalse}
931
932\permanent\protected\def\stophangrange
933  {\c_spac_align_hang_done\conditionalfalse
934   \removeunwantedspaces
935  %\localbreakpar
936   \par}
937
938\permanent\protected\def\starthangrangestep
939  {\ifconditional\c_spac_align_hang_done
940     \removeunwantedspaces
941   % \hfillneg
942   % \strut
943   % \parbreak
944     \localbreakpar
945   \fi
946   \ifnum\raggedhangstatus=\plusthree
947     \ifhmode
948       \strut
949       \penalty\plustenthousand
950       \hskip-\leftskip
951       \penalty\plustenthousand
952     \else
953       \spac_align_set_horizontal_hang_right_range
954       \dontleavehmode
955     \fi
956   \orelse\ifnum\raggedhangstatus=\plusfour
957     \ifhmode
958       \strut
959       \hfill
960     \else
961       \spac_align_set_horizontal_hang_left_range
962       \dontleavehmode
963     \fi
964   \fi
965  %\luaboundary 123 456
966   \ignorespaces}
967
968\permanent\protected\def\stophangrangestep
969  {\par\c_spac_align_hang_done\conditionaltrue} % par is needed
970
971\permanent\protected\def\emptyhangrangestep
972  {\strut\localbreakpar}
973
974% experiment
975
976\defcsname\??aligncommand\v!flushforward \endcsname{\c_spac_align_state_horizontal\ifconditional\inlinelefttoright\plustwo\else\plusthree\fi}
977\defcsname\??aligncommand\v!flushbackward\endcsname{\c_spac_align_state_horizontal\ifconditional\inlinelefttoright\plusthree\else\plustwo\fi}
978
979% experiment
980
981\defcsname\??aligncommand\v!always\endcsname{\toksapp\t_spac_align_collected{\bitwiseflip\hyphenationmode\forcecheckhyphenationcode}}
982
983% experiment
984
985\defcsname\??aligncommand\v!profile\endcsname{\toksapp\t_spac_align_collected{\setmainlineprofile}}
986
987% lastlinefit
988
989\newconstant\c_spac_align_state_fit
990
991\defcsname\??aligncommand\v!fit\endcsname
992  {\c_spac_align_state_fit\plusone}
993
994\appendtoks
995   \c_spac_align_state_fit\zerocount
996\to \t_spac_align_presets
997
998\appendtoks
999   \lastlinefit\ifcase\c_spac_align_state_fit\zerocount\else\plusthousand\fi
1000\to \t_spac_align_applied
1001
1002\immutable\integerdef\defaultdoublehyphendemerits\plustenthousand
1003\immutable\integerdef\defaultfinalhyphendemerits \plusfivethousand
1004\immutable\integerdef\defaultadjdemerits         \plustenthousand
1005\immutable\integerdef\defaultorphanpenalty       \plusfifty
1006\immutable\integerdef\defaulttoddlerpenalty      \plusfifty
1007\immutable\integerdef\defaultlefttwindemerits    \plusseventyfivehundred
1008\immutable\integerdef\defaultrighttwindemerits   \plusseventyfivehundred
1009
1010\immutable\integerdef\granularadjdemerits        \plusfivethousand % see accumulation in granular
1011
1012\frozen\doublehyphendemerits \defaultdoublehyphendemerits
1013\frozen\finalhyphendemerits  \defaultfinalhyphendemerits
1014\frozen\adjdemerits          \defaultadjdemerits
1015
1016\frozen\orphanpenalty        \zerocount
1017\frozen\toddlerpenalty       \zerocount
1018\frozen\lefttwindemerits     \zerocount
1019\frozen\righttwindemerits    \zerocount
1020
1021\permanent\protected\def\noorphans   {\orphanpenalty    \defaultorphanpenalty}
1022\permanent\protected\def\notoddlers  {\toddlerpenalty   \defaulttoddlerpenalty}
1023\permanent\protected\def\notwins     {\lefttwindemerits \defaultlefttwindemerits
1024                                      \righttwindemerits\defaultrighttwindemerits}
1025
1026\permanent\protected\def\keeporphans {\orphanpenalty    \zerocount}
1027\permanent\protected\def\keeptoddlers{\toddlerpenalty   \zerocount}
1028\permanent\protected\def\keeptwins   {\lefttwindemerits \zerocount
1029                                      \righttwindemerits\zerocount}
1030
1031% for now, not interfaced as these are experiments:
1032
1033    \immutable\def\s!noorphans   {noorphans}
1034    \immutable\def\s!keeporphans {keeporphans}
1035    \immutable\def\s!notwins     {notwins}
1036    \immutable\def\s!keeptwins   {keeptwins}
1037    \immutable\def\s!notoddlers  {notoddlers}
1038    \immutable\def\s!keeptoddlers{keeptoddlers}
1039
1040\defcsname\??aligncommand\s!noorphans   \endcsname{\toksapp\t_spac_align_collected{\noorphans}}
1041\defcsname\??aligncommand\s!keeporphans \endcsname{\toksapp\t_spac_align_collected{\keeporphans}}
1042\defcsname\??aligncommand\s!notwins     \endcsname{\toksapp\t_spac_align_collected{\notwins}}
1043\defcsname\??aligncommand\s!keeptwins   \endcsname{\toksapp\t_spac_align_collected{\keeptwins}}
1044\defcsname\??aligncommand\s!notoddlers  \endcsname{\toksapp\t_spac_align_collected{\notoddlers}}
1045\defcsname\??aligncommand\s!keeptoddlers\endcsname{\toksapp\t_spac_align_collected{\keeptoddlers}}
1046
1047\newconstant \matchallfitnessclasses \setconstant \matchallfitnessclasses "FF
1048
1049\appendtoks
1050    \fitnessclasses \zerocount
1051\to \t_spac_align_presets
1052
1053\permanent\protected\def\installaligncommand#1#2%
1054  {\defcsname\??aligncommand#1\endcsname{\appendtoks#2\to\t_spac_align_applied}}
1055
1056\aliased\let\stopinstallaligncommand\relax
1057
1058\permanent\protected\def\startinstallaligncommand[#1]#S#/\stopinstallaligncommand
1059  {\defcsname\??aligncommand#1\endcsname{\appendtoks#2\to\t_spac_align_applied}}
1060
1061\permanent \specificationdef \granularfitnessclasses \fitnessclasses \plusnine
1062    \plusninetynine
1063    \plusfourtytwo  % .75
1064    \plustwelve     % .50
1065    \plustwo        % .25
1066    \zerocount      % .00
1067    \plustwo        % .25
1068    \plustwelve     % .50
1069    \plusfourtytwo  % .75
1070    \plusninetynine
1071
1072% \permanent \specificationdef \defaultadjacentdemerits \adjacentdemerits \minusone \plustenthousand
1073
1074\permanent \specificationdef \granularadjacentdemerits \adjacentdemerits \pluseight
1075    \zerocount
1076    \plustwentyfivehundred
1077    \plusfivethousand
1078    \plusseventyfivehundred
1079    \plustenthousand
1080    \numexpr\plustenthousand+\plustwentyfivehundred \relax
1081    \numexpr\plustenthousand+\plusfivethousand      \relax
1082   %\numexpr\plustenthousand+\plusseventyfivehundred\relax
1083    \numexpr\plustenthousand+\plustenthousand       \relax
1084
1085\installaligncommand
1086  {\v!granular}
1087  {\granularfitnessclasses
1088   \granularadjacentdemerits}
1089
1090% end of definitions
1091
1092\definehspace [\v!final] [\emspaceamount]
1093
1094\def\spac_align_flush_parfill
1095  {\ifcase\c_spac_align_state_par_fill\else
1096     \spac_align_flush_parfill_indeed{\the\c_spac_align_state_par_fill}%
1097   \fi}
1098
1099\protected\def\spac_align_flush_parfill_indeed#1%
1100  {\parfillrightskip
1101     #1\directhspaceamount\v!final
1102   % plus \dimexpr\availablehsize-#1\directhspaceamount\v!final\relax
1103     plus 1fill
1104   \relax}
1105
1106%D For Wolfgang:
1107
1108\newtoks \t_spac_every_swap_align
1109
1110\appendtoks
1111    \defcsname\??aligncommand\v!right\endcsname{\c_spac_align_state_horizontal\plusthree}%
1112    \defcsname\??aligncommand\v!left \endcsname{\c_spac_align_state_horizontal\plustwo  }%
1113\to \t_spac_every_swap_align
1114
1115\permanent\protected\def\enablereversealignment
1116  {\expand\t_spac_every_swap_align
1117   \t_spac_every_swap_align\emptytoks}
1118
1119% Visible commands:
1120
1121\aliased\let\notragged           \spac_align_set_horizontal_none
1122\aliased\let\raggedleft          \spac_align_set_horizontal_left
1123\aliased\let\raggedcenter        \spac_align_set_horizontal_center
1124\aliased\let\raggedright         \spac_align_set_horizontal_right
1125\aliased\let\veryraggedleft      \spac_align_set_horizontal_very_left
1126\aliased\let\veryraggedcenter    \spac_align_set_horizontal_very_center
1127\aliased\let\veryraggedright     \spac_align_set_horizontal_very_right
1128\aliased\let\raggedwidecenter    \spac_align_set_horizontal_wide_center
1129\aliased\let\centeredlastline    \spac_align_set_horizontal_centered_last_line
1130\aliased\let\flushedrightlastline\spac_align_set_horizontal_flushedright_last_line
1131\aliased\let\ttraggedright       \spac_align_set_horizontal_right_tt            % a plain command
1132\aliased\let\forgetragged        \spac_align_set_horizontal_none
1133\aliased\let\raggedslanted       \spac_align_set_horizontal_slanted
1134
1135\appendtoks
1136    \spac_align_set_horizontal_none
1137\to \everyforgetall
1138
1139% Box commands.
1140
1141\permanent\protected\def\ibox
1142  {\vbox\bgroup
1143     \forgetall
1144     \enforced\let\\\endgraf
1145     \ifdoublesided\signalinnerrealign\fi
1146     \doifelserightpage\spac_align_set_horizontal_right\spac_align_set_horizontal_left
1147     \let\next}
1148
1149\permanent\protected\def\obox
1150  {\vbox\bgroup
1151     \forgetall
1152     \enforced\let\\\endgraf
1153     \ifdoublesided\signalouterrealign\fi
1154     \doifelserightpage\spac_align_set_horizontal_left\spac_align_set_horizontal_right
1155     \let\next}
1156
1157\let\raggedbox\relax
1158
1159\permanent\protected\def\dosetraggedvbox#1% can be more keys .. how about caching here (but seldom used)
1160  {\enforced\let\raggedbox\vbox
1161   \processcommacommand[#1]\spac_align_set_ragged_vbox}
1162
1163\permanent\protected\def\dosetraggedhbox#1% can be more keys .. how about caching here (but seldom used)
1164  {\enforced\let\raggedbox\hbox
1165   \processcommacommand[#1]\spac_align_set_ragged_hbox}
1166
1167\def\spac_align_set_ragged_vbox#1%
1168  {\ifcsname\??alignvertical#1\endcsname
1169     \lastnamedcs
1170     \quitcommalist
1171   \fi}
1172
1173\def\spac_align_set_ragged_hbox#1%
1174  {\ifcsname\??alignhorizontal#1\endcsname
1175     \lastnamedcs
1176     \quitcommalist
1177   \fi}
1178
1179\permanent\protected\def\spac_align_vertical_left      {\lbox}
1180\permanent\protected\def\spac_align_vertical_right     {\rbox}
1181\permanent\protected\def\spac_align_vertical_middle    {\cbox}
1182\permanent\protected\def\spac_align_vertical_inner     {\ibox}
1183\permanent\protected\def\spac_align_vertical_outer     {\obox}
1184\permanent\protected\def\spac_align_vertical_flushleft {\rbox}
1185\permanent\protected\def\spac_align_vertical_flushright{\lbox}
1186\permanent\protected\def\spac_align_vertical_center    {\cbox}
1187\permanent\protected\def\spac_align_vertical_no        {\vbox\bgroup\spac_align_set_horizontal_right\let\next=}
1188
1189\permanent\protected\def\spac_align_horizontal_left      {\doalignedline\v!left}
1190\permanent\protected\def\spac_align_horizontal_right     {\doalignedline\v!right}
1191\permanent\protected\def\spac_align_horizontal_middle    {\doalignedline\v!middle}
1192\permanent\protected\def\spac_align_horizontal_inner     {\doalignedline\v!inner}
1193\permanent\protected\def\spac_align_horizontal_outer     {\doalignedline\v!outer}
1194\permanent\protected\def\spac_align_horizontal_flushleft {\doalignedline\v!right}
1195\permanent\protected\def\spac_align_horizontal_flushright{\doalignedline\v!left}
1196\permanent\protected\def\spac_align_horizontal_center    {\doalignedline\v!middle}
1197
1198\defcsname\??alignvertical  \v!left      \endcsname{\enforced\let\raggedbox\spac_align_vertical_left}
1199\defcsname\??alignvertical  \v!right     \endcsname{\enforced\let\raggedbox\spac_align_vertical_right}
1200\defcsname\??alignvertical  \v!middle    \endcsname{\enforced\let\raggedbox\spac_align_vertical_middle}
1201\defcsname\??alignvertical  \v!inner     \endcsname{\enforced\let\raggedbox\spac_align_vertical_inner}
1202\defcsname\??alignvertical  \v!outer     \endcsname{\enforced\let\raggedbox\spac_align_vertical_outer}
1203\defcsname\??alignvertical  \v!flushleft \endcsname{\enforced\let\raggedbox\spac_align_vertical_flushleft }
1204\defcsname\??alignvertical  \v!flushright\endcsname{\enforced\let\raggedbox\spac_align_vertical_flushright}
1205\defcsname\??alignvertical  \v!center    \endcsname{\enforced\let\raggedbox\spac_align_vertical_center}
1206\defcsname\??alignvertical  \v!no        \endcsname{\enforced\let\raggedbox\spac_align_vertical_no}
1207
1208\defcsname\??alignhorizontal\v!left      \endcsname{\enforced\let\raggedbox\spac_align_horizontal_left}
1209\defcsname\??alignhorizontal\v!right     \endcsname{\enforced\let\raggedbox\spac_align_horizontal_right}
1210\defcsname\??alignhorizontal\v!middle    \endcsname{\enforced\let\raggedbox\spac_align_horizontal_middle}
1211\defcsname\??alignhorizontal\v!inner     \endcsname{\enforced\let\raggedbox\spac_align_horizontal_inner}
1212\defcsname\??alignhorizontal\v!outer     \endcsname{\enforced\let\raggedbox\spac_align_horizontal_outer}
1213\defcsname\??alignhorizontal\v!flushleft \endcsname{\enforced\let\raggedbox\spac_align_horizontal_flushleft}
1214\defcsname\??alignhorizontal\v!flushright\endcsname{\enforced\let\raggedbox\spac_align_horizontal_flushright}
1215\defcsname\??alignhorizontal\v!center    \endcsname{\enforced\let\raggedbox\spac_align_horizontal_center}
1216
1217% The next one can be in use so we keep it around but one should be aware of
1218% possible interference. But it will be removed at some point!
1219
1220\permanent\protected\def\setraggedskips#1#2#3#4#5#6#7% never change this name (todo: inline this one .. less tracingall)
1221  {\enforced\permanent\protected\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
1222   \updateraggedskips}
1223
1224\permanent\protected\def\dosetraggedskips#1#2#3#4#5#6#7%
1225  {\raggedstatus                 #1\relax
1226   \leftskip   1\leftskip \s!plus#2\relax
1227   \rightskip  1\rightskip\s!plus#3\relax
1228   \spaceskip                    #4\relax
1229   \xspaceskip                   #5\relax
1230   \parfillskip \zeropoint\s!plus#6\relax
1231   \parindent                    #7\relax
1232   \c_attr_alignstate\ifcase\raggedstatus\attributeunsetvalue\else\raggedstatus\fi}
1233
1234% older (context) names:
1235
1236\aliased\let\spaceamount  \interwordspace
1237\aliased\let\emspaceamount\emwidth
1238
1239% tracing:
1240
1241\def\spac_show_par_data#1%
1242  {\ifrelax#1\else
1243     \ifzero#1\else
1244       \hbox{\string#1: \the#1}\endgraf
1245     \fi
1246     \expandafter\spac_show_par_data
1247   \fi}
1248
1249\permanent\protected\def\showpardata
1250  {\normalexpanded{\dontleavehmode\inleftmargin{\vsmash{\infofont\framed[\c!align=\v!right]{%
1251     \hbox{font: \fontname\font}\endgraf
1252     \spac_show_par_data
1253       \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
1254       \hsize     \vsize
1255       \leftskip  \rightskip
1256       \spaceskip \xspaceskip
1257       \parindent \parfillleftskip \parinitrightskip \parinitleftskip \parfillrightskip
1258       \hyphenpenalty \exhyphenpenalty \automatichyphenpenalty \explicithyphenpenalty
1259     % \displaywidowpenalty
1260       \widowpenalty \clubpenalty \brokenpenalty
1261       \doublehyphendemerits \finalhyphendemerits \adjdemerits \orphanpenalty
1262       \toddlerpenalty \lefttwindemerits \righttwindemerits
1263     % \linebreakstretchcriterion \linebreakshrinkcriterion
1264   \relax}}}}}
1265
1266\permanent\protected\def\startshowpardata
1267  {\begingroup
1268   \showstruts
1269   \tracingparagraphs\maxdimen
1270   \enforced\let\startshowpardata\begingroup
1271   \toksapp\everypar{\showpardata}}
1272
1273\permanent\protected\def\stopshowpardata
1274  {\endgraf
1275   \endgroup}
1276
1277% Structure:
1278
1279\protected\def\startalignment
1280  {\par
1281   \begingroup
1282   \setupalign}
1283
1284\protected\def\stopalignment
1285  {\par
1286   \endgroup}
1287
1288\setnewconstant\alignstrutmode\plusone
1289
1290% see later for the real definition, which in the simple case is:
1291
1292\newtoks \everyleftofalignedline
1293\newtoks \everyrightofalignedline
1294
1295\permanent\protected\def\shiftalignedline#1#2#3#4% left, right, inner, outer
1296  {\rightorleftpageaction
1297     {\everyleftofalignedline {\hskip{#1+#3}}%
1298      \everyrightofalignedline{\hskip{#2+#4}}}
1299     {\everyleftofalignedline {\hskip{#1+#4}}%
1300      \everyrightofalignedline{\hskip{#2+#3}}}}
1301
1302\permanent\protected\def\doalignline#1#2% \\ == newline
1303  {\noindentation  % was \noindent
1304   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
1305   \begingroup
1306   \setlocalhsize % new
1307   \enforced\permanent\protected\def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
1308   \dowithnextbox
1309     {\hbox to \localhsize
1310        {\ifcase\alignstrutmode\or\strut\fi
1311         \expand\everyleftofalignedline
1312         #1\unhbox\nextbox#2\relax
1313         \expand\everyrightofalignedline}%
1314      \endgroup}
1315     \hbox}
1316
1317% plain commands
1318
1319\ifdefined\line       \else \permanent\protected\def\line        {\hbox to\hsize}    \fi
1320\ifdefined\leftline   \else \permanent\protected\def\leftline  #1{\line{#1\hss}}     \fi
1321\ifdefined\rightline  \else \permanent\protected\def\rightline #1{\line{\hss#1}}     \fi
1322\ifdefined\centerline \else \permanent\protected\def\centerline#1{\line{\hss#1\hss}} \fi
1323
1324% direct commands
1325
1326\installcorenamespace{alignwrapper}
1327
1328\protected\defcsname\??alignwrapper\v!left  \endcsname{\doalignline\relax \hss  }
1329\protected\defcsname\??alignwrapper\v!middle\endcsname{\doalignline\hss   \hss  }
1330\protected\defcsname\??alignwrapper\v!right \endcsname{\doalignline\hss   \relax}
1331\protected\defcsname\??alignwrapper\v!max   \endcsname{\doalignline\relax \relax}
1332
1333\def\spac_align_wrapper_middle{\doalignline\hss\hss}
1334
1335\def\spac_align_wrapper_handle#1%
1336  {\ifcsname\??alignwrapper#1\endcsname\expandafter\lastnamedcs\else\expandafter\spac_align_wrapper_middle\fi}
1337
1338\permanent\tolerant\protected\def\startlinealignment[#1]%
1339  {\spac_align_wrapper_handle{#1}%
1340   \bgroup\ignorespaces}
1341
1342\protected\def\spac_align_wrapper_stop
1343  {\removeunwantedspaces\egroup}
1344
1345\permanent\let\stoplinealignment\spac_align_wrapper_stop
1346
1347\permanent\protected\def\startleftaligned  {\startlinealignment[\v!left  ]}  \permanent\let\stopleftaligned  \spac_align_wrapper_stop
1348\permanent\protected\def\startmiddlealigned{\startlinealignment[\v!middle]}  \permanent\let\stopmiddlealigned\spac_align_wrapper_stop
1349\permanent\protected\def\startrightaligned {\startlinealignment[\v!right ]}  \permanent\let\stoprightaligned \spac_align_wrapper_stop
1350\permanent\protected\def\startmaxaligned   {\startlinealignment[\v!max   ]}  \permanent\let\stopmaxaligned   \spac_align_wrapper_stop
1351
1352\aliased\let\startmidaligned   \startmiddlealigned  \aliased\let\stopmidaligned   \stopmiddlealigned
1353\aliased\let\startcenteraligned\startmiddlealigned  \aliased\let\stopcenteraligned\stopmiddlealigned
1354
1355\permanent\protected\def\leftaligned  {\spac_align_wrapper_handle\v!left  }
1356\permanent\protected\def\middlealigned{\spac_align_wrapper_handle\v!middle}
1357\permanent\protected\def\rightaligned {\spac_align_wrapper_handle\v!right }
1358\permanent\protected\def\maxaligned   {\spac_align_wrapper_handle\v!max   }
1359
1360\aliased\let\midaligned   \middlealigned
1361\aliased\let\centeraligned\middlealigned
1362
1363\installcorenamespace{alignline}
1364
1365% Here left and flushleft as well as right and flushright are the same, as it's
1366% not used with % the aligh key.
1367
1368\letcsname\??alignline\v!left      \endcsname\leftaligned
1369\letcsname\??alignline\v!right     \endcsname\rightaligned
1370\letcsname\??alignline\v!middle    \endcsname\midaligned
1371\letcsname\??alignline\v!flushleft \endcsname\leftaligned  % beware, makes no sense in locations / we will have a special locations handler
1372\letcsname\??alignline\v!flushright\endcsname\rightaligned % beware, makes no sense in locations / we will have a special locations handler
1373\letcsname\??alignline\v!center    \endcsname\midaligned
1374\letcsname\??alignline\v!max       \endcsname\maxaligned
1375
1376%D Experimental (will be redone when floats are redone as it's real messy
1377%D now). It can also be made faster (if needed).
1378
1379\permanent\protected\def\doxalignline#1#2#3#4#5#6%
1380  {\noindentation  % was \noindent
1381   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
1382   \begingroup
1383   \setlocalhsize
1384   \enforced\permanent\protected\def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
1385   \dowithnextbox
1386     {\hbox to \localhsize
1387        {#1\hskip\ifdone#2\else#3\fi#4%
1388         \hbox to \localhsize
1389           {\expand\everyleftofalignedline
1390            \ifcase\alignstrutmode\or\strut\fi
1391            \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
1392            \expand\everyrightofalignedline}%
1393         \hss}%
1394        \endgroup}
1395     \hbox}
1396
1397\permanent\protected\def\doxcheckline % used for floats so multipass anyway
1398  {\signalrightpage\doifelserightpage\donetrue\donefalse}
1399
1400\defcsname\??alignline\v!inner      \endcsname{\doxalignline\doxcheckline++\zeropoint       \relax\hss  }
1401\defcsname\??alignline\v!outer      \endcsname{\doxalignline\doxcheckline++\zeropoint       \hss  \relax}
1402\defcsname\??alignline\v!innermargin\endcsname{\doxalignline\doxcheckline-+\innermargintotal\relax\hss  }
1403\defcsname\??alignline\v!outermargin\endcsname{\doxalignline\doxcheckline+-\outermargintotal\hss  \relax}
1404\defcsname\??alignline\v!inneredge  \endcsname{\doxalignline\doxcheckline-+\inneredgetotal  \relax\hss  }
1405\defcsname\??alignline\v!outeredge  \endcsname{\doxalignline\doxcheckline+-\outeredgetotal  \hss  \relax}
1406\defcsname\??alignline\v!backspace  \endcsname{\doxalignline\doxcheckline-+\backspace       \relax\hss  }
1407\defcsname\??alignline\v!cutspace   \endcsname{\doxalignline\doxcheckline+-\cutspace        \hss  \relax}
1408
1409\defcsname\??alignline\v!leftmargin \endcsname{\doxalignline\donefalse   --\leftmargintotal \hss  \relax}
1410\defcsname\??alignline\v!rightmargin\endcsname{\doxalignline\donefalse   ++\rightmargintotal\relax\hss  }
1411\defcsname\??alignline\v!leftedge   \endcsname{\doxalignline\donefalse   --\leftedgetotal   \hss  \relax}
1412\defcsname\??alignline\v!rightedge  \endcsname{\doxalignline\donefalse   ++\rightedgetotal  \relax\hss  }
1413
1414\permanent\protected\def\doalignedline#1{\begincsname\??alignline#1\endcsname}
1415
1416\permanent\protected\def\alignedline#1#2% setting default
1417  {\ifcsname\??alignline#1\endcsname
1418     \expandafter\lastnamedcs
1419   \else
1420     \csname\??alignline#2\expandafter\endcsname
1421   \fi}
1422
1423% beware: \wordright{whatever\kern-\rightskip} should work!
1424% so, no funny boxing here
1425
1426%D We need to pick up a box (downward compatible in case \type {\bgroup} is used
1427%D (test suite index example).
1428
1429\permanent\tolerant\protected\def\wordright[#1]%
1430  {\dowithnextbox
1431     {\normalexpanded{\spac_word_right_indeed{#1}{\hpack{\thebox\nextbox}}}}
1432     \hbox}
1433
1434\protected\def\spac_word_right_indeed#1#2%
1435  {\registerparwrapper
1436     {\v!word:\v!right}
1437     {\begingroup
1438      \frozen\parfillrightskip\zeroskip  % frozen ?
1439      \endgroup}
1440     {\doifelseparwrapper{\v!word:\v!right}{\unregisterparwrapper{\v!word:\v!right}}\donothing
1441      \removeunwantedspaces
1442      \ifcstok{#1}\v!right
1443        \kern-\rightskip
1444      \orelse\ifempty{#1}%
1445        % no kern
1446      \else
1447        \kern-#1%
1448      \fi
1449      \hfill
1450      \strut
1451      \kern\emwidth\strut\kern-\emwidth
1452      \nobreak
1453      \hfilll
1454      \quad
1455      #2}}
1456
1457% \dorecurse{5}{something} \wordright{--someone} \endgraf
1458% \dorecurse{6}{something} \wordright{--someone} \endgraf
1459% \dorecurse{7}{something} \wordright{--someone} \endgraf
1460%
1461% \dorecurse{5}{something} \wordright{--someone else entirely} \endgraf
1462% \dorecurse{6}{something} \wordright{--someone else entirely} \endgraf
1463% \dorecurse{7}{something} \wordright{--someone else entirely} \endgraf
1464%
1465% \wordright[\rightskip]{whatever}
1466
1467% Trick posted by WS on mailing list, generalized a bit. The bottom text only shows
1468% op when there is one line space available. We could add some extra space if needed.
1469
1470% v\protected\def\bottomword
1471%   {\par
1472%    \dowithnextbox
1473%      {\leaders\box\nextbox\vfil\page}
1474%      \vbox to \lineheight}
1475%
1476% \permanent\protected\def\bottomword
1477%   {\par
1478%    \groupedcommand
1479%      {\leaders
1480%       \vbox to \lineheight\bgroup}
1481%      {\egroup
1482%       \vfil
1483%       \page}}
1484
1485% \simplealignedbox{2cm}{right}{x}
1486
1487\installcorenamespace{alignsimple}
1488\installcorenamespace{alignsimplereverse}
1489
1490% todo: also handle \bgroup ... \egroup
1491
1492\protected\def\spac_align_simple_left  #1{{#1\hss}}
1493\protected\def\spac_align_simple_right #1{{\hss#1}}
1494\protected\def\spac_align_simple_middle#1{{\hss#1\hss}}
1495
1496\letcsname\??alignsimple       \v!right     \endcsname\spac_align_simple_left
1497\letcsname\??alignsimple       \v!outer     \endcsname\spac_align_simple_left   % not managed! see linenumbers
1498\letcsname\??alignsimple       \v!flushleft \endcsname\spac_align_simple_left
1499\letcsname\??alignsimple       \v!left      \endcsname\spac_align_simple_right
1500\letcsname\??alignsimple       \v!inner     \endcsname\spac_align_simple_right  % not managed! see linenumbers
1501\letcsname\??alignsimple       \v!flushright\endcsname\spac_align_simple_right
1502\letcsname\??alignsimple       \v!middle    \endcsname\spac_align_simple_middle
1503
1504\letcsname\??alignsimplereverse\v!right     \endcsname\spac_align_simple_right
1505\letcsname\??alignsimplereverse\v!outer     \endcsname\spac_align_simple_right % not managed! see linenumbers
1506\letcsname\??alignsimplereverse\v!flushleft \endcsname\spac_align_simple_right
1507\letcsname\??alignsimplereverse\v!left      \endcsname\spac_align_simple_left
1508\letcsname\??alignsimplereverse\v!inner     \endcsname\spac_align_simple_left  % not managed! see linenumbers
1509\letcsname\??alignsimplereverse\v!flushright\endcsname\spac_align_simple_left
1510\letcsname\??alignsimplereverse\v!middle    \endcsname\spac_align_simple_middle
1511
1512\protected\def\spac_align_simple#1%
1513  {\begincsname\??alignsimple#1\endcsname}
1514
1515\permanent\protected\def\simplealignedbox#1#2%
1516  {\hbox \ifdim#1>\zeropoint to #1
1517     \ifcsname\??alignsimple#2\endcsname
1518       \doubleexpandafter\lastnamedcs
1519     \else
1520       \doubleexpandafter\spac_align_simple_left
1521     \fi
1522   \fi}
1523
1524\permanent\protected\def\simplealignedspreadbox#1#2%
1525  {\hbox \ifdim#1>\zeropoint spread #1
1526     \ifcsname\??alignsimple#2\endcsname
1527       \doubleexpandafter\lastnamedcs
1528     \else
1529       \doubleexpandafter\spac_align_simple_left
1530     \fi
1531   \fi}
1532
1533\permanent\protected\def\simplealignedboxplus#1#2#3%
1534  {\hbox #3 \ifdim#1>\zeropoint to #1
1535     \ifcsname\??alignsimple#2\endcsname
1536       \doubleexpandafter\lastnamedcs
1537     \else
1538       \doubleexpandafter\spac_align_simple_left
1539     \fi
1540   \fi}
1541
1542\newconditional\alignsimplelefttoright \alignsimplelefttoright\conditionaltrue
1543
1544\permanent\protected\def\simplereversealignedbox#1#2%
1545  {\hbox \ifdim#1>\zeropoint to #1
1546     \ifcsname\??alignsimplereverse#2\endcsname
1547       \doubleexpandafter\lastnamedcs
1548     \else
1549       \doubleexpandafter\spac_align_simple_left
1550     \fi
1551   \fi}
1552
1553\permanent\protected\def\simplereversealignedboxplus#1#2#3%
1554  {\hbox #3 \ifdim#1>\zeropoint to #1
1555     \ifcsname\??alignsimplereverse#2\endcsname
1556       \doubleexpandafter\lastnamedcs
1557     \else
1558       \doubleexpandafter\spac_align_simple_left
1559     \fi
1560   \fi}
1561
1562% Some obsolete (old) helpers:
1563
1564\permanent\tolerant\protected\def\definehbox[#1]#*[#2]%
1565  {\ifarguments\else\frozen\instance\protected\defcsname hbox#1\endcsname##1{\hbox to #2{\begstrut##1\endstrut\hss}}\fi}
1566
1567%D Some direction related helpers:
1568
1569\installcorenamespace {reverse}
1570
1571\defcsname\??reverse\v!normal \endcsname{\ifconditional\inlinelefttoright\else\s!reverse\fi}
1572\defcsname\??reverse\v!reverse\endcsname{\ifconditional\inlinelefttoright     \s!reverse\fi}
1573
1574\permanent\def\usedirectionparameterreverse#1{\begincsname\??reverse#1\c!direction\endcsname}
1575
1576%D Now official:
1577
1578\permanent\protected\def\spaceorpar{\endgraf\ifhmode\space\fi}
1579
1580%D Kind of documenting:
1581%D
1582%D \starttyping
1583%D \disabletrackers[builders.hpack.quality] % enabled by default
1584%D \enabletrackers[builders.hpack.collect]
1585%D \enabletrackers[builders.hpack.overflow]
1586%D
1587%D \starttext
1588%D     {\hsize 4cm \input tufte \par} \page
1589%D     {\hsize 8cm \input tufte \par} \page
1590%D \stoptext
1591%D \stoptyping
1592
1593\protect \endinput
1594