spac-ali.mkxl /size: 56 Kb    last modification: 2024-01-16 09: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
296\newconstant\c_spac_align_state_horizontal
297\newconstant\c_spac_align_state_broad
298\newconstant\c_spac_align_state_par_fill
299
300\def\v_spac_align_fill_amount          {\plusone  fil}
301\def\v_spac_align_fill_amount_hard     {\plusone fill}
302\def\v_spac_align_fill_amount_extreme  {\plustenthousand  filll}
303\def\v_spac_align_fill_amount_negative {\minusone fil}
304\def\v_spac_align_fill_amount_double   {\plustwo  fil}
305\def\v_spac_align_fill_amount_space    {\plustwo  fil} % can be added to xspace if we have a key
306\def\v_spac_align_fill_amount_half             {.5fil}
307\let\v_spac_align_space_amount        \interwordspace
308\def\v_spac_align_space_amount_x          {.5\emwidth}
309
310\newgluespec\s_zero_plus_one_fil  \s_zero_plus_one_fil  = 0pt plus 1fil
311\newgluespec\s_zero_plus_one_fill \s_zero_plus_one_fill = 0pt plus 1fill
312\newgluespec\s_zero_plus_zero     \s_zero_plus_zero     = 0pt plus 0pt
313
314% \s!plus ... slower than inline
315
316\permanent\protected\def\spac_align_set_horizontal_none % should also relax \updateraggedskips
317  {\raggedstatus     \zerocount
318   \c_attr_alignstate\attributeunsetvalue
319   \leftskip         \plusone\leftskip
320   \rightskip        \plusone\rightskip
321   \spaceskip        \zeroskip
322   \xspaceskip       \zeroskip
323   \parinitleftskip  \zeroskip
324   \parinitrightskip \zeroskip
325   \parfillleftskip  \zeroskip
326   \parfillrightskip \s_zero_plus_one_fil % new
327   \raggedonelinerstate\conditionalfalse % now here
328   \enforced\aliased\let\updateraggedskips\relax}          % no need for adaption
329
330\permanent\protected\def\spac_align_set_horizontal_left
331  {\setraggedness    \spac_align_set_raggedness_left
332   \raggedstatus     \plusone
333   \c_attr_alignstate\plusone
334   \leftskip         \plusone\leftskip \s!plus\spac_align_set_raggedness_left
335   \rightskip        \plusone\rightskip\s!plus\zeropoint
336   \spaceskip        \v_spac_align_space_amount
337   \xspaceskip       \v_spac_align_space_amount_x
338   \parinitleftskip  \zeroskip
339   \parinitrightskip \zeroskip
340 % \parfillleftskip  \zeroskip
341 % \parfillrightskip \s_zero_plus_zero
342 % needs testing:
343   \parfillleftskip  \s_zero_plus_one_fil
344   \parfillrightskip \zeroskip
345   \parindent        \zeropoint
346   \relax}
347
348\permanent\protected\def\spac_align_set_horizontal_center
349  {\setraggedness    \spac_align_set_raggedness_middle
350   \raggedstatus     \plustwo
351   \c_attr_alignstate\plustwo
352   \leftskip         \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
353   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
354   \spaceskip        \v_spac_align_space_amount
355   \xspaceskip       \v_spac_align_space_amount_x
356   \parinitleftskip  \zeroskip
357   \parinitrightskip \zeroskip
358   \parfillleftskip  \zeroskip
359   \parfillrightskip \s_zero_plus_zero
360   \parindent        \zeropoint
361   \relax}
362
363\permanent\protected\def\spac_align_set_horizontal_right
364  {\setraggedness    \spac_align_set_raggedness_right
365   \raggedstatus     \plusthree
366   \c_attr_alignstate\plusthree
367   \leftskip         \plusone\leftskip \s!plus\zeropoint
368   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_right
369   \spaceskip        \v_spac_align_space_amount
370   \xspaceskip       \v_spac_align_space_amount_x
371   \parinitleftskip  \zeroskip
372   \parinitrightskip \zeroskip
373   \parfillleftskip  \zeroskip
374   \parfillrightskip \s_zero_plus_one_fil
375  %\parindent        \parindent
376   \relax}
377
378\permanent\protected\def\spac_align_set_horizontal_very_left
379  {\raggedstatus     \plusone
380   \c_attr_alignstate\plusone
381   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount
382   \rightskip        \plusone\rightskip\s!plus\zeropoint
383   \spaceskip        \v_spac_align_space_amount
384   \xspaceskip       \v_spac_align_space_amount_x
385   \parinitleftskip  \zeroskip
386   \parinitrightskip \zeroskip
387 % \parfillleftskip  \zeroskip
388 % \parfillrightskip \s_zero_plus_zero
389 % needs testing:
390   \parfillleftskip  \s_zero_plus_zero
391   \parfillrightskip \zeroskip
392   \parindent        \zeropoint
393   \relax}
394
395\permanent\protected\def\spac_align_set_horizontal_very_center
396  {\raggedstatus     \plustwo
397   \c_attr_alignstate\plustwo
398   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount
399   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount
400   \spaceskip        \v_spac_align_space_amount
401   \xspaceskip       \v_spac_align_space_amount_x
402   \parinitleftskip  \zeroskip
403   \parinitrightskip \zeroskip
404   \parfillleftskip  \zeroskip
405   \parfillrightskip \s_zero_plus_zero
406   \parindent        \zeropoint
407   \relax}
408
409\permanent\protected\def\spac_align_set_horizontal_very_right
410  {\raggedstatus     \plusthree
411   \c_attr_alignstate\plusthree
412   \leftskip         \plusone\leftskip \s!plus\zeropoint
413   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount
414   \spaceskip        \v_spac_align_space_amount
415   \xspaceskip       \v_spac_align_space_amount_x
416   \parinitleftskip  \zeroskip
417   \parinitrightskip \zeroskip
418   \parfillleftskip  \zeroskip
419   \parfillrightskip \s_zero_plus_zero
420  %\parindent        \parindent
421   \relax}
422
423\permanent\protected\def\spac_align_set_horizontal_wide_center
424  {\setraggedness    \spac_align_set_raggedness_middle
425   \raggedstatus     \plustwo
426   \c_attr_alignstate\plustwo
427   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount_half
428   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount_half
429   \spaceskip        \v_spac_align_space_amount
430   \xspaceskip       \v_spac_align_space_amount_x
431   \parinitleftskip  \zeroskip
432   \parinitrightskip \zeroskip
433   \parfillleftskip  \zeroskip
434   \parfillrightskip \s_zero_plus_zero
435   \parindent        \zeropoint
436   \relax}
437
438\permanent\protected\def\spac_align_set_horizontal_centered_last_line
439  {\raggedstatus     \zerocount
440   \c_attr_alignstate\attributeunsetvalue
441   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
442   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
443   \spaceskip        \zeroskip
444   \xspaceskip       \zeroskip
445   \parinitleftskip  \zeroskip
446   \parinitrightskip \zeroskip
447   \parfillleftskip  \zeroskip
448   \parfillrightskip \zeropoint\s!plus\v_spac_align_fill_amount_double\relax
449   \parindent        \zeropoint
450   \relax}
451
452\permanent\protected\def\spac_align_set_horizontal_flushedright_last_line
453  {\raggedstatus     \zerocount
454   \c_attr_alignstate\attributeunsetvalue
455   \leftskip         \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
456   \rightskip        \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
457   \spaceskip        \zeroskip
458   \xspaceskip       \zeroskip
459   \parinitleftskip  \zeroskip
460   \parinitrightskip \zeroskip
461   \parfillleftskip  \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
462   \parfillrightskip \zeroskip
463   \parindent        \zeropoint
464   \relax}
465
466\permanent\protected\def\spac_align_set_horizontal_right_tt % a plain command
467  {\tttf % brrr
468   \raggedstatus     \plusthree
469   \c_attr_alignstate\plusthree
470   \leftskip         \plusone\leftskip \s!plus\zeropoint\relax
471   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_right\relax
472   \spaceskip        \zeroskip
473   \xspaceskip       \zeroskip
474   \parinitleftskip  \zeroskip
475   \parinitrightskip \zeroskip
476   \parfillleftskip  \zeroskip
477   \parfillrightskip \s_zero_plus_zero
478  %\parindent        \parindent
479   \relax}
480
481\permanent\protected\def\spac_align_set_horizontal_slanted
482  {\raggedstatus     \zerocount
483  %\c_attr_alignstate\attributeunsetvalue
484   \c_attr_alignstate\plustwo
485   \leftskip         \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
486   \rightskip        \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
487   \spaceskip        \zeroskip
488   \xspaceskip       \zeroskip
489   \parinitleftskip  \zeroskip
490   \parinitrightskip \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
491   \parfillleftskip  \zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
492   \parfillrightskip \zeroskip
493   \parindent        \zeropoint
494   \relax}
495
496\permanent\protected\def\spac_align_set_horizontal_extra
497  {\xspaceskip\zeropoint\s!plus\v_spac_align_fill_amount_space\relax}
498
499\def\spac_align_flush_horizontal
500  {\ifcase\c_spac_align_state_horizontal
501     % 0
502     \spac_align_set_horizontal_none
503   \or
504     % 1 center
505     \ifcase\c_spac_align_state_broad
506       \spac_align_set_horizontal_center
507     \or
508       \spac_align_set_horizontal_very_center
509     \or
510       \spac_align_set_horizontal_wide_center
511     \fi
512   \or
513     % 2 flush left
514     \ifcase\c_spac_align_state_broad
515       \ifcase\c_spac_align_state_tight
516         \spac_align_set_horizontal_right
517       \else
518         \spac_align_set_horizontal_center
519         \leftskip1\leftskip
520       \fi
521     \else
522       \spac_align_set_horizontal_very_right
523     \fi
524   \or
525     % 3 flush right
526     \ifcase\c_spac_align_state_broad
527       \ifcase\c_spac_align_state_tight
528         \spac_align_set_horizontal_left
529       \else
530         \spac_align_set_horizontal_center
531         \rightskip1\rightskip
532       \fi
533     \else
534       \spac_align_set_horizontal_very_left
535     \fi
536   \or
537     % 4 inner
538     \ifdoublesided
539       \signalinnerrealign
540     \fi
541     \rightorleftpageaction\spac_align_set_horizontal_right\spac_align_set_horizontal_left
542   \or
543     % 5 outer
544     \ifdoublesided
545       \signalouterrealign
546     \fi
547     \rightorleftpageaction\spac_align_set_horizontal_left\spac_align_set_horizontal_right
548   \or
549     % 6 oneliner
550     \ifcase\c_spac_align_state_broad
551       \spac_align_set_horizontal_right
552     \else
553       \spac_align_set_horizontal_very_right
554     \fi
555    %\parfillleftskip \zeroskip
556     \parfillrightskip\zeroskip
557   \or
558     % 7 centered last line
559     \spac_align_set_horizontal_centered_last_line
560   \or
561     % 8 right aligned last line
562     \spac_align_set_horizontal_flushedright_last_line
563   \or
564     % 9 paragraph
565    %\parfillleftskip \zeroskip
566     \parfillrightskip\zeroskip
567   \or
568     % 10 slanted
569     \spac_align_set_horizontal_slanted
570   \or
571     % 11 hangleft
572     \spac_align_set_horizontal_hang_left
573   \or
574     % 12 hangright
575     \spac_align_set_horizontal_hang_right
576   \fi
577   \relax}
578
579% Page spacing:
580
581\newconstant\c_spac_align_state_page
582
583% \mutable\def\bottomalignlimit{\plusthree\lineheight}
584
585\newconstant\bottomraggednessmode % 0=ragged 1=normal/align 2=baseline 3=depth 4=weird-line
586
587\permanent\protected\def\raggedbottom
588  {\bottomraggednessmode\zerocount
589   \settopskip}
590
591\permanent\protected\def\alignbottom
592  {\bottomraggednessmode\plusone
593   \settopskip}
594
595\permanent\protected\def\baselinebottom
596  {\bottomraggednessmode\plustwo
597   \settopskip}
598
599\permanent\protected\def\depthlinebottom
600  {\bottomraggednessmode\plusthree
601   \settopskip}
602
603\aliased\let\normalbottom\alignbottom % downward compatible
604
605\permanent\protected\def\setbottomalignmode#1%
606  {\bottomraggednessmode#1%
607   \settopskip}
608
609\def\spac_align_flush_page
610  {\ifcase\c_spac_align_state_page
611     % keep state
612   \or
613     \raggedbottom
614   \or
615     \alignbottom
616   \or
617     \baselinebottom
618   \or
619     \depthlinebottom
620   \fi}
621
622% Directions
623
624\newconstant\c_spac_align_state_direction
625
626\def\spac_align_flush_direction
627  {\ifcase\c_spac_align_state_direction
628    % keep state
629   \or
630     \lefttoright
631   \or
632     \righttoleft
633   \fi}
634
635% Trick
636
637%D \starttyping
638%D \framed[width=5.5cm,align={flushleft}]       {This is a test sentence to see if it aligns okay.}
639%D \framed[width=5.5cm,align={flushright}]      {This is a test sentence to see if it aligns okay.}
640%D \framed[width=5.5cm,align={flushleft,tight}] {This is a test sentence to see if it aligns okay.}
641%D \framed[width=5.5cm,align={flushright,tight}]{This is a test sentence to see if it aligns okay.}
642%D \framed[width=5.5cm,align={flushleft,broad}] {This is a test sentence to see if it aligns okay.}
643%D \framed[width=5.5cm,align={flushright,broad}]{This is a test sentence to see if it aligns okay.}
644%D \stoptyping
645
646\newconstant\c_spac_align_state_tight
647
648% Interesting is that the non cached version is also pretty efficient
649% and as we cache we seldom call that one now so one can debate the
650% speedup.
651
652\newtoks\t_spac_align_collected
653\newtoks\t_spac_align_applied
654\newtoks\t_spac_align_presets
655
656\aliased\let\raggedcommand    \relax
657\aliased\let\updateraggedskips\relax
658
659\def\spac_align_add_to_cache
660  {\enforced\let\raggedbox\relax % why
661   % we inherit hyphenation and tolerance
662   \expand\t_spac_align_presets
663%    \lastlinefit\zerocount
664   \ifcsname\??aligncommand\m_spac_align_named\endcsname
665     \lastnamedcs
666   \else
667     \rawprocesscommacommand[\m_spac_align_asked]\spac_align_collect
668   \fi
669   \etoks\t_spac_align_collected
670     {\raggedonelinerstate\conditionalfalse % bad
671      \expand\t_spac_align_collected
672      \expand\t_spac_align_applied}%
673   \enforced\permanent\protected\edef\raggedcommand    {\expand\t_spac_align_collected}%
674   \enforced\permanent\protected\edef\updateraggedskips{\spac_align_flush_horizontal}%
675   \enforced\aliased\gletcsname\??alignmentnormalcache\m_spac_align_named\endcsname\raggedcommand
676   \enforced\aliased\gletcsname\??alignmentraggedcache\m_spac_align_named\endcsname\updateraggedskips}
677
678\appendtoks
679  \spac_align_flush_horizontal
680  \spac_align_flush_vertical
681  \spac_align_flush_direction
682  \spac_align_flush_page
683  \spac_align_flush_parfill
684\to \t_spac_align_applied
685
686\appendtoks
687   \t_spac_align_collected       \emptytoks
688   \c_spac_align_state_broad     \zerocount
689   \c_spac_align_state_horizontal\zerocount
690   \c_spac_align_state_vertical  \zerocount
691   \c_spac_align_state_spread    \zerocount
692   \c_spac_align_state_direction \zerocount % what is default ?
693   \c_spac_align_state_tight     \zerocount
694   \c_spac_align_state_page      \zerocount
695   \c_spac_align_state_par_fill  \zerocount
696\to \t_spac_align_presets
697
698\mutable\def\m_spac_align_named{\m_spac_align_asked}
699
700\def\spac_align_collect#1%
701  {\csname\??aligncommand#1\endcsname}
702
703\permanent\protected\tolerant\def\definealign[#1]#*[#2]%
704  {\pushmacro\m_spac_align_named
705   \edef\m_spac_align_named{#1}%
706   \edef\m_spac_align_asked{#2}%
707   \spac_align_add_to_cache
708   \popmacro\m_spac_align_named}
709
710% The local (key driven) setter:
711
712\permanent\protected\def\spac_align_prepare#1% deferred
713  {\edef\m_spac_align_asked{#1}%
714   \enforced\aliased\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
715   \ifrelax\raggedcommand
716     \spac_align_add_to_cache
717   \else
718     \enforced\aliased\expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
719   \fi}
720
721\aliased\let\dosetraggedcommand\spac_align_prepare % sort of public
722
723% The regular align setter:
724
725\permanent\tolerant\protected\def\setupalign[#1]% immediate
726  {\edef\m_spac_align_asked{#1}%
727   \enforced\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
728   \ifrelax\raggedcommand
729     \spac_align_add_to_cache
730   \else
731     \enforced\aliased\expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
732   \fi
733   \raggedcommand}
734
735\permanent\protected\def\usealignparameter#1% faster local variant
736  {\edef\m_spac_align_asked{#1\c!align}%
737   \ifempty\m_spac_align_asked\else
738     \spac_align_use_indeed
739   \fi}
740
741\permanent\protected\def\dousealignparameter#1% faster local variant
742  {\edef\m_spac_align_asked{#1}%
743   \ifempty\m_spac_align_asked\else
744     \spac_align_use_indeed
745   \fi}
746
747\def\spac_align_use_indeed
748  {\enforced\aliased\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% experiment
757
758\protected\def\spac_align_use_later#1%
759  {\begingroup
760   \edef\m_spac_align_asked{#1}%
761   \enforced\aliased\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
762   \ifrelax\raggedcommand
763     \spac_align_add_to_cache
764   \fi
765   \endgroup}
766
767\protected\def\spac_align_use_now#1%
768  {\csname\??alignmentnormalcache#1\endcsname}
769
770% Maybe we need something different in columns.
771
772\permanent\protected\def\installalign#1#2% beware: commands must be unexpandable!
773  {\ifcsname\??aligncommand#1\endcsname \else  % : so maybe we should use \etoksapp
774     \defcsname\??aligncommand#1\endcsname{\toksapp\t_spac_align_collected{#2}}%
775   \fi}
776
777% The keywords:
778
779\letcsname\??aligncommand\empty            \endcsname\empty
780\defcsname\??aligncommand\v!broad          \endcsname{\c_spac_align_state_broad     \plusone  }
781\defcsname\??aligncommand\v!wide           \endcsname{\c_spac_align_state_broad     \plustwo  }
782
783\defcsname\??aligncommand\v!bottom         \endcsname{\c_spac_align_state_page      \plusone  }
784\defcsname\??aligncommand\v!height         \endcsname{\c_spac_align_state_page      \plustwo  }
785\defcsname\??aligncommand\v!depth          \endcsname{\c_spac_align_state_page      \plusfour }
786\defcsname\??aligncommand\v!line           \endcsname{\c_spac_align_state_page      \plusthree
787                                                      % this will become another keyword (undocumented anyway)
788                                                      \toksapp\t_spac_align_collected{\raggedonelinerstate\conditionaltrue}}
789
790\defcsname\??aligncommand\v!high           \endcsname{\c_spac_align_state_vertical  \plusthree}
791\defcsname\??aligncommand\v!low            \endcsname{\c_spac_align_state_vertical  \plustwo  }
792\defcsname\??aligncommand\v!lohi           \endcsname{\c_spac_align_state_vertical  \plusone  }
793
794\defcsname\??aligncommand\v!spread         \endcsname{\c_spac_align_state_spread    \plusone  }
795
796\defcsname\??aligncommand\v!flushright     \endcsname{\c_spac_align_state_horizontal\plusthree}
797\defcsname\??aligncommand\v!flushleft      \endcsname{\c_spac_align_state_horizontal\plustwo  }
798\defcsname\??aligncommand\v!middle         \endcsname{\c_spac_align_state_horizontal\plusone  }
799\defcsname\??aligncommand\v!no             \endcsname{\c_spac_align_state_horizontal\plustwo  }
800\defcsname\??aligncommand\v!yes            \endcsname{\c_spac_align_state_horizontal\zerocount}
801\defcsname\??aligncommand\v!width          \endcsname{\c_spac_align_state_horizontal\zerocount}
802\defcsname\??aligncommand\v!normal         \endcsname{\c_spac_align_state_horizontal\zerocount}
803\defcsname\??aligncommand\v!reset          \endcsname{\c_spac_align_state_page      \zerocount
804                                                      \c_spac_align_state_horizontal\zerocount}
805\defcsname\??aligncommand\v!inner          \endcsname{\c_spac_align_state_horizontal\plusfour }
806\defcsname\??aligncommand\v!outer          \endcsname{\c_spac_align_state_horizontal\plusfive }
807\defcsname\??aligncommand\v!flushinner     \endcsname{\c_spac_align_state_horizontal\plusfour }
808\defcsname\??aligncommand\v!flushouter     \endcsname{\c_spac_align_state_horizontal\plusfive }
809\defcsname\??aligncommand\v!right          \endcsname{\c_spac_align_state_horizontal\plustwo  }
810\defcsname\??aligncommand\v!left           \endcsname{\c_spac_align_state_horizontal\plusthree}
811\defcsname\??aligncommand\v!center         \endcsname{\c_spac_align_state_horizontal\plusone
812                                                      \c_spac_align_state_broad     \plustwo  }
813\defcsname\??aligncommand\v!disable        \endcsname{\c_spac_align_state_horizontal\plussix  }
814\defcsname\??aligncommand\v!last           \endcsname{\c_spac_align_state_horizontal\plusseven}
815\defcsname\??aligncommand\v!end            \endcsname{\c_spac_align_state_horizontal\pluseight}
816\defcsname\??aligncommand\v!paragraph      \endcsname{\c_spac_align_state_horizontal\plusnine}
817
818\defcsname\??aligncommand\v!lefttoright    \endcsname{\c_spac_align_state_direction \plusone  }
819\defcsname\??aligncommand\v!righttoleft    \endcsname{\c_spac_align_state_direction \plustwo  }
820\defcsname\??aligncommand               l2r\endcsname{\c_spac_align_state_direction \plusone  }
821\defcsname\??aligncommand               r2l\endcsname{\c_spac_align_state_direction \plustwo  }
822
823\defcsname\??aligncommand\v!tight          \endcsname{\c_spac_align_state_tight     \plusone}
824
825\defcsname\??aligncommand\v!slanted        \endcsname{\c_spac_align_state_horizontal\plusten
826                                                      \c_spac_align_state_broad     \plustwo  }
827
828
829\defcsname\??aligncommand\v!table          \endcsname{\c_spac_align_state_vertical  \plusthree
830                                                      \c_spac_align_state_broad     \plusone
831                                                      \c_spac_align_state_horizontal\plustwo  }
832
833\defcsname\??aligncommand\v!lesshyphenation\endcsname{\toksapp\t_spac_align_collected{\lesshyphens}}
834\defcsname\??aligncommand\v!morehyphenation\endcsname{\toksapp\t_spac_align_collected{\morehyphens}}
835
836\defcsname\??aligncommand\v!hanging        \endcsname{\toksapp\t_spac_align_collected{\font_protruding_enable }}
837\defcsname\??aligncommand\v!hangingboth    \endcsname{\toksapp\t_spac_align_collected{\font_protruding_enable_b}}
838\defcsname\??aligncommand\v!nothanging     \endcsname{\toksapp\t_spac_align_collected{\font_protruding_disable}}
839\defcsname\??aligncommand\v!hz             \endcsname{\toksapp\t_spac_align_collected{\font_expansion_enable  }}
840\defcsname\??aligncommand\v!fullhz         \endcsname{\toksapp\t_spac_align_collected{\font_expansion_enable_k}}
841\defcsname\??aligncommand\v!nohz           \endcsname{\toksapp\t_spac_align_collected{\font_expansion_disable }}
842%defcsname\??aligncommand\v!spacing        \endcsname{\toksapp\t_spac_align_collected{\normalspacing\zerocount}} % not yet
843%defcsname\??aligncommand\v!nospacing      \endcsname{\toksapp\t_spac_align_collected{\normalspacing\plusone}}   % not yet
844\defcsname\??aligncommand\v!hyphenated     \endcsname{\toksapp\t_spac_align_collected{\dohyphens}}
845\defcsname\??aligncommand\v!nothyphenated  \endcsname{\toksapp\t_spac_align_collected{\nohyphens}}
846\defcsname\??aligncommand\v!collapsed      \endcsname{\toksapp\t_spac_align_collected{\dohyphencollapsing}}
847\defcsname\??aligncommand\v!notcollapsed   \endcsname{\toksapp\t_spac_align_collected{\nohyphencollapsing}}
848\defcsname\??aligncommand\v!explicit       \endcsname{\toksapp\t_spac_align_collected{\nohyphens\doexplicithyphens}}
849
850\defcsname\??aligncommand\v!tolerant       \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_tolerant}}
851\defcsname\??aligncommand\v!verytolerant   \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_very_tolerant}}
852\defcsname\??aligncommand\v!stretch        \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_stretch}}
853\defcsname\??aligncommand\v!extremestretch \endcsname{\toksapp\t_spac_align_collected{\spac_align_set_extreme_stretch}}
854
855\defcsname\??aligncommand          \v!final\endcsname{\c_spac_align_state_par_fill\plusone}
856\defcsname\??aligncommand        1*\v!final\endcsname{\c_spac_align_state_par_fill\plusone}
857\defcsname\??aligncommand        2*\v!final\endcsname{\c_spac_align_state_par_fill\plustwo}      % hardcoded multiplier
858\defcsname\??aligncommand        3*\v!final\endcsname{\c_spac_align_state_par_fill\plusthree}
859\defcsname\??aligncommand        4*\v!final\endcsname{\c_spac_align_state_par_fill\plusfour}
860
861% a one shot (only usefull in e.g. framed, also needs tolerance and stretch)
862
863\defcsname\??aligncommand          \v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}}
864\defcsname\??aligncommand        1*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plusone}}
865\defcsname\??aligncommand        2*\v!more\endcsname{\toksapp\t_spac_align_collected{\looseness\plustwo}}
866
867% for verbatim overflow
868
869\defcsname\??aligncommand\v!hangleft      \endcsname{\c_spac_align_state_horizontal\pluseleven}
870\defcsname\??aligncommand\v!hangright     \endcsname{\c_spac_align_state_horizontal\plustwelve}
871
872\permanent\protected\def\spac_align_set_horizontal_hang_right
873  {\spac_align_set_horizontal_very_left
874   \parinitrightskip\s_zero_plus_one_fill
875   \relax}
876
877\permanent\protected\def\spac_align_set_horizontal_hang_left
878  {\spac_align_set_horizontal_very_right
879   \parinitleftskip \s_zero_plus_one_fill
880   \relax}
881
882% experiment
883
884\defcsname\??aligncommand\v!flushforward \endcsname{\c_spac_align_state_horizontal\ifconditional\inlinelefttoright\plustwo\else\plusthree\fi}
885\defcsname\??aligncommand\v!flushbackward\endcsname{\c_spac_align_state_horizontal\ifconditional\inlinelefttoright\plusthree\else\plustwo\fi}
886
887% experiment
888
889\defcsname\??aligncommand\v!always\endcsname{\toksapp\t_spac_align_collected{\bitwiseflip\hyphenationmode\forcecheckhyphenationcode}}
890
891% experiment
892
893\defcsname\??aligncommand\v!profile\endcsname{\toksapp\t_spac_align_collected{\setmainlineprofile}}
894
895% lastlinefit
896
897\newconstant\c_spac_align_state_fit
898
899\defcsname\??aligncommand\v!fit\endcsname
900  {\c_spac_align_state_fit\plusone}
901
902\appendtoks
903   \c_spac_align_state_fit\zerocount
904\to \t_spac_align_presets
905
906\appendtoks
907   \lastlinefit\ifcase\c_spac_align_state_fit\zerocount\else\plusthousand\fi
908\to \t_spac_align_applied
909
910% linebreakcriterion
911
912\immutable\integerdef\defaultdoublehyphendemerits    10000
913\immutable\integerdef\defaultfinalhyphendemerits      5000
914\immutable\integerdef\defaultadjdemerits             10000
915\immutable\integerdef\defaultorphanpenalty               0
916\immutable\integerdef\defaultlinebreakcriterion          0 % 12 12 12 99 : 0C0C0C63
917
918\immutable\integerdef\granularadjdemerits              5000  % maybe 2500
919\immutable\integerdef\granularlinebreakcriterion  "020C2A63  %  2 12 42 99
920
921\frozen\doublehyphendemerits\defaultdoublehyphendemerits
922\frozen\finalhyphendemerits \defaultfinalhyphendemerits
923\frozen\adjdemerits         \defaultadjdemerits
924\frozen\linebreakcriterion  \defaultlinebreakcriterion
925\frozen\orphanpenalty       \defaultorphanpenalty
926
927% better but incompatible:
928%
929% \frozen\adjdemerits         \optimaladjdemerits
930% \frozen\linebreakcriterion  \optimallinebreakcriterion
931
932\newconstant\c_spac_align_state_granular
933
934\defcsname\??aligncommand\v!granular\endcsname % no way to reset it .. todo: \everyresetalign
935  {\c_spac_align_state_granular\plusone}
936
937\appendtoks
938   \c_spac_align_state_granular\zerocount
939\to \t_spac_align_presets
940
941% \doubleadjdemerits: when zero it defaults to \adjdemerits
942
943\appendtoks
944  \ifcase\c_spac_align_state_granular
945     \adjdemerits       \defaultadjdemerits
946     \doubleadjdemerits \defaultadjdemerits
947     \linebreakcriterion\defaultlinebreakcriterion
948   \else
949     \adjdemerits       \granularadjdemerits
950% \doubleadjdemerits 100000
951     \doubleadjdemerits \defaultadjdemerits
952     \linebreakcriterion\granularlinebreakcriterion
953   \fi
954\to \t_spac_align_applied
955
956% end of definitions
957
958\definehspace [\v!final] [\emspaceamount]
959
960\def\spac_align_flush_parfill
961  {\ifcase\c_spac_align_state_par_fill\else
962     \spac_align_flush_parfill_indeed{\the\c_spac_align_state_par_fill}%
963   \fi}
964
965\protected\def\spac_align_flush_parfill_indeed#1%
966  {\parfillrightskip
967     #1\directhspaceamount\v!final
968   % plus \dimexpr\availablehsize-#1\directhspaceamount\v!final\relax
969     plus 1fill
970   \relax}
971
972%D For Wolfgang:
973
974\newtoks \t_spac_every_swap_align
975
976\appendtoks
977    \defcsname\??aligncommand\v!right\endcsname{\c_spac_align_state_horizontal\plusthree}%
978    \defcsname\??aligncommand\v!left \endcsname{\c_spac_align_state_horizontal\plustwo  }%
979\to \t_spac_every_swap_align
980
981\permanent\protected\def\enablereversealignment
982  {\expand\t_spac_every_swap_align
983   \t_spac_every_swap_align\emptytoks}
984
985% Visible commands:
986
987\aliased\let\notragged           \spac_align_set_horizontal_none
988\aliased\let\raggedleft          \spac_align_set_horizontal_left
989\aliased\let\raggedcenter        \spac_align_set_horizontal_center
990\aliased\let\raggedright         \spac_align_set_horizontal_right
991\aliased\let\veryraggedleft      \spac_align_set_horizontal_very_left
992\aliased\let\veryraggedcenter    \spac_align_set_horizontal_very_center
993\aliased\let\veryraggedright     \spac_align_set_horizontal_very_right
994\aliased\let\raggedwidecenter    \spac_align_set_horizontal_wide_center
995\aliased\let\centeredlastline    \spac_align_set_horizontal_centered_last_line
996\aliased\let\flushedrightlastline\spac_align_set_horizontal_flushedright_last_line
997\aliased\let\ttraggedright       \spac_align_set_horizontal_right_tt            % a plain command
998\aliased\let\forgetragged        \spac_align_set_horizontal_none
999\aliased\let\raggedslanted       \spac_align_set_horizontal_slanted
1000
1001\appendtoks
1002    \spac_align_set_horizontal_none
1003\to \everyforgetall
1004
1005% Box commands.
1006
1007\permanent\protected\def\ibox
1008  {\vbox\bgroup
1009     \forgetall
1010     \enforced\let\\\endgraf
1011     \ifdoublesided\signalinnerrealign\fi
1012     \doifelserightpage\spac_align_set_horizontal_right\spac_align_set_horizontal_left
1013     \let\next}
1014
1015\permanent\protected\def\obox
1016  {\vbox\bgroup
1017     \forgetall
1018     \enforced\let\\\endgraf
1019     \ifdoublesided\signalouterrealign\fi
1020     \doifelserightpage\spac_align_set_horizontal_left\spac_align_set_horizontal_right
1021     \let\next}
1022
1023\let\raggedbox\relax
1024
1025\permanent\protected\def\dosetraggedvbox#1% can be more keys .. how about caching here (but seldom used)
1026  {\enforced\let\raggedbox\vbox
1027   \processcommacommand[#1]\spac_align_set_ragged_vbox}
1028
1029\permanent\protected\def\dosetraggedhbox#1% can be more keys .. how about caching here (but seldom used)
1030  {\enforced\let\raggedbox\hbox
1031   \processcommacommand[#1]\spac_align_set_ragged_hbox}
1032
1033\def\spac_align_set_ragged_vbox#1%
1034  {\ifcsname\??alignvertical#1\endcsname
1035     \lastnamedcs
1036     \quitcommalist
1037   \fi}
1038
1039\def\spac_align_set_ragged_hbox#1%
1040  {\ifcsname\??alignhorizontal#1\endcsname
1041     \lastnamedcs
1042     \quitcommalist
1043   \fi}
1044
1045\permanent\protected\def\spac_align_vertical_left      {\lbox}
1046\permanent\protected\def\spac_align_vertical_right     {\rbox}
1047\permanent\protected\def\spac_align_vertical_middle    {\cbox}
1048\permanent\protected\def\spac_align_vertical_inner     {\ibox}
1049\permanent\protected\def\spac_align_vertical_outer     {\obox}
1050\permanent\protected\def\spac_align_vertical_flushleft {\rbox}
1051\permanent\protected\def\spac_align_vertical_flushright{\lbox}
1052\permanent\protected\def\spac_align_vertical_center    {\cbox}
1053\permanent\protected\def\spac_align_vertical_no        {\vbox\bgroup\spac_align_set_horizontal_right\let\next=}
1054
1055\permanent\protected\def\spac_align_horizontal_left      {\doalignedline\v!left}
1056\permanent\protected\def\spac_align_horizontal_right     {\doalignedline\v!right}
1057\permanent\protected\def\spac_align_horizontal_middle    {\doalignedline\v!middle}
1058\permanent\protected\def\spac_align_horizontal_inner     {\doalignedline\v!inner}
1059\permanent\protected\def\spac_align_horizontal_outer     {\doalignedline\v!outer}
1060\permanent\protected\def\spac_align_horizontal_flushleft {\doalignedline\v!right}
1061\permanent\protected\def\spac_align_horizontal_flushright{\doalignedline\v!left}
1062\permanent\protected\def\spac_align_horizontal_center    {\doalignedline\v!middle}
1063
1064\defcsname\??alignvertical  \v!left      \endcsname{\enforced\let\raggedbox\spac_align_vertical_left}
1065\defcsname\??alignvertical  \v!right     \endcsname{\enforced\let\raggedbox\spac_align_vertical_right}
1066\defcsname\??alignvertical  \v!middle    \endcsname{\enforced\let\raggedbox\spac_align_vertical_middle}
1067\defcsname\??alignvertical  \v!inner     \endcsname{\enforced\let\raggedbox\spac_align_vertical_inner}
1068\defcsname\??alignvertical  \v!outer     \endcsname{\enforced\let\raggedbox\spac_align_vertical_outer}
1069\defcsname\??alignvertical  \v!flushleft \endcsname{\enforced\let\raggedbox\spac_align_vertical_flushleft }
1070\defcsname\??alignvertical  \v!flushright\endcsname{\enforced\let\raggedbox\spac_align_vertical_flushright}
1071\defcsname\??alignvertical  \v!center    \endcsname{\enforced\let\raggedbox\spac_align_vertical_center}
1072\defcsname\??alignvertical  \v!no        \endcsname{\enforced\let\raggedbox\spac_align_vertical_no}
1073
1074\defcsname\??alignhorizontal\v!left      \endcsname{\enforced\let\raggedbox\spac_align_horizontal_left}
1075\defcsname\??alignhorizontal\v!right     \endcsname{\enforced\let\raggedbox\spac_align_horizontal_right}
1076\defcsname\??alignhorizontal\v!middle    \endcsname{\enforced\let\raggedbox\spac_align_horizontal_middle}
1077\defcsname\??alignhorizontal\v!inner     \endcsname{\enforced\let\raggedbox\spac_align_horizontal_inner}
1078\defcsname\??alignhorizontal\v!outer     \endcsname{\enforced\let\raggedbox\spac_align_horizontal_outer}
1079\defcsname\??alignhorizontal\v!flushleft \endcsname{\enforced\let\raggedbox\spac_align_horizontal_flushleft}
1080\defcsname\??alignhorizontal\v!flushright\endcsname{\enforced\let\raggedbox\spac_align_horizontal_flushright}
1081\defcsname\??alignhorizontal\v!center    \endcsname{\enforced\let\raggedbox\spac_align_horizontal_center}
1082
1083% The next one can be in use so we keep it around but one should be aware of
1084% possible interference. But it will be removed at some point!
1085
1086\permanent\protected\def\setraggedskips#1#2#3#4#5#6#7% never change this name (todo: inline this one .. less tracingall)
1087  {\enforced\permanent\protected\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
1088   \updateraggedskips}
1089
1090\permanent\protected\def\dosetraggedskips#1#2#3#4#5#6#7%
1091  {\raggedstatus                 #1\relax
1092   \leftskip   1\leftskip \s!plus#2\relax
1093   \rightskip  1\rightskip\s!plus#3\relax
1094   \spaceskip                    #4\relax
1095   \xspaceskip                   #5\relax
1096   \parfillskip \zeropoint\s!plus#6\relax
1097   \parindent                    #7\relax
1098   \c_attr_alignstate\ifcase\raggedstatus\attributeunsetvalue\else\raggedstatus\fi}
1099
1100% older (context) names:
1101
1102\aliased\let\spaceamount  \interwordspace
1103\aliased\let\emspaceamount\emwidth
1104
1105% tracing:
1106
1107\def\spac_show_par_data#1%
1108  {\ifrelax#1\else
1109     \ifzero#1\else
1110       \hbox{\string#1: \the#1}\endgraf
1111     \fi
1112     \expandafter\spac_show_par_data
1113   \fi}
1114
1115\permanent\protected\def\showpardata
1116  {\normalexpanded{\dontleavehmode\inleftmargin{\vsmash{\infofont\framed[\c!align=\v!right]{%
1117     \hbox{font: \fontname\font}\endgraf
1118     \spac_show_par_data
1119       \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
1120       \hsize     \vsize
1121       \leftskip  \rightskip
1122       \spaceskip \xspaceskip
1123       \parindent \parfillleftskip \parinitrightskip \parinitleftskip \parfillrightskip
1124       \hyphenpenalty \exhyphenpenalty \automatichyphenpenalty \explicithyphenpenalty
1125       \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty
1126       \doublehyphendemerits \finalhyphendemerits \adjdemerits \orphanpenalty
1127       \linebreakcriterion
1128   \relax}}}}}
1129
1130\permanent\protected\def\startshowpardata
1131  {\begingroup
1132   \showstruts
1133   \tracingparagraphs\maxdimen
1134   \enforced\let\startshowpardata\begingroup
1135   \toksapp\everypar{\showpardata}}
1136
1137\permanent\protected\def\stopshowpardata
1138  {\endgraf
1139   \endgroup}
1140
1141% Structure:
1142
1143\protected\def\startalignment
1144  {\par
1145   \begingroup
1146   \setupalign}
1147
1148\protected\def\stopalignment
1149  {\par
1150   \endgroup}
1151
1152\setnewconstant\alignstrutmode\plusone
1153
1154% see later for the real definition, which in the simple case is:
1155
1156\newtoks \everyleftofalignedline
1157\newtoks \everyrightofalignedline
1158
1159\permanent\protected\def\shiftalignedline#1#2#3#4% left, right, inner, outer
1160  {\rightorleftpageaction
1161     {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
1162      \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
1163     {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
1164      \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}
1165
1166\permanent\protected\def\doalignline#1#2% \\ == newline
1167  {\noindentation  % was \noindent
1168   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
1169   \begingroup
1170   \setlocalhsize % new
1171   \enforced\permanent\protected\def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
1172   \dowithnextbox
1173     {\hbox to \localhsize
1174        {\ifcase\alignstrutmode\or\strut\fi
1175         \expand\everyleftofalignedline
1176         #1\unhbox\nextbox#2\relax
1177         \expand\everyrightofalignedline}%
1178      \endgroup}
1179     \hbox}
1180
1181% plain commands
1182
1183\ifdefined\line       \else \permanent\protected\def\line        {\hbox to\hsize}    \fi
1184\ifdefined\leftline   \else \permanent\protected\def\leftline  #1{\line{#1\hss}}     \fi
1185\ifdefined\rightline  \else \permanent\protected\def\rightline #1{\line{\hss#1}}     \fi
1186\ifdefined\centerline \else \permanent\protected\def\centerline#1{\line{\hss#1\hss}} \fi
1187
1188% direct commands
1189
1190\installcorenamespace{alignwrapper}
1191
1192\protected\defcsname\??alignwrapper\v!left  \endcsname{\doalignline\relax \hss  }
1193\protected\defcsname\??alignwrapper\v!middle\endcsname{\doalignline\hss   \hss  }
1194\protected\defcsname\??alignwrapper\v!right \endcsname{\doalignline\hss   \relax}
1195\protected\defcsname\??alignwrapper\v!max   \endcsname{\doalignline\relax \relax}
1196
1197\def\spac_align_wrapper_middle{\doalignline\hss\hss}
1198
1199\def\spac_align_wrapper_handle#1%
1200  {\ifcsname\??alignwrapper#1\endcsname\expandafter\lastnamedcs\else\expandafter\spac_align_wrapper_middle\fi}
1201
1202\permanent\tolerant\protected\def\startlinealignment[#1]%
1203  {\spac_align_wrapper_handle{#1}%
1204   \bgroup\ignorespaces}
1205
1206\protected\def\spac_align_wrapper_stop
1207  {\removeunwantedspaces\egroup}
1208
1209\permanent\let\stoplinealignment\spac_align_wrapper_stop
1210
1211\permanent\protected\def\startleftaligned  {\startlinealignment[\v!left  ]}  \permanent\let\stopleftaligned  \spac_align_wrapper_stop
1212\permanent\protected\def\startmiddlealigned{\startlinealignment[\v!middle]}  \permanent\let\stopmiddlealigned\spac_align_wrapper_stop
1213\permanent\protected\def\startrightaligned {\startlinealignment[\v!right ]}  \permanent\let\stoprightaligned \spac_align_wrapper_stop
1214\permanent\protected\def\startmaxaligned   {\startlinealignment[\v!max   ]}  \permanent\let\stopmaxaligned   \spac_align_wrapper_stop
1215
1216\aliased\let\startmidaligned   \startmiddlealigned  \aliased\let\stopmidaligned   \stopmiddlealigned
1217\aliased\let\startcenteraligned\startmiddlealigned  \aliased\let\stopcenteraligned\stopmiddlealigned
1218
1219\permanent\protected\def\leftaligned  {\spac_align_wrapper_handle\v!left  }
1220\permanent\protected\def\middlealigned{\spac_align_wrapper_handle\v!middle}
1221\permanent\protected\def\rightaligned {\spac_align_wrapper_handle\v!right }
1222\permanent\protected\def\maxaligned   {\spac_align_wrapper_handle\v!max   }
1223
1224\aliased\let\midaligned   \middlealigned
1225\aliased\let\centeraligned\middlealigned
1226
1227\installcorenamespace{alignline}
1228
1229\letcsname\??alignline\v!left      \endcsname\leftaligned
1230\letcsname\??alignline\v!right     \endcsname\rightaligned
1231\letcsname\??alignline\v!middle    \endcsname\midaligned
1232\letcsname\??alignline\v!flushleft \endcsname\rightaligned % beware, makes no sense in locations / we will have a special locations handler
1233\letcsname\??alignline\v!flushright\endcsname\leftaligned  % beware, makes no sense in locations / we will have a special locations handler
1234\letcsname\??alignline\v!center    \endcsname\midaligned
1235\letcsname\??alignline\v!max       \endcsname\maxaligned
1236
1237%D Experimental (will be redone when floats are redone as it's real messy
1238%D now). It can also be made faster (if needed).
1239
1240\permanent\protected\def\doxalignline#1#2#3#4#5#6%
1241  {\noindentation  % was \noindent
1242   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
1243   \begingroup
1244   \setlocalhsize
1245   \enforced\permanent\protected\def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
1246   \dowithnextbox
1247     {\hbox to \localhsize
1248        {#1\hskip\ifdone#2\else#3\fi#4%
1249         \hbox to \localhsize
1250           {\expand\everyleftofalignedline
1251            \ifcase\alignstrutmode\or\strut\fi
1252            \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
1253            \expand\everyrightofalignedline}%
1254         \hss}%
1255        \endgroup}
1256     \hbox}
1257
1258\permanent\protected\def\doxcheckline % used for floats so multipass anyway
1259  {\signalrightpage\doifelserightpage\donetrue\donefalse}
1260
1261\defcsname\??alignline\v!inner      \endcsname{\doxalignline\doxcheckline++\zeropoint       \relax\hss  }
1262\defcsname\??alignline\v!outer      \endcsname{\doxalignline\doxcheckline++\zeropoint       \hss  \relax}
1263\defcsname\??alignline\v!innermargin\endcsname{\doxalignline\doxcheckline-+\innermargintotal\relax\hss  }
1264\defcsname\??alignline\v!outermargin\endcsname{\doxalignline\doxcheckline+-\outermargintotal\hss  \relax}
1265\defcsname\??alignline\v!inneredge  \endcsname{\doxalignline\doxcheckline-+\inneredgetotal  \relax\hss  }
1266\defcsname\??alignline\v!outeredge  \endcsname{\doxalignline\doxcheckline+-\outeredgetotal  \hss  \relax}
1267\defcsname\??alignline\v!backspace  \endcsname{\doxalignline\doxcheckline-+\backspace       \relax\hss  }
1268\defcsname\??alignline\v!cutspace   \endcsname{\doxalignline\doxcheckline+-\cutspace        \hss  \relax}
1269
1270\defcsname\??alignline\v!leftmargin \endcsname{\doxalignline\donefalse   --\leftmargintotal \hss  \relax}
1271\defcsname\??alignline\v!rightmargin\endcsname{\doxalignline\donefalse   ++\rightmargintotal\relax\hss  }
1272\defcsname\??alignline\v!leftedge   \endcsname{\doxalignline\donefalse   --\leftedgetotal   \hss  \relax}
1273\defcsname\??alignline\v!rightedge  \endcsname{\doxalignline\donefalse   ++\rightedgetotal  \relax\hss  }
1274
1275\permanent\protected\def\doalignedline#1{\begincsname\??alignline#1\endcsname}
1276
1277\permanent\protected\def\alignedline#1#2% setting default
1278  {\ifcsname\??alignline#1\endcsname
1279     \expandafter\lastnamedcs
1280   \else
1281     \csname\??alignline#2\expandafter\endcsname
1282   \fi}
1283
1284% beware: \wordright{whatever\kern-\rightskip} should work!
1285% so, no funny boxing here
1286
1287%D We need to pick up a box (downward compatible in case \type {\bgroup} is used
1288%D (test suite index example).
1289
1290\permanent\tolerant\protected\def\wordright[#1]%
1291  {\dowithnextbox
1292     {\normalexpanded{\spac_word_right_indeed{#1}{\hpack{\thebox\nextbox}}}}
1293     \hbox}
1294
1295\protected\def\spac_word_right_indeed#1#2%
1296  {\registerparwrapper
1297     {\v!word:\v!right}
1298     {\begingroup
1299      \frozen\parfillrightskip   \zeroskip  % frozen ?
1300      \frozen\finalhyphendemerits\zerocount % frozen ?
1301      \endgroup}
1302     {\doifelseparwrapper{\v!word:\v!right}{\unregisterparwrapper{\v!word:\v!right}}\donothing
1303      \removeunwantedspaces
1304      \ifcstok{#1}\v!right
1305        \kern-\rightskip
1306      \orelse\ifempty{#1}%
1307        % no kern
1308      \else
1309        \kern-#1%
1310      \fi
1311      \hfilll
1312      \discretionary{\strut}{\strut}{\strut}% \allowbreak % changed back from \hskip\zeropoint
1313      \hfilll
1314      \quad % decent spacing
1315      #2}}
1316
1317% \dorecurse{5}{something} \wordright{--someone} \endgraf
1318% \dorecurse{6}{something} \wordright{--someone} \endgraf
1319% \dorecurse{7}{something} \wordright{--someone} \endgraf
1320%
1321% \dorecurse{5}{something} \wordright{--someone else entirely} \endgraf
1322% \dorecurse{6}{something} \wordright{--someone else entirely} \endgraf
1323% \dorecurse{7}{something} \wordright{--someone else entirely} \endgraf
1324%
1325% \wordright[\rightskip]{whatever}
1326
1327% Trick posted by WS on mailing list, generalized a bit. The bottom text only shows
1328% op when there is one line space available. We could add some extra space if needed.
1329
1330% v\protected\def\bottomword
1331%   {\par
1332%    \dowithnextbox
1333%      {\leaders\box\nextbox\vfil\page}
1334%      \vbox to \lineheight}
1335%
1336% \permanent\protected\def\bottomword
1337%   {\par
1338%    \groupedcommand
1339%      {\leaders
1340%       \vbox to \lineheight\bgroup}
1341%      {\egroup
1342%       \vfil
1343%       \page}}
1344
1345% \simplealignedbox{2cm}{right}{x}
1346
1347\installcorenamespace{alignsimple}
1348\installcorenamespace{alignsimplereverse}
1349
1350% todo: also handle \bgroup ... \egroup
1351
1352\protected\def\spac_align_simple_left  #1{{#1\hss}}
1353\protected\def\spac_align_simple_right #1{{\hss#1}}
1354\protected\def\spac_align_simple_middle#1{{\hss#1\hss}}
1355
1356\letcsname\??alignsimple       \v!right     \endcsname\spac_align_simple_left
1357\letcsname\??alignsimple       \v!outer     \endcsname\spac_align_simple_left   % not managed! see linenumbers
1358\letcsname\??alignsimple       \v!flushleft \endcsname\spac_align_simple_left
1359\letcsname\??alignsimple       \v!left      \endcsname\spac_align_simple_right
1360\letcsname\??alignsimple       \v!inner     \endcsname\spac_align_simple_right  % not managed! see linenumbers
1361\letcsname\??alignsimple       \v!flushright\endcsname\spac_align_simple_right
1362\letcsname\??alignsimple       \v!middle    \endcsname\spac_align_simple_middle
1363
1364\letcsname\??alignsimplereverse\v!right     \endcsname\spac_align_simple_right
1365\letcsname\??alignsimplereverse\v!outer     \endcsname\spac_align_simple_right % not managed! see linenumbers
1366\letcsname\??alignsimplereverse\v!flushleft \endcsname\spac_align_simple_right
1367\letcsname\??alignsimplereverse\v!left      \endcsname\spac_align_simple_left
1368\letcsname\??alignsimplereverse\v!inner     \endcsname\spac_align_simple_left  % not managed! see linenumbers
1369\letcsname\??alignsimplereverse\v!flushright\endcsname\spac_align_simple_left
1370\letcsname\??alignsimplereverse\v!middle    \endcsname\spac_align_simple_middle
1371
1372\protected\def\spac_align_simple#1%
1373  {\begincsname\??alignsimple#1\endcsname}
1374
1375\permanent\protected\def\simplealignedbox#1#2%
1376  {\hbox \ifdim#1>\zeropoint to #1
1377     \ifcsname\??alignsimple#2\endcsname
1378       \doubleexpandafter\lastnamedcs
1379     \else
1380       \doubleexpandafter\spac_align_simple_left
1381     \fi
1382   \fi}
1383
1384\permanent\protected\def\simplealignedspreadbox#1#2%
1385  {\hbox \ifdim#1>\zeropoint spread #1
1386     \ifcsname\??alignsimple#2\endcsname
1387       \doubleexpandafter\lastnamedcs
1388     \else
1389       \doubleexpandafter\spac_align_simple_left
1390     \fi
1391   \fi}
1392
1393\permanent\protected\def\simplealignedboxplus#1#2#3%
1394  {\hbox #3 \ifdim#1>\zeropoint to #1
1395     \ifcsname\??alignsimple#2\endcsname
1396       \doubleexpandafter\lastnamedcs
1397     \else
1398       \doubleexpandafter\spac_align_simple_left
1399     \fi
1400   \fi}
1401
1402\newconditional\alignsimplelefttoright \alignsimplelefttoright\conditionaltrue
1403
1404\permanent\protected\def\simplereversealignedbox#1#2%
1405  {\hbox \ifdim#1>\zeropoint to #1
1406     \ifcsname\??alignsimplereverse#2\endcsname
1407       \doubleexpandafter\lastnamedcs
1408     \else
1409       \doubleexpandafter\spac_align_simple_left
1410     \fi
1411   \fi}
1412
1413\permanent\protected\def\simplereversealignedboxplus#1#2#3%
1414  {\hbox #3 \ifdim#1>\zeropoint to #1
1415     \ifcsname\??alignsimplereverse#2\endcsname
1416       \doubleexpandafter\lastnamedcs
1417     \else
1418       \doubleexpandafter\spac_align_simple_left
1419     \fi
1420   \fi}
1421
1422% Some obsolete (old) helpers:
1423
1424\permanent\tolerant\protected\def\definehbox[#1]#*[#2]%
1425  {\ifarguments\else\frozen\instance\protected\defcsname hbox#1\endcsname##1{\hbox to #2{\begstrut##1\endstrut\hss}}\fi}
1426
1427%D Some direction related helpers:
1428
1429\installcorenamespace {reverse}
1430
1431\defcsname\??reverse\v!normal \endcsname{\ifconditional\inlinelefttoright\else\s!reverse\fi}
1432\defcsname\??reverse\v!reverse\endcsname{\ifconditional\inlinelefttoright     \s!reverse\fi}
1433
1434\permanent\def\usedirectionparameterreverse#1{\begincsname\??reverse#1\c!direction\endcsname}
1435
1436%D Now official:
1437
1438\permanent\protected\def\spaceorpar{\endgraf\ifhmode\space\fi}
1439
1440%D Kind of documenting:
1441%D
1442%D \starttyping
1443%D \disabletrackers[builders.hpack.quality] % enabled by default
1444%D \enabletrackers[builders.hpack.collect]
1445%D \enabletrackers[builders.hpack.overflow]
1446%D
1447%D \starttext
1448%D     {\hsize 4cm \input tufte \par} \page
1449%D     {\hsize 8cm \input tufte \par} \page
1450%D \stoptext
1451%D \stoptyping
1452
1453\protect \endinput
1454