spac-ali.mkiv /size: 45 Kb    last modification: 2023-12-21 09:44
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
19%D {flush*} variants. Starting at the last day of 2011 both methods are
20%D merged into one and caching has been added, which makes switching
21%D twice as fast.
22
23% Todo: find a way to force last lines to have some distance from the right
24% edge (problem: keywords or presets), maybe a plugin
25%
26% \setupalign[...,myoption] % last
27%
28% but that also means myoption gets frozen due to caching.
29
30\registerctxluafile{spac-ali}{optimize}
31
32\definesystemattribute[realign]   [public] % might be combined with the next one
33\definesystemattribute[alignstate][public] % will make a single attributes for several states
34
35\appendtoks
36    \c_attr_realign   \attributeunsetvalue
37    \c_attr_alignstate\attributeunsetvalue
38\to \everyforgetall
39
40\unexpanded\def\resetrealignsignal{\c_attr_realign\attributeunsetvalue}
41\unexpanded\def\signalinnerrealign{\clf_setrealign\plustwo}
42\unexpanded\def\signalouterrealign{\clf_setrealign\plusone}
43
44\installcorenamespace{aligncommand}
45\installcorenamespace{alignhorizontal}
46\installcorenamespace{alignvertical}
47
48\installcorenamespace{alignmentnormalcache}
49\installcorenamespace{alignmentraggedcache}
50
51% nasty hack:
52
53\installcorenamespace{alignmentnormalcacheodd}
54\installcorenamespace{alignmentnormalcacheeven}
55
56\installcorenamespace{alignmentraggedcacheodd}
57\installcorenamespace{alignmentraggedcacheeven}
58
59\def\??alignmentnormalcache{\ifodd\realpageno\??alignmentnormalcacheodd\else\??alignmentnormalcacheeven\fi}
60\def\??alignmentraggedcache{\ifodd\realpageno\??alignmentraggedcacheodd\else\??alignmentraggedcacheeven\fi}
61
62\newtoks\everyresetalign % todo
63
64% This will become a more advanced layout controller soon:
65
66\newconditional\layoutlefttoright   \settrue\layoutlefttoright
67\newconditional\displaylefttoright  \settrue\displaylefttoright
68\newconditional\inlinelefttoright   \settrue\inlinelefttoright
69
70\unexpanded\def\lefttoright
71  {\ifvmode
72     \spac_directions_lefttoright_vmode
73   \else
74     \spac_directions_lefttoright_hmode
75   \fi}
76
77\unexpanded\def\righttoleft
78  {\ifvmode
79     \spac_directions_righttoleft_vmode
80   \else
81     \spac_directions_righttoleft_hmode
82   \fi}
83
84\unexpanded\def\spac_directions_lefttoright_vmode
85  {\settrue\displaylefttoright
86   \settrue\inlinelefttoright
87   \textdirection\directionlefttoright
88   \pardirection \directionlefttoright}
89
90\unexpanded\def\spac_directions_righttoleft_vmode
91  {\setfalse\displaylefttoright
92   \setfalse\inlinelefttoright
93   \textdirection\directionrighttoleft
94   \pardirection \directionrighttoleft}
95
96\unexpanded\def\spac_directions_lefttoright_hmode
97  {\linedirection\directionlefttoright % linedir keeps subtype of skip
98   \settrue\inlinelefttoright}
99
100\unexpanded\def\spac_directions_righttoleft_hmode
101  {\linedirection\directionrighttoleft % linedir keeps subtype of skip
102   \setfalse\inlinelefttoright}
103
104\unexpanded\def\synchronizelayoutdirection
105  {\ifconditional\layoutlefttoright
106     \spac_directions_synchronize_lr
107   \else
108     \spac_directions_synchronize_rl
109   \fi}
110
111\unexpanded\def\synchronizedisplaydirection
112  {\ifconditional\displaylefttoright
113     \spac_directions_synchronize_lr
114   \else
115     \spac_directions_synchronize_rl
116   \fi}
117
118\def\spac_directions_synchronize_lr
119  {\settrue\inlinelefttoright
120   \textdirection\directionlefttoright
121   \pardirection \directionlefttoright}
122
123\def\spac_directions_synchronize_rl
124  {\setfalse\inlinelefttoright
125   \textdirection\directionrighttoleft
126   \pardirection \directionrighttoleft}
127
128\unexpanded\def\synchronizeinlinedirection
129  {% why not \linedirection here
130   \textdirection\ifconditional\inlinelefttoright\directionlefttoright\else\directionrighttoleft\fi}
131
132\unexpanded\def\checkedlefttoright
133  {\ifvmode
134     \spac_directions_lefttoright_vmode
135   \else
136     \spac_directions_lefttoright_hmode_checked
137   \fi}
138
139\unexpanded\def\checkedrighttoleft
140  {\ifvmode
141     \spac_directions_righttoleft_vmode
142   \else
143     \spac_directions_righttoleft_hmode_checked
144   \fi}
145
146\unexpanded\def\spac_directions_lefttoright_hmode_checked
147  {\ifconditional\inlinelefttoright\else
148     \lefttoright
149   \fi}
150
151\unexpanded\def\spac_directions_righttoleft_hmode_checked
152  {\ifconditional\inlinelefttoright
153     \righttoleft
154   \fi}
155
156\installcorenamespace{bidi}
157
158\letvalue{\??bidi\v!left }\checkedlefttoright \letvalue{\??bidi l2r}\checkedlefttoright
159\letvalue{\??bidi\v!right}\checkedrighttoleft \letvalue{\??bidi r2l}\checkedrighttoleft
160
161\unexpanded\def\usebidiparameter#1%
162  {\begincsname\??bidi#1\c!bidi\endcsname}
163
164\unexpanded\def\showdirections
165  {\dontleavehmode
166   \begingroup\infofont\textdirection\directionlefttoright[\space
167   layout:  \ifconditional\layoutlefttoright  l2r\else r2l\fi\space
168   display: \ifconditional\displaylefttoright l2r\else r2l\fi\space
169   inline:  \ifconditional\inlinelefttoright  l2r\else r2l\fi\space
170   ]\endgroup}
171
172\unexpanded\def\righttolefthbox#1#{\reversehbox#1\bgroup\righttoleft\let\next} \let\rtlhbox\righttolefthbox
173\unexpanded\def\lefttorighthbox#1#{\naturalhbox#1\bgroup\lefttoright\let\next} \let\ltrhbox\lefttorighthbox
174\unexpanded\def\righttoleftvbox#1#{\reversevbox#1\bgroup\righttoleft\let\next} \let\rtlvbox\righttoleftvbox
175\unexpanded\def\lefttorightvbox#1#{\naturalvbox#1\bgroup\lefttoright\let\next} \let\ltrvbox\lefttorightvbox
176\unexpanded\def\righttoleftvtop#1#{\reversevtop#1\bgroup\righttoleft\let\next} \let\rtlvtop\righttoleftvtop
177\unexpanded\def\lefttorightvtop#1#{\naturalvtop#1\bgroup\lefttoright\let\next} \let\ltrvtop\lefttorightvtop
178
179\unexpanded\def\autodirhbox#1#{\hbox#1\bgroup\synchronizeinlinedirection\let\next}
180\unexpanded\def\autodirvbox#1#{\vbox#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vbox
181\unexpanded\def\autodirvtop#1#{\vtop#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vtop
182
183\unexpanded\def\leftorrighthbox{\ifconditional\displaylefttoright\expandafter\lefttorighthbox\else\expandafter\righttolefthbox\fi}
184\unexpanded\def\leftorrightvbox{\ifconditional\displaylefttoright\expandafter\lefttorightvbox\else\expandafter\righttoleftvbox\fi}
185\unexpanded\def\leftorrightvtop{\ifconditional\displaylefttoright\expandafter\lefttorightvtop\else\expandafter\righttoleftvtop\fi}
186
187\unexpanded\def\rtltext{\groupedcommand{\dontleavehmode\righttoleft\ignorespaces}\removeunwantedspaces}
188\unexpanded\def\ltrtext{\groupedcommand{\dontleavehmode\lefttoright\ignorespaces}\removeunwantedspaces}
189
190% Tolerance and hyphenation
191
192\ifdefined\lesshyphens \else \let\lesshyphens\relax \fi
193\ifdefined\morehyphens \else \let\morehyphens\relax \fi
194\ifdefined\nohyphens   \else \let\nohyphens  \relax \fi
195\ifdefined\dohyphens   \else \let\dohyphens  \relax \fi
196
197\newconstant\c_spac_tolerance_default  \c_spac_tolerance_default 1500 % shouldn't that be 200
198\newconstant\c_spac_tolerance_minimum  \c_spac_tolerance_minimum 1500
199\newconstant\c_spac_tolerance_normal   \c_spac_tolerance_normal  3000
200\newconstant\c_spac_tolerance_extreme  \c_spac_tolerance_extreme 4500
201
202\def\spac_align_set_raggedness_left  {\plustwo\bodyfontsize}
203\def\spac_align_set_raggedness_right {\plustwo\bodyfontsize}
204\def\spac_align_set_raggedness_middle{\plussix\bodyfontsize} % overloaded below
205
206% oeps, hsize can be 0pt in which case we get a strange division
207% was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
208
209\def\spac_align_set_raggedness_middle{\ifzeropt\hsize\plussix\bodyfontsize\else.5\hsize\fi}
210
211\unexpanded\def\setraggedness#1% tricky .. we keep the global tolerance otherwise ... to be reconsidered
212  {\ifnum\tolerance<\c_spac_tolerance_minimum
213     \tolerance\c_spac_tolerance_minimum % small values have unwanted side effects
214   \else
215     % todo: take set value or none .. better done elsewhere (200 is normal)
216   \fi
217   \ifx\dohyphens\relax % was 2.5 in old implementation using scratch registers
218     \hyphenpenalty\dimexpr2.8\hsize/\dimexpr#1\relax\relax % 50 in raggedright/raggedleft
219  %\else
220     % no need to do something as we're in \nohyphens
221   \fi}
222
223\unexpanded\def\spac_align_set_tolerant
224  {\tolerance\c_spac_tolerance_normal}
225
226\unexpanded\def\spac_align_set_very_tolerant
227  {\tolerance\c_spac_tolerance_extreme}
228
229\unexpanded\def\spac_align_set_stretch
230  {\emergencystretch\bodyfontsize}
231
232\unexpanded\def\spac_align_set_extreme_stretch
233  {\emergencystretch10\bodyfontsize}
234
235% Vertical
236
237\newconstant\c_spac_align_state_vertical
238
239\unexpanded\def\spac_align_set_vertical_none
240  {\let\raggedtopcommand   \relax
241   \let\raggedbottomcommand\relax}
242
243\unexpanded\def\spac_align_set_vertical_lohi
244  {\let\raggedtopcommand   \vfilll
245   \let\raggedbottomcommand\vfilll}
246
247\unexpanded\def\spac_align_set_vertical_low
248  {\let\raggedtopcommand   \vfilll
249   \let\raggedbottomcommand\relax}
250
251\unexpanded\def\spac_align_set_vertical_high
252  {\let\raggedtopcommand   \relax
253   \let\raggedbottomcommand\vfilll}
254
255\def\spac_align_flush_vertical
256  {\ifcase\c_spac_align_state_vertical
257     \spac_align_set_vertical_none
258   \or
259     \spac_align_set_vertical_lohi
260   \or
261     \spac_align_set_vertical_low
262   \or
263     \spac_align_set_vertical_high
264   \fi}
265
266% Horizontal
267
268\ifdefined\raggedonelinerstate \else
269    \newconditional\raggedonelinerstate  % public
270\fi
271
272% \appendtoks
273%     \setfalse\raggedonelinerstate
274% \to \everyforgetall
275
276\newconstant\raggedstatus % public
277
278\newconstant\c_spac_align_state_horizontal
279\newconstant\c_spac_align_state_broad
280\newconstant\c_spac_align_state_par_fill
281
282\def\v_spac_align_fill_amount          {\plusone  fil}
283\def\v_spac_align_fill_amount_hard     {\plusone fill}
284\def\v_spac_align_fill_amount_extreme  {\plustenthousand  filll}
285\def\v_spac_align_fill_amount_negative {\minusone fil}
286\def\v_spac_align_fill_amount_double   {\plustwo  fil}
287\def\v_spac_align_fill_amount_space    {\plustwo  fil} % can be added to xspace if we have a key
288\def\v_spac_align_fill_amount_half             {.5fil}
289\let\v_spac_align_space_amount        \interwordspace
290\def\v_spac_align_space_amount_x          {.5\emwidth}
291
292\newskip\s_zero_plus_one_fil \s_zero_plus_one_fil = 0pt plus 1fil
293\newskip\s_zero_plus_zero    \s_zero_plus_zero    = 0pt plus 0pt
294
295% \s!plus ... slower than inline
296
297\unexpanded\def\spac_align_set_horizontal_none % should also relax \updateraggedskips
298  {\raggedstatus\zerocount
299   \c_attr_alignstate\attributeunsetvalue
300   \leftskip   \plusone\leftskip
301   \rightskip  \plusone\rightskip
302   \spaceskip  \zeropoint
303   \xspaceskip \zeropoint
304   \parfillskip\s_zero_plus_one_fil % new
305   \setfalse\raggedonelinerstate    % now here
306   \let\updateraggedskips\relax}    % no need for adaption
307
308\unexpanded\def\spac_align_set_horizontal_left
309  {\setraggedness\spac_align_set_raggedness_left
310   \raggedstatus\plusone
311   \c_attr_alignstate\plusone
312   \leftskip   \plusone\leftskip \s!plus\spac_align_set_raggedness_left
313   \rightskip  \plusone\rightskip\s!plus\zeropoint
314   \spaceskip  \v_spac_align_space_amount
315   \xspaceskip \v_spac_align_space_amount_x
316   \parfillskip\s_zero_plus_zero
317   \parindent  \zeropoint
318   \relax}
319
320\unexpanded\def\spac_align_set_horizontal_center
321  {\setraggedness\spac_align_set_raggedness_middle
322   \raggedstatus\plustwo
323   \c_attr_alignstate\plustwo
324   \leftskip   \plusone\leftskip \s!plus\spac_align_set_raggedness_middle
325   \rightskip  \plusone\rightskip\s!plus\spac_align_set_raggedness_middle
326   \spaceskip  \v_spac_align_space_amount
327   \xspaceskip \v_spac_align_space_amount_x
328   \parfillskip\s_zero_plus_zero
329   \parindent  \zeropoint
330   \relax}
331
332\unexpanded\def\spac_align_set_horizontal_right
333  {\setraggedness\spac_align_set_raggedness_right
334   \raggedstatus\plusthree
335   \c_attr_alignstate\plusthree
336   \leftskip   \plusone\leftskip \s!plus\zeropoint
337   \rightskip  \plusone\rightskip\s!plus\spac_align_set_raggedness_right
338   \spaceskip  \v_spac_align_space_amount
339   \xspaceskip \v_spac_align_space_amount_x
340   \parfillskip\s_zero_plus_one_fil
341  %\parindent  \parindent
342   \relax}
343
344\unexpanded\def\spac_align_set_horizontal_very_left
345  {\raggedstatus\plusone
346   \c_attr_alignstate\plusone
347   \leftskip   \plusone\leftskip \s!plus\v_spac_align_fill_amount
348   \rightskip  \plusone\rightskip\s!plus\zeropoint
349   \spaceskip  \v_spac_align_space_amount
350   \xspaceskip \v_spac_align_space_amount_x
351   \parfillskip\s_zero_plus_zero
352   \parindent  \zeropoint
353   \relax}
354
355\unexpanded\def\spac_align_set_horizontal_very_center
356  {\raggedstatus\plustwo
357   \c_attr_alignstate\plustwo
358   \leftskip   \plusone\leftskip \s!plus\v_spac_align_fill_amount
359   \rightskip  \plusone\rightskip\s!plus\v_spac_align_fill_amount
360   \spaceskip  \v_spac_align_space_amount
361   \xspaceskip \v_spac_align_space_amount_x
362   \parfillskip\s_zero_plus_zero
363   \parindent  \zeropoint
364   \relax}
365
366\unexpanded\def\spac_align_set_horizontal_very_right
367  {\raggedstatus\plusthree
368   \c_attr_alignstate\plusthree
369   \leftskip   \plusone\leftskip \s!plus\zeropoint
370   \rightskip  \plusone\rightskip\s!plus\v_spac_align_fill_amount
371   \spaceskip  \v_spac_align_space_amount
372   \xspaceskip \v_spac_align_space_amount_x
373   \parfillskip\s_zero_plus_zero
374  %\parindent  \parindent
375   \relax}
376
377\unexpanded\def\spac_align_set_horizontal_wide_center
378  {\setraggedness\spac_align_set_raggedness_middle
379   \raggedstatus\plustwo
380   \c_attr_alignstate\plustwo
381   \leftskip   \plusone\leftskip \s!plus\v_spac_align_fill_amount_half
382   \rightskip  \plusone\rightskip\s!plus\v_spac_align_fill_amount_half
383   \spaceskip  \v_spac_align_space_amount
384   \xspaceskip \v_spac_align_space_amount_x
385   \parfillskip\s_zero_plus_zero
386   \parindent  \zeropoint
387   \relax}
388
389\unexpanded\def\spac_align_set_horizontal_centered_last_line
390  {\raggedstatus\zerocount
391   \c_attr_alignstate\attributeunsetvalue
392   \leftskip   \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
393   \rightskip  \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
394   \spaceskip  \zeropoint\relax
395   \xspaceskip \zeropoint\relax
396   \parfillskip\zeropoint\s!plus\v_spac_align_fill_amount_double\relax
397   \parindent  \zeropoint
398   \relax}
399
400\unexpanded\def\spac_align_set_horizontal_flushedright_last_line
401  {\raggedstatus\zerocount
402   \c_attr_alignstate\attributeunsetvalue
403   \leftskip       \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax
404   \rightskip      \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax
405   \spaceskip      \zeropoint\relax
406   \xspaceskip     \zeropoint\relax
407   \parfillskip    \zeropoint
408   \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax
409   \parfillleftmode\plustwo % \plusone checks for multiple lines
410   \parindent      \zeropoint
411   \relax}
412
413\unexpanded\def\spac_align_set_horizontal_right_tt % a plain command
414  {\tttf % brrr
415   \raggedstatus\plusthree
416   \c_attr_alignstate\plusthree
417   \leftskip   \plusone\leftskip \s!plus\zeropoint\relax
418   \rightskip  \plusone\rightskip\s!plus\spac_align_set_raggedness_right\relax
419   \spaceskip  \zeropoint\relax
420   \xspaceskip \zeropoint\relax
421   \parfillskip\s_zero_plus_zero
422  %\parindent  \parindent
423   \relax}
424
425\unexpanded\def\spac_align_set_horizontal_extra
426  {\xspaceskip\zeropoint\s!plus\v_spac_align_fill_amount_space\relax}
427
428\def\spac_align_flush_horizontal
429  {\ifcase\c_spac_align_state_horizontal
430     % 0
431     \spac_align_set_horizontal_none
432   \or
433     % 1 center
434     \ifcase\c_spac_align_state_broad
435       \spac_align_set_horizontal_center
436     \or
437       \spac_align_set_horizontal_very_center
438     \or
439       \spac_align_set_horizontal_wide_center
440     \fi
441   \or
442     % 2 flush left
443     \ifcase\c_spac_align_state_broad
444       \spac_align_set_horizontal_right
445     \else
446       \spac_align_set_horizontal_very_right
447     \fi
448   \or
449     % 3 flush right
450     \ifcase\c_spac_align_state_broad
451       \spac_align_set_horizontal_left
452     \else
453       \spac_align_set_horizontal_very_left
454     \fi
455   \or
456     % 4 inner
457     \ifdoublesided
458       \signalinnerrealign
459     \fi
460     \rightorleftpageaction\spac_align_set_horizontal_right\spac_align_set_horizontal_left
461   \or
462     % 5 outer
463     \ifdoublesided
464       \signalouterrealign
465     \fi
466     \rightorleftpageaction\spac_align_set_horizontal_left\spac_align_set_horizontal_right
467   \or
468     % 6 oneliner
469     \ifcase\c_spac_align_state_broad
470       \spac_align_set_horizontal_right
471     \else
472       \spac_align_set_horizontal_very_right
473     \fi
474     \parfillskip\zeropoint
475   \or
476     % 7 centered last line
477     \spac_align_set_horizontal_centered_last_line
478   \or
479     % 8 right aligned last line
480     \spac_align_set_horizontal_flushedright_last_line
481   \or
482     % 9 paragraph
483     \parfillskip\zeropoint
484   \fi
485   \relax}
486
487% Page spacing:
488
489\newconstant\c_spac_align_state_page
490
491\def\bottomalignlimit{\plusthree\lineheight}
492
493\newconstant\bottomraggednessmode % 0=ragged 1=normal/align 2=baseline
494
495\unexpanded\def\raggedbottom
496  {\bottomraggednessmode\zerocount
497   \settopskip}
498
499\unexpanded\def\alignbottom
500  {\bottomraggednessmode\plusone
501   \settopskip}
502
503\unexpanded\def\baselinebottom
504  {\bottomraggednessmode\plustwo
505   \settopskip}
506
507\let\normalbottom\alignbottom % downward compatible
508
509\unexpanded\def\setbottomalignmode#1%
510  {\bottomraggednessmode#1%
511   \settopskip}
512
513\def\spac_align_flush_page
514  {\ifcase\c_spac_align_state_page
515     % keep state
516   \or
517     \raggedbottom
518   \or
519     \alignbottom
520   \or
521     \baselinebottom
522   \fi}
523
524% Directions
525
526\newconstant\c_spac_align_state_direction
527
528\def\spac_align_flush_direction
529  {\ifcase\c_spac_align_state_direction
530    % keep state
531   \or
532     \lefttoright
533   \or
534     \righttoleft
535   \fi}
536
537% Interesting is that the non cached version is also pretty efficient
538% and as we cache we seldom call that one now so one can debate the
539% speedup.
540
541\newtoks\t_spac_align_collected
542
543\let\raggedcommand    \relax
544\let\updateraggedskips\relax
545
546\def\spac_align_add_to_cache
547  {\let\raggedbox\relax % why
548   % we inherit hyphenation and tolerance
549   \t_spac_align_collected       \emptytoks
550   \c_spac_align_state_broad     \zerocount
551   \c_spac_align_state_horizontal\zerocount
552   \c_spac_align_state_vertical  \zerocount
553   \c_spac_align_state_direction \zerocount % what is default ?
554   \c_spac_align_state_page      \zerocount
555   \c_spac_align_state_par_fill  \zerocount
556   \ifcsname\??aligncommand\m_spac_align_asked\endcsname
557     \lastnamedcs
558   \else
559     \rawprocesscommacommand[\m_spac_align_asked]\spac_align_collect
560   \fi
561   \normalexpanded{\t_spac_align_collected
562     {% \resetrealignsignal % can go as it is always set
563      \setfalse\raggedonelinerstate % bad
564      \the\t_spac_align_collected
565      \spac_align_flush_horizontal
566      \spac_align_flush_vertical
567      \spac_align_flush_direction
568      \spac_align_flush_page
569      \spac_align_flush_parfill
570      }}% kept, nice for tracing
571   \edef\raggedcommand    {\the\t_spac_align_collected }%
572   \edef\updateraggedskips{\spac_align_flush_horizontal}%
573   \expandafter\glet\csname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand
574   \expandafter\glet\csname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips}
575
576\def\spac_align_collect#1%
577  {\csname\??aligncommand#1\endcsname}
578
579% The local (key driven) setter:
580
581\unexpanded\def\spac_align_prepare#1% deferred
582  {\edef\m_spac_align_asked{#1}%
583   \expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
584   \ifx\raggedcommand\relax
585     \spac_align_add_to_cache
586   \else
587     \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
588   \fi}
589
590\let\dosetraggedcommand\spac_align_prepare % sort of public
591
592% The regular align setter:
593
594\unexpanded\def\setupalign
595  {\dosingleempty\spac_align_setup}
596
597\def\spac_align_setup[#1]% immediate
598  {\edef\m_spac_align_asked{#1}%
599   \expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
600   \ifx\raggedcommand\relax
601     \spac_align_add_to_cache
602   \else
603     \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
604   \fi
605   \raggedcommand}
606
607\unexpanded\def\usealignparameter#1% faster local variant
608  {\edef\m_spac_align_asked{#1\c!align}%
609   \ifx\m_spac_align_asked\empty\else
610     \spac_align_use_indeed
611   \fi}
612
613\unexpanded\def\dousealignparameter#1% faster local variant
614  {\edef\m_spac_align_asked{#1}%
615   \ifx\m_spac_align_asked\empty\else
616     \spac_align_use_indeed
617   \fi}
618
619\def\spac_align_use_indeed
620  {\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
621   \ifx\raggedcommand\relax
622     \spac_align_add_to_cache
623   \else
624     \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname
625   \fi
626   \raggedcommand}
627
628% experiment
629
630\unexpanded\def\spac_align_use_later#1%
631  {\begingroup
632   \edef\m_spac_align_asked{#1}%
633   \expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname
634   \ifx\raggedcommand\relax
635     \spac_align_add_to_cache
636   \fi
637   \endgroup}
638
639\unexpanded\def\spac_align_use_now#1%
640  {\csname\??alignmentnormalcache#1\endcsname}
641
642% Maybe we need something different in columns.
643
644\unexpanded\def\installalign#1#2% beware: commands must be unexpandable!
645  {\ifcsname\??aligncommand#1\endcsname \else
646     \setvalue{\??aligncommand#1}{\toksapp\t_spac_align_collected{#2}}%
647   \fi}
648
649% beware, toks stuff and states are set at a differt time, so installalign is
650% only for special options
651%
652% \setvalue{\??aligncommand whatever}%
653%   {\c_spac_align_state_horizontal\plushundred
654%    \toksapp\t_spac_align_collected{.....}}
655%
656% this one could deal with both
657%
658% \unexpanded\def\installalignoption#1#2%
659%   {\ifcsname\??aligncommand#1\endcsname \else
660%      \setvalue{\??aligncommand#1}%
661%        {\spac_align_set_horizontal_none
662%         \c_spac_align_state_horizontal\plushundred % don't set
663%         \toksapp\t_spac_align_collected{#2}}%
664%    \fi}
665%
666% \installalignoption
667%   {whatever}
668%   {}
669
670% The keywords:
671
672\letvalue{\??aligncommand\empty            }\empty
673\setvalue{\??aligncommand\v!broad          }{\c_spac_align_state_broad     \plusone  }
674\setvalue{\??aligncommand\v!wide           }{\c_spac_align_state_broad     \plustwo  }
675
676\setvalue{\??aligncommand\v!bottom         }{\c_spac_align_state_page      \plusone  }
677\setvalue{\??aligncommand\v!height         }{\c_spac_align_state_page      \plustwo  }
678\setvalue{\??aligncommand\v!line           }{\c_spac_align_state_page      \plusthree
679                                             % this will become another keyword (undocumented anyway)
680                                             \toksapp\t_spac_align_collected{\settrue\raggedonelinerstate}}
681
682\setvalue{\??aligncommand\v!high           }{\c_spac_align_state_vertical  \plusthree}
683\setvalue{\??aligncommand\v!low            }{\c_spac_align_state_vertical  \plustwo  }
684\setvalue{\??aligncommand\v!lohi           }{\c_spac_align_state_vertical  \plusone  }
685
686\setvalue{\??aligncommand\v!flushright     }{\c_spac_align_state_horizontal\plusthree}
687\setvalue{\??aligncommand\v!flushleft      }{\c_spac_align_state_horizontal\plustwo  }
688\setvalue{\??aligncommand\v!middle         }{\c_spac_align_state_horizontal\plusone  }
689\setvalue{\??aligncommand\v!no             }{\c_spac_align_state_horizontal\plustwo  }
690\setvalue{\??aligncommand\v!yes            }{\c_spac_align_state_horizontal\zerocount}
691\setvalue{\??aligncommand\v!width          }{\c_spac_align_state_horizontal\zerocount}
692\setvalue{\??aligncommand\v!normal         }{\c_spac_align_state_horizontal\zerocount}
693\setvalue{\??aligncommand\v!reset          }{\c_spac_align_state_page      \zerocount
694                                             \c_spac_align_state_horizontal\zerocount}
695\setvalue{\??aligncommand\v!inner          }{\c_spac_align_state_horizontal\plusfour }
696\setvalue{\??aligncommand\v!outer          }{\c_spac_align_state_horizontal\plusfive }
697\setvalue{\??aligncommand\v!flushinner     }{\c_spac_align_state_horizontal\plusfour }
698\setvalue{\??aligncommand\v!flushouter     }{\c_spac_align_state_horizontal\plusfive }
699\setvalue{\??aligncommand\v!right          }{\c_spac_align_state_horizontal\plustwo  }
700\setvalue{\??aligncommand\v!left           }{\c_spac_align_state_horizontal\plusthree}
701\setvalue{\??aligncommand\v!center         }{\c_spac_align_state_horizontal\plusone
702                                             \c_spac_align_state_broad     \plustwo  }
703\setvalue{\??aligncommand\v!disable        }{\c_spac_align_state_horizontal\plussix  }
704\setvalue{\??aligncommand\v!last           }{\c_spac_align_state_horizontal\plusseven}
705\setvalue{\??aligncommand\v!end            }{\c_spac_align_state_horizontal\pluseight}
706\setvalue{\??aligncommand\v!paragraph      }{\c_spac_align_state_horizontal\plusnine}
707
708\setvalue{\??aligncommand\v!lefttoright    }{\c_spac_align_state_direction \plusone  }
709\setvalue{\??aligncommand\v!righttoleft    }{\c_spac_align_state_direction \plustwo  }
710\setvalue{\??aligncommand               l2r}{\c_spac_align_state_direction \plusone  }
711\setvalue{\??aligncommand               r2l}{\c_spac_align_state_direction \plustwo  }
712
713\setvalue{\??aligncommand\v!table          }{\c_spac_align_state_vertical  \plusthree
714                                             \c_spac_align_state_broad     \plusone
715                                             \c_spac_align_state_horizontal\plustwo  }
716
717\setvalue{\??aligncommand\v!lesshyphenation}{\toksapp\t_spac_align_collected{\lesshyphens}}
718\setvalue{\??aligncommand\v!morehyphenation}{\toksapp\t_spac_align_collected{\morehyphens}}
719
720\setvalue{\??aligncommand\v!hanging        }{\toksapp\t_spac_align_collected{\font_protruding_enable }}
721\setvalue{\??aligncommand\v!hangingboth    }{\toksapp\t_spac_align_collected{\font_protruding_enable_b}}
722\setvalue{\??aligncommand\v!nothanging     }{\toksapp\t_spac_align_collected{\font_protruding_disable}}
723\setvalue{\??aligncommand\v!hz             }{\toksapp\t_spac_align_collected{\font_expansion_enable  }}
724\setvalue{\??aligncommand\v!fullhz         }{\toksapp\t_spac_align_collected{\font_expansion_enable_k}}
725\setvalue{\??aligncommand\v!nohz           }{\toksapp\t_spac_align_collected{\font_expansion_disable }}
726%setvalue{\??aligncommand\v!spacing        }{\toksapp\t_spac_align_collected{\normalspacing\zerocount}} % not yet
727%setvalue{\??aligncommand\v!nospacing      }{\toksapp\t_spac_align_collected{\normalspacing\plusone}}   % not yet
728\setvalue{\??aligncommand\v!hyphenated     }{\toksapp\t_spac_align_collected{\dohyphens}}
729\setvalue{\??aligncommand\v!nothyphenated  }{\toksapp\t_spac_align_collected{\nohyphens}}
730
731\setvalue{\??aligncommand\v!tolerant       }{\toksapp\t_spac_align_collected{\spac_align_set_tolerant}}
732\setvalue{\??aligncommand\v!verytolerant   }{\toksapp\t_spac_align_collected{\spac_align_set_very_tolerant}}
733\setvalue{\??aligncommand\v!stretch        }{\toksapp\t_spac_align_collected{\spac_align_set_stretch}}
734\setvalue{\??aligncommand\v!extremestretch }{\toksapp\t_spac_align_collected{\spac_align_set_extreme_stretch}}
735
736\setvalue{\??aligncommand  \v!final}{\c_spac_align_state_par_fill\plusone}
737\setvalue{\??aligncommand1*\v!final}{\c_spac_align_state_par_fill\plusone}
738\setvalue{\??aligncommand2*\v!final}{\c_spac_align_state_par_fill\plustwo}      % hardcoded multiplier
739\setvalue{\??aligncommand3*\v!final}{\c_spac_align_state_par_fill\plusthree}
740\setvalue{\??aligncommand4*\v!final}{\c_spac_align_state_par_fill\plusfour}
741
742% a one shot (only usefull in e.g. framed, also needs tolerance and stretch)
743
744\setvalue{\??aligncommand  \v!more}{\toksapp\t_spac_align_collected{\looseness\plusone}}
745\setvalue{\??aligncommand1*\v!more}{\toksapp\t_spac_align_collected{\looseness\plusone}}
746\setvalue{\??aligncommand2*\v!more}{\toksapp\t_spac_align_collected{\looseness\plustwo}}
747
748\definehspace [\v!final] [\emspaceamount]
749
750\def\spac_align_flush_parfill
751  {\ifcase\c_spac_align_state_par_fill\else
752     \spac_align_flush_parfill_indeed{\number\c_spac_align_state_par_fill}%
753   \fi}
754
755\unexpanded\def\spac_align_flush_parfill_indeed#1%
756  {\parfillskip
757     #1\directhspaceamount\v!final
758   % plus \dimexpr\availablehsize-#1\directhspaceamount\v!final\relax
759     plus 1fill
760   \relax}
761
762%D For Wolfgang:
763
764\newtoks \t_spac_every_swap_align
765
766\appendtoks
767    \setvalue{\??aligncommand\v!right}{\c_spac_align_state_horizontal\plusthree}%
768    \setvalue{\??aligncommand\v!left }{\c_spac_align_state_horizontal\plustwo  }%
769\to \t_spac_every_swap_align
770
771\unexpanded\def\enablereversealignment
772  {\the\t_spac_every_swap_align
773   \t_spac_every_swap_align\emptytoks}
774
775% Visible commands:
776
777\let\notragged           \spac_align_set_horizontal_none
778\let\raggedleft          \spac_align_set_horizontal_left
779\let\raggedcenter        \spac_align_set_horizontal_center
780\let\raggedright         \spac_align_set_horizontal_right
781\let\veryraggedleft      \spac_align_set_horizontal_very_left
782\let\veryraggedcenter    \spac_align_set_horizontal_very_center
783\let\veryraggedright     \spac_align_set_horizontal_very_right
784\let\raggedwidecenter    \spac_align_set_horizontal_wide_center
785\let\centeredlastline    \spac_align_set_horizontal_centered_last_line
786\let\flushedrightlastline\spac_align_set_horizontal_flushedright_last_line
787\let\ttraggedright       \spac_align_set_horizontal_right_tt            % a plain command
788
789\let\forgetragged      \spac_align_set_horizontal_none
790
791\appendtoks
792    \spac_align_set_horizontal_none
793\to \everyforgetall
794
795% Box commands.
796
797\unexpanded\def\ibox
798  {\vbox\bgroup
799     \forgetall
800     \let\\\endgraf
801     \ifdoublesided\signalinnerrealign\fi
802     \doifelserightpage\spac_align_set_horizontal_right\spac_align_set_horizontal_left
803     \let\next}
804
805\unexpanded\def\obox
806  {\vbox\bgroup
807     \forgetall
808     \let\\\endgraf
809     \ifdoublesided\signalouterrealign\fi
810     \doifelserightpage\spac_align_set_horizontal_left\spac_align_set_horizontal_right
811     \let\next}
812
813\let\raggedbox\relax
814
815\def\dosetraggedvbox#1% can be more keys .. how about caching here (but seldom used)
816  {\let\raggedbox\vbox
817   \processcommacommand[#1]\spac_align_set_ragged_vbox}
818
819\def\dosetraggedhbox#1% can be more keys .. how about caching here (but seldom used)
820  {\let\raggedbox\hbox
821   \processcommacommand[#1]\spac_align_set_ragged_hbox}
822
823\def\spac_align_set_ragged_vbox#1%
824  {\ifcsname\??alignvertical#1\endcsname
825     \lastnamedcs
826     \quitcommalist
827   \fi}
828
829\def\spac_align_set_ragged_hbox#1%
830  {\ifcsname\??alignhorizontal#1\endcsname
831     \lastnamedcs
832     \quitcommalist
833   \fi}
834
835% \def\usealignparametersethbox#1%
836%   {\edef\p_spac_align{#1\c!align}%
837%    \let\raggedbox\hbox
838%    \ifx\p_spac_align\empty \else
839%      \processcommacommand[\p_spac_align]\spac_align_set_ragged_hbox
840%    \fi}
841%
842% \def\usealignparametersetvbox#1%
843%   {\edef\p_spac_align{#1\c!align}%
844%    \let\raggedbox\vbox
845%    \ifx\p_spac_align\empty \else
846%      \processcommacommand[\p_spac_align]\spac_align_set_ragged_vbox
847%    \fi}
848
849\setvalue{\??alignvertical  \v!left      }{\let\raggedbox\lbox}
850\setvalue{\??alignvertical  \v!right     }{\let\raggedbox\rbox}
851\setvalue{\??alignvertical  \v!middle    }{\let\raggedbox\cbox}
852\setvalue{\??alignvertical  \v!inner     }{\let\raggedbox\ibox}
853\setvalue{\??alignvertical  \v!outer     }{\let\raggedbox\obox}
854\setvalue{\??alignvertical  \v!flushleft }{\let\raggedbox\rbox}
855\setvalue{\??alignvertical  \v!flushright}{\let\raggedbox\lbox}
856\setvalue{\??alignvertical  \v!center    }{\let\raggedbox\cbox}
857\setvalue{\??alignvertical  \v!no        }{\def\raggedbox{\vbox\bgroup\spac_align_set_horizontal_right\let\next=}]}
858
859% maybe \let's
860
861\setvalue{\??alignhorizontal\v!left      }{\def\raggedbox{\doalignedline\v!left  }}
862\setvalue{\??alignhorizontal\v!right     }{\def\raggedbox{\doalignedline\v!right }}
863\setvalue{\??alignhorizontal\v!middle    }{\def\raggedbox{\doalignedline\v!middle}}
864\setvalue{\??alignhorizontal\v!inner     }{\def\raggedbox{\doalignedline\v!inner }}
865\setvalue{\??alignhorizontal\v!outer     }{\def\raggedbox{\doalignedline\v!outer }}
866\setvalue{\??alignhorizontal\v!flushleft }{\def\raggedbox{\doalignedline\v!right }}
867\setvalue{\??alignhorizontal\v!flushright}{\def\raggedbox{\doalignedline\v!left  }}
868\setvalue{\??alignhorizontal\v!center    }{\def\raggedbox{\doalignedline\v!middle}}
869
870% The next one can be in use so we keep it around but oen should
871% be aware of possible interference.
872
873\unexpanded\def\setraggedskips#1#2#3#4#5#6#7% never change this name (todo: inline this one .. less tracingall)
874  {\unexpanded\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
875   \updateraggedskips}
876
877\def\dosetraggedskips#1#2#3#4#5#6#7%
878  {\raggedstatus                 #1\relax
879   \leftskip   1\leftskip \s!plus#2\relax
880   \rightskip  1\rightskip\s!plus#3\relax
881   \spaceskip                    #4\relax
882   \xspaceskip                   #5\relax
883   \parfillskip \zeropoint\s!plus#6\relax
884   \parindent                    #7\relax
885   \c_attr_alignstate\ifcase\raggedstatus\attributeunsetvalue\else\raggedstatus\fi}
886
887% older (context) names:
888
889\let\spaceamount  \interwordspace
890\let\emspaceamount\emwidth
891
892% tracing:
893
894\def\spac_show_par_data#1%
895  {\ifx#1\relax\else
896     \hbox{\string#1: \the#1}\endgraf
897     \expandafter\spac_show_par_data
898   \fi}
899
900\unexpanded\def\showpardata
901  {\edef\thepardata
902     {\hbox{font: \fontname\font}\endgraf
903      \spac_show_par_data
904        \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
905        \hsize     \vsize
906        \leftskip  \rightskip
907        \spaceskip \xspaceskip
908        \parindent \parfillskip
909        \hyphenpenalty \exhyphenpenalty \automatichyphenpenalty \explicithyphenpenalty
910        \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty
911        \doublehyphendemerits \finalhyphendemerits \adjdemerits
912      \relax}%
913   \dontleavehmode
914   \begingroup
915   \inleftmargin{\vsmash{\infofont\framed[\c!align=\v!right]{\thepardata}}}%
916   \endgroup
917   \let\showpardata\relax}
918
919\unexpanded\def\startshowpardata
920  {\begingroup
921   \showstruts
922   \tracingparagraphs\maxdimen
923   \appendtoksonce\showpardata\to\everypar}
924
925\unexpanded\def\stopshowpardata
926  {\endgraf
927   \endgroup}
928
929% Structure:
930
931\unexpanded\def\startalignment
932  {\par
933   \begingroup
934   \setupalign}
935
936\unexpanded\def\stopalignment
937  {\par
938   \endgroup}
939
940\setnewconstant\alignstrutmode\plusone
941
942% see later for the real definition, which in the simple case is:
943
944\newtoks \everyleftofalignedline
945\newtoks \everyrightofalignedline
946
947\unexpanded\def\shiftalignedline#1#2#3#4% left, right, inner, outer
948  {\rightorleftpageaction
949     {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
950      \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
951     {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
952      \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}
953
954\def\doalignline#1#2% \\ == newline
955  {\noindentation  % was \noindent
956   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
957   \begingroup
958   \setlocalhsize % new
959   \protected\def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
960   \dowithnextbox
961     {\hbox to \localhsize
962        {\ifcase\alignstrutmode\or\strut\fi
963         \the\everyleftofalignedline
964         #1\unhbox\nextbox#2\relax
965         \the\everyrightofalignedline}%
966      \endgroup}
967     \hbox}
968
969% plain commands
970
971\ifdefined\line       \else \def\line        {\hbox to\hsize}    \fi
972\ifdefined\leftline   \else \def\leftline  #1{\line{#1\hss}}     \fi
973\ifdefined\rightline  \else \def\rightline #1{\line{\hss#1}}     \fi
974\ifdefined\centerline \else \def\centerline#1{\line{\hss#1\hss}} \fi
975
976% direct commands
977
978\installcorenamespace{alignwrapper}
979
980\setuvalue{\??alignwrapper\v!left  }{\doalignline\relax \hss  }
981\setuvalue{\??alignwrapper\v!middle}{\doalignline\hss   \hss  }
982\setuvalue{\??alignwrapper\v!right }{\doalignline\hss   \relax}
983\setuvalue{\??alignwrapper\v!max   }{\doalignline\relax \relax}
984
985\def\spac_align_wrapper_middle      {\doalignline\hss   \hss}
986
987\def\spac_align_wrapper_handle#1%
988 %{\csname\??alignwrapper\ifcsname\??alignwrapper#1\endcsname#1\else\v!middle\fi\endcsname}
989  {\ifcsname\??alignwrapper#1\endcsname\expandafter\lastnamedcs\else\expandafter\spac_align_wrapper_middle\fi}
990
991\unexpanded\def\spac_align_wrapper_start[#1]%
992  {\spac_align_wrapper_handle{#1}%
993   \bgroup\ignorespaces}
994
995\unexpanded\def\spac_align_wrapper_stop
996  {\removeunwantedspaces\egroup}
997
998\unexpanded\def\startlinealignment
999  {\dosingleempty\spac_align_wrapper_start}
1000
1001\let\stoplinealignment\spac_align_wrapper_stop
1002
1003\unexpanded\def\startleftaligned  {\spac_align_wrapper_start[\v!left  ]}  \let\stopleftaligned  \spac_align_wrapper_stop
1004\unexpanded\def\startmiddlealigned{\spac_align_wrapper_start[\v!middle]}  \let\stopmiddlealigned\spac_align_wrapper_stop
1005\unexpanded\def\startrightaligned {\spac_align_wrapper_start[\v!right ]}  \let\stoprightaligned \spac_align_wrapper_stop
1006\unexpanded\def\startmaxaligned   {\spac_align_wrapper_start[\v!max   ]}  \let\stopmaxaligned   \spac_align_wrapper_stop
1007
1008\let\startmidaligned   \startmiddlealigned  \let\stopmidaligned   \stopmiddlealigned
1009\let\startcenteraligned\startmiddlealigned  \let\stopcenteraligned\stopmiddlealigned
1010
1011\unexpanded\def\leftaligned  {\spac_align_wrapper_handle\v!left  }
1012\unexpanded\def\middlealigned{\spac_align_wrapper_handle\v!middle}
1013\unexpanded\def\rightaligned {\spac_align_wrapper_handle\v!right }
1014\unexpanded\def\maxaligned   {\spac_align_wrapper_handle\v!max   }
1015
1016\let\midaligned   \middlealigned
1017\let\centeraligned\middlealigned
1018
1019\installcorenamespace{alignline}
1020
1021\letvalue{\??alignline\v!left      }\leftaligned
1022\letvalue{\??alignline\v!right     }\rightaligned
1023\letvalue{\??alignline\v!middle    }\midaligned
1024\letvalue{\??alignline\v!flushleft }\rightaligned % beware, makes no sense in locations / we will have a special locations handler
1025\letvalue{\??alignline\v!flushright}\leftaligned  % beware, makes no sense in locations / we will have a special locations handler
1026\letvalue{\??alignline\v!center    }\midaligned
1027\letvalue{\??alignline\v!max       }\maxaligned
1028
1029\def\doalignedline#1{\resetrealignsignal\csname\??alignline#1\endcsname}
1030
1031%D Experimental (will be redone when floats are redone as it's real messy
1032%D now). It can also be made faster (if needed).
1033
1034\def\doxalignline#1#2#3#4#5#6%
1035  {\noindentation  % was \noindent
1036   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
1037   \begingroup
1038   \setlocalhsize
1039   \protected\def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
1040   \dowithnextbox
1041     {\hbox to \localhsize
1042        {#1\hskip\ifdone#2\else#3\fi#4%
1043         \hbox to \localhsize
1044           {\the\everyleftofalignedline
1045            \ifcase\alignstrutmode\or\strut\fi
1046            \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
1047            \the\everyrightofalignedline}%
1048         \hss}%
1049        \endgroup}
1050     \hbox}
1051
1052\def\doxcheckline % used for floats so multipass anyway
1053  {\signalrightpage\doifelserightpage\donetrue\donefalse}
1054
1055\setvalue{\??alignline\v!inner      }{\doxalignline\doxcheckline++\zeropoint       \relax\hss  }
1056\setvalue{\??alignline\v!outer      }{\doxalignline\doxcheckline++\zeropoint       \hss  \relax}
1057\setvalue{\??alignline\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss  }
1058\setvalue{\??alignline\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss  \relax}
1059\setvalue{\??alignline\v!inneredge  }{\doxalignline\doxcheckline-+\inneredgetotal  \relax\hss  }
1060\setvalue{\??alignline\v!outeredge  }{\doxalignline\doxcheckline+-\outeredgetotal  \hss  \relax}
1061\setvalue{\??alignline\v!backspace  }{\doxalignline\doxcheckline-+\backspace       \relax\hss  }
1062\setvalue{\??alignline\v!cutspace   }{\doxalignline\doxcheckline+-\cutspace        \hss  \relax}
1063
1064\setvalue{\??alignline\v!leftmargin }{\doxalignline\donefalse   --\leftmargintotal \hss  \relax}
1065\setvalue{\??alignline\v!rightmargin}{\doxalignline\donefalse   ++\rightmargintotal\relax\hss  }
1066\setvalue{\??alignline\v!leftedge   }{\doxalignline\donefalse   --\leftedgetotal   \hss  \relax}
1067\setvalue{\??alignline\v!rightedge  }{\doxalignline\donefalse   ++\rightedgetotal  \relax\hss  }
1068
1069\def\doalignedline#1% unchecked
1070  {\csname\??alignline#1\endcsname} % no \resetrealignsignal here ?
1071
1072\def\alignedline#1#2% setting default
1073 % {\csname\??alignline\ifcsname\??alignline#1\endcsname#1\else#2\fi\endcsname}
1074  {\ifcsname\??alignline#1\endcsname
1075     \expandafter\lastnamedcs
1076   \else
1077     \csname\??alignline#2\expandafter\endcsname
1078   \fi}
1079
1080% beware: \wordright{whatever\kern-\rightskip} should work!
1081% so, no funny boxing here
1082
1083\unexpanded\def\wordright
1084  {\dosingleempty\spac_word_right}
1085
1086\def\spac_word_right[#1]%
1087  {% don't change
1088   \groupedcommand
1089     {\removeunwantedspaces
1090      \hfill
1091      \allowbreak % changed back from \hskip\zeropoint
1092      \strut
1093      \hfill
1094      \quad % decent spacing
1095      \hbox}
1096     {\doifelse{#1}\v!right{\kern-\rightskip}{\doifsomething{#1}{\kern-#1}}%
1097      \parfillskip\zeropoint
1098      \finalhyphendemerits\zerocount % yes or no (see hyhenation/specialcases-001.tex)
1099      \par}}
1100
1101% \dorecurse{5}{something} \wordright{--someone} \endgraf
1102% \dorecurse{6}{something} \wordright{--someone} \endgraf
1103% \dorecurse{7}{something} \wordright{--someone} \endgraf
1104%
1105% \dorecurse{5}{something} \wordright{--someone else entirely} \endgraf
1106% \dorecurse{6}{something} \wordright{--someone else entirely} \endgraf
1107% \dorecurse{7}{something} \wordright{--someone else entirely} \endgraf
1108%
1109% \wordright[\rightskip]{whatever}
1110
1111% Trick posted by WS on mailing list, generalized a bit. The bottom text only shows
1112% op when there is one line space available. We could add some extra space if needed.
1113
1114% \unexpanded\def\bottomword
1115%   {\par
1116%    \dowithnextbox
1117%      {\leaders\box\nextbox\vfil\page}
1118%      \vbox to \lineheight}
1119%
1120% \unexpanded\def\bottomword
1121%   {\par
1122%    \groupedcommand
1123%      {\leaders
1124%       \vbox to \lineheight\bgroup}
1125%      {\egroup
1126%       \vfil
1127%       \page}}
1128
1129% \simplealignedbox{2cm}{right}{x}
1130
1131\installcorenamespace{alignsimple}
1132\installcorenamespace{alignsimplereverse}
1133
1134% todo: also handle \bgroup ... \egroup
1135
1136\unexpanded\def\spac_align_simple_left  #1{{#1\hss}}
1137\unexpanded\def\spac_align_simple_right #1{{\hss#1}}
1138\unexpanded\def\spac_align_simple_middle#1{{\hss#1\hss}}
1139
1140\letvalue{\??alignsimple       \v!right     }\spac_align_simple_left
1141\letvalue{\??alignsimple       \v!outer     }\spac_align_simple_left   % not managed! see linenumbers
1142\letvalue{\??alignsimple       \v!flushleft }\spac_align_simple_left
1143\letvalue{\??alignsimple       \v!left      }\spac_align_simple_right
1144\letvalue{\??alignsimple       \v!inner     }\spac_align_simple_right  % not managed! see linenumbers
1145\letvalue{\??alignsimple       \v!flushright}\spac_align_simple_right
1146\letvalue{\??alignsimple       \v!middle    }\spac_align_simple_middle
1147
1148\letvalue{\??alignsimplereverse\v!right     }\spac_align_simple_right
1149\letvalue{\??alignsimplereverse\v!outer     }\spac_align_simple_right % not managed! see linenumbers
1150\letvalue{\??alignsimplereverse\v!flushleft }\spac_align_simple_right
1151\letvalue{\??alignsimplereverse\v!left      }\spac_align_simple_left
1152\letvalue{\??alignsimplereverse\v!inner     }\spac_align_simple_left  % not managed! see linenumbers
1153\letvalue{\??alignsimplereverse\v!flushright}\spac_align_simple_left
1154\letvalue{\??alignsimplereverse\v!middle    }\spac_align_simple_middle
1155
1156\unexpanded\def\simplealignedbox#1#2%
1157  {\hbox \ifdim#1>\zeropoint to #1
1158     \ifcsname\??alignsimple#2\endcsname
1159       \doubleexpandafter\lastnamedcs
1160     \else
1161       \doubleexpandafter\spac_align_simple_left
1162     \fi
1163   \fi}
1164
1165\unexpanded\def\simplealignedspreadbox#1#2%
1166  {\hbox \ifdim#1>\zeropoint spread #1
1167     \ifcsname\??alignsimple#2\endcsname
1168       \doubleexpandafter\lastnamedcs
1169     \else
1170       \doubleexpandafter\spac_align_simple_left
1171     \fi
1172   \fi}
1173
1174\unexpanded\def\simplealignedboxplus#1#2#3%
1175  {\hbox #3 \ifdim#1>\zeropoint to #1
1176     \ifcsname\??alignsimple#2\endcsname
1177       \doubleexpandafter\lastnamedcs
1178     \else
1179       \doubleexpandafter\spac_align_simple_left
1180     \fi
1181   \fi}
1182
1183\newconditional\alignsimplelefttoright \settrue\alignsimplelefttoright
1184
1185\unexpanded\def\simplereversealignedbox#1#2%
1186  {\hbox \ifdim#1>\zeropoint to #1
1187     \ifcsname\??alignsimplereverse#2\endcsname
1188       \doubleexpandafter\lastnamedcs
1189     \else
1190       \doubleexpandafter\spac_align_simple_left
1191     \fi
1192   \fi}
1193
1194\unexpanded\def\simplereversealignedboxplus#1#2#3%
1195  {\hbox #3 \ifdim#1>\zeropoint to #1
1196     \ifcsname\??alignsimplereverse#2\endcsname
1197       \doubleexpandafter\lastnamedcs
1198     \else
1199       \doubleexpandafter\spac_align_simple_left
1200     \fi
1201   \fi}
1202
1203% \installnamespace{alignsets}
1204%
1205% \setvalue{\??alignsets\v!right     }#1#2{\let#1\relax\let#2\hss  }
1206% \setvalue{\??alignsets\v!left      }#1#2{\let#1\hss  \let#2\relax}
1207% \setvalue{\??alignsets\v!flushright}#1#2{\let#1\hss  \let#2\relax}
1208% \setvalue{\??alignsets\v!flushleft }#1#2{\let#1\relax\let#2\hss  }
1209% \setvalue{\??alignsets\v!middle    }#1#2{\let#1\hss  \let#2\hss  }
1210% \setvalue{\??alignsets\v!low       }#1#2{\let#1\vss  \let#2\relax}
1211% \setvalue{\??alignsets\v!high      }#1#2{\let#1\relax\let#2\vss  }
1212% \setvalue{\??alignsets\v!lohi      }#1#2{\let#1\vss  \let#2\vss  }
1213% \setvalue{\??alignsets\s!unknown   }#1#2{\let#1\relax\let#2\relax}
1214%
1215% \unexpanded\def\spac_align_set_ss#1%
1216%   {\csname\??alignsetss\ifcsname\??alignsetss#1\endcsname#1\else\s!unknown\fi\endcsname}
1217
1218% Some obsolete (old) helpers:
1219
1220\unexpanded\def\definehbox
1221  {\dodoubleargument\spac_align_definehbox}
1222
1223\def\spac_align_definehbox[#1][#2]%
1224  {\setvalue{hbox#1}##1{\hbox to #2{\begstrut##1\endstrut\hss}}}
1225
1226%D Some direction related helpers:
1227
1228\installcorenamespace {reverse}
1229
1230\setvalue{\??reverse\v!normal }{\ifconditional\inlinelefttoright\else\s!reverse\fi}
1231\setvalue{\??reverse\v!reverse}{\ifconditional\inlinelefttoright     \s!reverse\fi}
1232
1233\let\usedirectionparameterreverse\gobbleoneargument
1234
1235\protect \endinput
1236