%D \module %D [ file=spac-ali, %D version=2009.10.16, % 1997.03.31, was core-spa.tex %D title=\CONTEXT\ Spacing Macros, %D subtitle=Alignments, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Spacing Macros / Alignments} \unprotect %D The \type {new} and \type {old} methods are gone as we now have \type %D {flush*} variants. Starting at the last day of 2011 both methods are %D merged into one and caching has been added, which makes switching %D twice as fast. % Todo: find a way to force last lines to have some distance from the right % edge (problem: keywords or presets), maybe a plugin % % \setupalign[...,myoption] % last % % but that also means myoption gets frozen due to caching. \registerctxluafile{spac-ali}{optimize} \definesystemattribute[realign] [public] % might be combined with the next one \definesystemattribute[alignstate][public] % will make a single attributes for several states \appendtoks \c_attr_realign \attributeunsetvalue \c_attr_alignstate\attributeunsetvalue \to \everyforgetall \unexpanded\def\resetrealignsignal{\c_attr_realign\attributeunsetvalue} \unexpanded\def\signalinnerrealign{\clf_setrealign\plustwo} \unexpanded\def\signalouterrealign{\clf_setrealign\plusone} \installcorenamespace{aligncommand} \installcorenamespace{alignhorizontal} \installcorenamespace{alignvertical} \installcorenamespace{alignmentnormalcache} \installcorenamespace{alignmentraggedcache} % nasty hack: \installcorenamespace{alignmentnormalcacheodd} \installcorenamespace{alignmentnormalcacheeven} \installcorenamespace{alignmentraggedcacheodd} \installcorenamespace{alignmentraggedcacheeven} \def\??alignmentnormalcache{\ifodd\realpageno\??alignmentnormalcacheodd\else\??alignmentnormalcacheeven\fi} \def\??alignmentraggedcache{\ifodd\realpageno\??alignmentraggedcacheodd\else\??alignmentraggedcacheeven\fi} \newtoks\everyresetalign % todo % This will become a more advanced layout controller soon: \newconditional\layoutlefttoright \settrue\layoutlefttoright \newconditional\displaylefttoright \settrue\displaylefttoright \newconditional\inlinelefttoright \settrue\inlinelefttoright \unexpanded\def\lefttoright {\ifvmode \spac_directions_lefttoright_vmode \else \spac_directions_lefttoright_hmode \fi} \unexpanded\def\righttoleft {\ifvmode \spac_directions_righttoleft_vmode \else \spac_directions_righttoleft_hmode \fi} \unexpanded\def\spac_directions_lefttoright_vmode {\settrue\displaylefttoright \settrue\inlinelefttoright \textdirection\directionlefttoright \pardirection \directionlefttoright} \unexpanded\def\spac_directions_righttoleft_vmode {\setfalse\displaylefttoright \setfalse\inlinelefttoright \textdirection\directionrighttoleft \pardirection \directionrighttoleft} \unexpanded\def\spac_directions_lefttoright_hmode {\linedirection\directionlefttoright % linedir keeps subtype of skip \settrue\inlinelefttoright} \unexpanded\def\spac_directions_righttoleft_hmode {\linedirection\directionrighttoleft % linedir keeps subtype of skip \setfalse\inlinelefttoright} \unexpanded\def\synchronizelayoutdirection {\ifconditional\layoutlefttoright \spac_directions_synchronize_lr \else \spac_directions_synchronize_rl \fi} \unexpanded\def\synchronizedisplaydirection {\ifconditional\displaylefttoright \spac_directions_synchronize_lr \else \spac_directions_synchronize_rl \fi} \def\spac_directions_synchronize_lr {\settrue\inlinelefttoright \textdirection\directionlefttoright \pardirection \directionlefttoright} \def\spac_directions_synchronize_rl {\setfalse\inlinelefttoright \textdirection\directionrighttoleft \pardirection \directionrighttoleft} \unexpanded\def\synchronizeinlinedirection {% why not \linedirection here \textdirection\ifconditional\inlinelefttoright\directionlefttoright\else\directionrighttoleft\fi} \unexpanded\def\checkedlefttoright {\ifvmode \spac_directions_lefttoright_vmode \else \spac_directions_lefttoright_hmode_checked \fi} \unexpanded\def\checkedrighttoleft {\ifvmode \spac_directions_righttoleft_vmode \else \spac_directions_righttoleft_hmode_checked \fi} \unexpanded\def\spac_directions_lefttoright_hmode_checked {\ifconditional\inlinelefttoright\else \lefttoright \fi} \unexpanded\def\spac_directions_righttoleft_hmode_checked {\ifconditional\inlinelefttoright \righttoleft \fi} \installcorenamespace{bidi} \letvalue{\??bidi\v!left }\checkedlefttoright \letvalue{\??bidi l2r}\checkedlefttoright \letvalue{\??bidi\v!right}\checkedrighttoleft \letvalue{\??bidi r2l}\checkedrighttoleft \unexpanded\def\usebidiparameter#1% {\begincsname\??bidi#1\c!bidi\endcsname} \unexpanded\def\showdirections {\dontleavehmode \begingroup\infofont\textdirection\directionlefttoright[\space layout: \ifconditional\layoutlefttoright l2r\else r2l\fi\space display: \ifconditional\displaylefttoright l2r\else r2l\fi\space inline: \ifconditional\inlinelefttoright l2r\else r2l\fi\space ]\endgroup} \unexpanded\def\righttolefthbox#1#{\reversehbox#1\bgroup\righttoleft\let\next} \let\rtlhbox\righttolefthbox \unexpanded\def\lefttorighthbox#1#{\naturalhbox#1\bgroup\lefttoright\let\next} \let\ltrhbox\lefttorighthbox \unexpanded\def\righttoleftvbox#1#{\reversevbox#1\bgroup\righttoleft\let\next} \let\rtlvbox\righttoleftvbox \unexpanded\def\lefttorightvbox#1#{\naturalvbox#1\bgroup\lefttoright\let\next} \let\ltrvbox\lefttorightvbox \unexpanded\def\righttoleftvtop#1#{\reversevtop#1\bgroup\righttoleft\let\next} \let\rtlvtop\righttoleftvtop \unexpanded\def\lefttorightvtop#1#{\naturalvtop#1\bgroup\lefttoright\let\next} \let\ltrvtop\lefttorightvtop \unexpanded\def\autodirhbox#1#{\hbox#1\bgroup\synchronizeinlinedirection\let\next} \unexpanded\def\autodirvbox#1#{\vbox#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vbox \unexpanded\def\autodirvtop#1#{\vtop#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vtop \unexpanded\def\leftorrighthbox{\ifconditional\displaylefttoright\expandafter\lefttorighthbox\else\expandafter\righttolefthbox\fi} \unexpanded\def\leftorrightvbox{\ifconditional\displaylefttoright\expandafter\lefttorightvbox\else\expandafter\righttoleftvbox\fi} \unexpanded\def\leftorrightvtop{\ifconditional\displaylefttoright\expandafter\lefttorightvtop\else\expandafter\righttoleftvtop\fi} \unexpanded\def\rtltext{\groupedcommand{\dontleavehmode\righttoleft\ignorespaces}\removeunwantedspaces} \unexpanded\def\ltrtext{\groupedcommand{\dontleavehmode\lefttoright\ignorespaces}\removeunwantedspaces} % Tolerance and hyphenation \ifdefined\lesshyphens \else \let\lesshyphens\relax \fi \ifdefined\morehyphens \else \let\morehyphens\relax \fi \ifdefined\nohyphens \else \let\nohyphens \relax \fi \ifdefined\dohyphens \else \let\dohyphens \relax \fi \newconstant\c_spac_tolerance_default \c_spac_tolerance_default 1500 % shouldn't that be 200 \newconstant\c_spac_tolerance_minimum \c_spac_tolerance_minimum 1500 \newconstant\c_spac_tolerance_normal \c_spac_tolerance_normal 3000 \newconstant\c_spac_tolerance_extreme \c_spac_tolerance_extreme 4500 \def\spac_align_set_raggedness_left {\plustwo\bodyfontsize} \def\spac_align_set_raggedness_right {\plustwo\bodyfontsize} \def\spac_align_set_raggedness_middle{\plussix\bodyfontsize} % overloaded below % oeps, hsize can be 0pt in which case we get a strange division % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{} \def\spac_align_set_raggedness_middle{\ifzeropt\hsize\plussix\bodyfontsize\else.5\hsize\fi} \unexpanded\def\setraggedness#1% tricky .. we keep the global tolerance otherwise ... to be reconsidered {\ifnum\tolerance<\c_spac_tolerance_minimum \tolerance\c_spac_tolerance_minimum % small values have unwanted side effects \else % todo: take set value or none .. better done elsewhere (200 is normal) \fi \ifx\dohyphens\relax % was 2.5 in old implementation using scratch registers \hyphenpenalty\dimexpr2.8\hsize/\dimexpr#1\relax\relax % 50 in raggedright/raggedleft %\else % no need to do something as we're in \nohyphens \fi} \unexpanded\def\spac_align_set_tolerant {\tolerance\c_spac_tolerance_normal} \unexpanded\def\spac_align_set_very_tolerant {\tolerance\c_spac_tolerance_extreme} \unexpanded\def\spac_align_set_stretch {\emergencystretch\bodyfontsize} \unexpanded\def\spac_align_set_extreme_stretch {\emergencystretch10\bodyfontsize} % Vertical \newconstant\c_spac_align_state_vertical \unexpanded\def\spac_align_set_vertical_none {\let\raggedtopcommand \relax \let\raggedbottomcommand\relax} \unexpanded\def\spac_align_set_vertical_lohi {\let\raggedtopcommand \vfilll \let\raggedbottomcommand\vfilll} \unexpanded\def\spac_align_set_vertical_low {\let\raggedtopcommand \vfilll \let\raggedbottomcommand\relax} \unexpanded\def\spac_align_set_vertical_high {\let\raggedtopcommand \relax \let\raggedbottomcommand\vfilll} \def\spac_align_flush_vertical {\ifcase\c_spac_align_state_vertical \spac_align_set_vertical_none \or \spac_align_set_vertical_lohi \or \spac_align_set_vertical_low \or \spac_align_set_vertical_high \fi} % Horizontal \ifdefined\raggedonelinerstate \else \newconditional\raggedonelinerstate % public \fi % \appendtoks % \setfalse\raggedonelinerstate % \to \everyforgetall \newconstant\raggedstatus % public \newconstant\c_spac_align_state_horizontal \newconstant\c_spac_align_state_broad \newconstant\c_spac_align_state_par_fill \def\v_spac_align_fill_amount {\plusone fil} \def\v_spac_align_fill_amount_hard {\plusone fill} \def\v_spac_align_fill_amount_extreme {\plustenthousand filll} \def\v_spac_align_fill_amount_negative {\minusone fil} \def\v_spac_align_fill_amount_double {\plustwo fil} \def\v_spac_align_fill_amount_space {\plustwo fil} % can be added to xspace if we have a key \def\v_spac_align_fill_amount_half {.5fil} \let\v_spac_align_space_amount \interwordspace \def\v_spac_align_space_amount_x {.5\emwidth} \newskip\s_zero_plus_one_fil \s_zero_plus_one_fil = 0pt plus 1fil \newskip\s_zero_plus_zero \s_zero_plus_zero = 0pt plus 0pt % \s!plus ... slower than inline \unexpanded\def\spac_align_set_horizontal_none % should also relax \updateraggedskips {\raggedstatus\zerocount \c_attr_alignstate\attributeunsetvalue \leftskip \plusone\leftskip \rightskip \plusone\rightskip \spaceskip \zeropoint \xspaceskip \zeropoint \parfillskip\s_zero_plus_one_fil % new \setfalse\raggedonelinerstate % now here \let\updateraggedskips\relax} % no need for adaption \unexpanded\def\spac_align_set_horizontal_left {\setraggedness\spac_align_set_raggedness_left \raggedstatus\plusone \c_attr_alignstate\plusone \leftskip \plusone\leftskip \s!plus\spac_align_set_raggedness_left \rightskip \plusone\rightskip\s!plus\zeropoint \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_zero \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_center {\setraggedness\spac_align_set_raggedness_middle \raggedstatus\plustwo \c_attr_alignstate\plustwo \leftskip \plusone\leftskip \s!plus\spac_align_set_raggedness_middle \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_middle \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_zero \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_right {\setraggedness\spac_align_set_raggedness_right \raggedstatus\plusthree \c_attr_alignstate\plusthree \leftskip \plusone\leftskip \s!plus\zeropoint \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_right \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_one_fil %\parindent \parindent \relax} \unexpanded\def\spac_align_set_horizontal_very_left {\raggedstatus\plusone \c_attr_alignstate\plusone \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount \rightskip \plusone\rightskip\s!plus\zeropoint \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_zero \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_very_center {\raggedstatus\plustwo \c_attr_alignstate\plustwo \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_zero \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_very_right {\raggedstatus\plusthree \c_attr_alignstate\plusthree \leftskip \plusone\leftskip \s!plus\zeropoint \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_zero %\parindent \parindent \relax} \unexpanded\def\spac_align_set_horizontal_wide_center {\setraggedness\spac_align_set_raggedness_middle \raggedstatus\plustwo \c_attr_alignstate\plustwo \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount_half \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_half \spaceskip \v_spac_align_space_amount \xspaceskip \v_spac_align_space_amount_x \parfillskip\s_zero_plus_zero \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_centered_last_line {\raggedstatus\zerocount \c_attr_alignstate\attributeunsetvalue \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax \spaceskip \zeropoint\relax \xspaceskip \zeropoint\relax \parfillskip\zeropoint\s!plus\v_spac_align_fill_amount_double\relax \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_flushedright_last_line {\raggedstatus\zerocount \c_attr_alignstate\attributeunsetvalue \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax \spaceskip \zeropoint\relax \xspaceskip \zeropoint\relax \parfillskip \zeropoint \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax \parfillleftmode\plustwo % \plusone checks for multiple lines \parindent \zeropoint \relax} \unexpanded\def\spac_align_set_horizontal_right_tt % a plain command {\tttf % brrr \raggedstatus\plusthree \c_attr_alignstate\plusthree \leftskip \plusone\leftskip \s!plus\zeropoint\relax \rightskip \plusone\rightskip\s!plus\spac_align_set_raggedness_right\relax \spaceskip \zeropoint\relax \xspaceskip \zeropoint\relax \parfillskip\s_zero_plus_zero %\parindent \parindent \relax} \unexpanded\def\spac_align_set_horizontal_extra {\xspaceskip\zeropoint\s!plus\v_spac_align_fill_amount_space\relax} \def\spac_align_flush_horizontal {\ifcase\c_spac_align_state_horizontal % 0 \spac_align_set_horizontal_none \or % 1 center \ifcase\c_spac_align_state_broad \spac_align_set_horizontal_center \or \spac_align_set_horizontal_very_center \or \spac_align_set_horizontal_wide_center \fi \or % 2 flush left \ifcase\c_spac_align_state_broad \spac_align_set_horizontal_right \else \spac_align_set_horizontal_very_right \fi \or % 3 flush right \ifcase\c_spac_align_state_broad \spac_align_set_horizontal_left \else \spac_align_set_horizontal_very_left \fi \or % 4 inner \ifdoublesided \signalinnerrealign \fi \rightorleftpageaction\spac_align_set_horizontal_right\spac_align_set_horizontal_left \or % 5 outer \ifdoublesided \signalouterrealign \fi \rightorleftpageaction\spac_align_set_horizontal_left\spac_align_set_horizontal_right \or % 6 oneliner \ifcase\c_spac_align_state_broad \spac_align_set_horizontal_right \else \spac_align_set_horizontal_very_right \fi \parfillskip\zeropoint \or % 7 centered last line \spac_align_set_horizontal_centered_last_line \or % 8 right aligned last line \spac_align_set_horizontal_flushedright_last_line \or % 9 paragraph \parfillskip\zeropoint \fi \relax} % Page spacing: \newconstant\c_spac_align_state_page \def\bottomalignlimit{\plusthree\lineheight} \newconstant\bottomraggednessmode % 0=ragged 1=normal/align 2=baseline \unexpanded\def\raggedbottom {\bottomraggednessmode\zerocount \settopskip} \unexpanded\def\alignbottom {\bottomraggednessmode\plusone \settopskip} \unexpanded\def\baselinebottom {\bottomraggednessmode\plustwo \settopskip} \let\normalbottom\alignbottom % downward compatible \unexpanded\def\setbottomalignmode#1% {\bottomraggednessmode#1% \settopskip} \def\spac_align_flush_page {\ifcase\c_spac_align_state_page % keep state \or \raggedbottom \or \alignbottom \or \baselinebottom \fi} % Directions \newconstant\c_spac_align_state_direction \def\spac_align_flush_direction {\ifcase\c_spac_align_state_direction % keep state \or \lefttoright \or \righttoleft \fi} % Interesting is that the non cached version is also pretty efficient % and as we cache we seldom call that one now so one can debate the % speedup. \newtoks\t_spac_align_collected \let\raggedcommand \relax \let\updateraggedskips\relax \def\spac_align_add_to_cache {\let\raggedbox\relax % why % we inherit hyphenation and tolerance \t_spac_align_collected \emptytoks \c_spac_align_state_broad \zerocount \c_spac_align_state_horizontal\zerocount \c_spac_align_state_vertical \zerocount \c_spac_align_state_direction \zerocount % what is default ? \c_spac_align_state_page \zerocount \c_spac_align_state_par_fill \zerocount \ifcsname\??aligncommand\m_spac_align_asked\endcsname \lastnamedcs \else \rawprocesscommacommand[\m_spac_align_asked]\spac_align_collect \fi \normalexpanded{\t_spac_align_collected {% \resetrealignsignal % can go as it is always set \setfalse\raggedonelinerstate % bad \the\t_spac_align_collected \spac_align_flush_horizontal \spac_align_flush_vertical \spac_align_flush_direction \spac_align_flush_page \spac_align_flush_parfill }}% kept, nice for tracing \edef\raggedcommand {\the\t_spac_align_collected }% \edef\updateraggedskips{\spac_align_flush_horizontal}% \expandafter\glet\csname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand \expandafter\glet\csname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips} \def\spac_align_collect#1% {\csname\??aligncommand#1\endcsname} % The local (key driven) setter: \unexpanded\def\spac_align_prepare#1% deferred {\edef\m_spac_align_asked{#1}% \expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname \ifx\raggedcommand\relax \spac_align_add_to_cache \else \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname \fi} \let\dosetraggedcommand\spac_align_prepare % sort of public % The regular align setter: \unexpanded\def\setupalign {\dosingleempty\spac_align_setup} \def\spac_align_setup[#1]% immediate {\edef\m_spac_align_asked{#1}% \expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname \ifx\raggedcommand\relax \spac_align_add_to_cache \else \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname \fi \raggedcommand} \unexpanded\def\usealignparameter#1% faster local variant {\edef\m_spac_align_asked{#1\c!align}% \ifx\m_spac_align_asked\empty\else \spac_align_use_indeed \fi} \unexpanded\def\dousealignparameter#1% faster local variant {\edef\m_spac_align_asked{#1}% \ifx\m_spac_align_asked\empty\else \spac_align_use_indeed \fi} \def\spac_align_use_indeed {\expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname \ifx\raggedcommand\relax \spac_align_add_to_cache \else \expandafter\let\expandafter\updateraggedskips\csname\??alignmentraggedcache\m_spac_align_asked\endcsname \fi \raggedcommand} % experiment \unexpanded\def\spac_align_use_later#1% {\begingroup \edef\m_spac_align_asked{#1}% \expandafter\let\expandafter\raggedcommand\csname\??alignmentnormalcache\m_spac_align_asked\endcsname \ifx\raggedcommand\relax \spac_align_add_to_cache \fi \endgroup} \unexpanded\def\spac_align_use_now#1% {\csname\??alignmentnormalcache#1\endcsname} % Maybe we need something different in columns. \unexpanded\def\installalign#1#2% beware: commands must be unexpandable! {\ifcsname\??aligncommand#1\endcsname \else \setvalue{\??aligncommand#1}{\toksapp\t_spac_align_collected{#2}}% \fi} % beware, toks stuff and states are set at a differt time, so installalign is % only for special options % % \setvalue{\??aligncommand whatever}% % {\c_spac_align_state_horizontal\plushundred % \toksapp\t_spac_align_collected{.....}} % % this one could deal with both % % \unexpanded\def\installalignoption#1#2% % {\ifcsname\??aligncommand#1\endcsname \else % \setvalue{\??aligncommand#1}% % {\spac_align_set_horizontal_none % \c_spac_align_state_horizontal\plushundred % don't set % \toksapp\t_spac_align_collected{#2}}% % \fi} % % \installalignoption % {whatever} % {} % The keywords: \letvalue{\??aligncommand\empty }\empty \setvalue{\??aligncommand\v!broad }{\c_spac_align_state_broad \plusone } \setvalue{\??aligncommand\v!wide }{\c_spac_align_state_broad \plustwo } \setvalue{\??aligncommand\v!bottom }{\c_spac_align_state_page \plusone } \setvalue{\??aligncommand\v!height }{\c_spac_align_state_page \plustwo } \setvalue{\??aligncommand\v!line }{\c_spac_align_state_page \plusthree % this will become another keyword (undocumented anyway) \toksapp\t_spac_align_collected{\settrue\raggedonelinerstate}} \setvalue{\??aligncommand\v!high }{\c_spac_align_state_vertical \plusthree} \setvalue{\??aligncommand\v!low }{\c_spac_align_state_vertical \plustwo } \setvalue{\??aligncommand\v!lohi }{\c_spac_align_state_vertical \plusone } \setvalue{\??aligncommand\v!flushright }{\c_spac_align_state_horizontal\plusthree} \setvalue{\??aligncommand\v!flushleft }{\c_spac_align_state_horizontal\plustwo } \setvalue{\??aligncommand\v!middle }{\c_spac_align_state_horizontal\plusone } \setvalue{\??aligncommand\v!no }{\c_spac_align_state_horizontal\plustwo } \setvalue{\??aligncommand\v!yes }{\c_spac_align_state_horizontal\zerocount} \setvalue{\??aligncommand\v!width }{\c_spac_align_state_horizontal\zerocount} \setvalue{\??aligncommand\v!normal }{\c_spac_align_state_horizontal\zerocount} \setvalue{\??aligncommand\v!reset }{\c_spac_align_state_page \zerocount \c_spac_align_state_horizontal\zerocount} \setvalue{\??aligncommand\v!inner }{\c_spac_align_state_horizontal\plusfour } \setvalue{\??aligncommand\v!outer }{\c_spac_align_state_horizontal\plusfive } \setvalue{\??aligncommand\v!flushinner }{\c_spac_align_state_horizontal\plusfour } \setvalue{\??aligncommand\v!flushouter }{\c_spac_align_state_horizontal\plusfive } \setvalue{\??aligncommand\v!right }{\c_spac_align_state_horizontal\plustwo } \setvalue{\??aligncommand\v!left }{\c_spac_align_state_horizontal\plusthree} \setvalue{\??aligncommand\v!center }{\c_spac_align_state_horizontal\plusone \c_spac_align_state_broad \plustwo } \setvalue{\??aligncommand\v!disable }{\c_spac_align_state_horizontal\plussix } \setvalue{\??aligncommand\v!last }{\c_spac_align_state_horizontal\plusseven} \setvalue{\??aligncommand\v!end }{\c_spac_align_state_horizontal\pluseight} \setvalue{\??aligncommand\v!paragraph }{\c_spac_align_state_horizontal\plusnine} \setvalue{\??aligncommand\v!lefttoright }{\c_spac_align_state_direction \plusone } \setvalue{\??aligncommand\v!righttoleft }{\c_spac_align_state_direction \plustwo } \setvalue{\??aligncommand l2r}{\c_spac_align_state_direction \plusone } \setvalue{\??aligncommand r2l}{\c_spac_align_state_direction \plustwo } \setvalue{\??aligncommand\v!table }{\c_spac_align_state_vertical \plusthree \c_spac_align_state_broad \plusone \c_spac_align_state_horizontal\plustwo } \setvalue{\??aligncommand\v!lesshyphenation}{\toksapp\t_spac_align_collected{\lesshyphens}} \setvalue{\??aligncommand\v!morehyphenation}{\toksapp\t_spac_align_collected{\morehyphens}} \setvalue{\??aligncommand\v!hanging }{\toksapp\t_spac_align_collected{\font_protruding_enable }} \setvalue{\??aligncommand\v!hangingboth }{\toksapp\t_spac_align_collected{\font_protruding_enable_b}} \setvalue{\??aligncommand\v!nothanging }{\toksapp\t_spac_align_collected{\font_protruding_disable}} \setvalue{\??aligncommand\v!hz }{\toksapp\t_spac_align_collected{\font_expansion_enable }} \setvalue{\??aligncommand\v!fullhz }{\toksapp\t_spac_align_collected{\font_expansion_enable_k}} \setvalue{\??aligncommand\v!nohz }{\toksapp\t_spac_align_collected{\font_expansion_disable }} %setvalue{\??aligncommand\v!spacing }{\toksapp\t_spac_align_collected{\normalspacing\zerocount}} % not yet %setvalue{\??aligncommand\v!nospacing }{\toksapp\t_spac_align_collected{\normalspacing\plusone}} % not yet \setvalue{\??aligncommand\v!hyphenated }{\toksapp\t_spac_align_collected{\dohyphens}} \setvalue{\??aligncommand\v!nothyphenated }{\toksapp\t_spac_align_collected{\nohyphens}} \setvalue{\??aligncommand\v!tolerant }{\toksapp\t_spac_align_collected{\spac_align_set_tolerant}} \setvalue{\??aligncommand\v!verytolerant }{\toksapp\t_spac_align_collected{\spac_align_set_very_tolerant}} \setvalue{\??aligncommand\v!stretch }{\toksapp\t_spac_align_collected{\spac_align_set_stretch}} \setvalue{\??aligncommand\v!extremestretch }{\toksapp\t_spac_align_collected{\spac_align_set_extreme_stretch}} \setvalue{\??aligncommand \v!final}{\c_spac_align_state_par_fill\plusone} \setvalue{\??aligncommand1*\v!final}{\c_spac_align_state_par_fill\plusone} \setvalue{\??aligncommand2*\v!final}{\c_spac_align_state_par_fill\plustwo} % hardcoded multiplier \setvalue{\??aligncommand3*\v!final}{\c_spac_align_state_par_fill\plusthree} \setvalue{\??aligncommand4*\v!final}{\c_spac_align_state_par_fill\plusfour} % a one shot (only usefull in e.g. framed, also needs tolerance and stretch) \setvalue{\??aligncommand \v!more}{\toksapp\t_spac_align_collected{\looseness\plusone}} \setvalue{\??aligncommand1*\v!more}{\toksapp\t_spac_align_collected{\looseness\plusone}} \setvalue{\??aligncommand2*\v!more}{\toksapp\t_spac_align_collected{\looseness\plustwo}} \definehspace [\v!final] [\emspaceamount] \def\spac_align_flush_parfill {\ifcase\c_spac_align_state_par_fill\else \spac_align_flush_parfill_indeed{\number\c_spac_align_state_par_fill}% \fi} \unexpanded\def\spac_align_flush_parfill_indeed#1% {\parfillskip #1\directhspaceamount\v!final % plus \dimexpr\availablehsize-#1\directhspaceamount\v!final\relax plus 1fill \relax} %D For Wolfgang: \newtoks \t_spac_every_swap_align \appendtoks \setvalue{\??aligncommand\v!right}{\c_spac_align_state_horizontal\plusthree}% \setvalue{\??aligncommand\v!left }{\c_spac_align_state_horizontal\plustwo }% \to \t_spac_every_swap_align \unexpanded\def\enablereversealignment {\the\t_spac_every_swap_align \t_spac_every_swap_align\emptytoks} % Visible commands: \let\notragged \spac_align_set_horizontal_none \let\raggedleft \spac_align_set_horizontal_left \let\raggedcenter \spac_align_set_horizontal_center \let\raggedright \spac_align_set_horizontal_right \let\veryraggedleft \spac_align_set_horizontal_very_left \let\veryraggedcenter \spac_align_set_horizontal_very_center \let\veryraggedright \spac_align_set_horizontal_very_right \let\raggedwidecenter \spac_align_set_horizontal_wide_center \let\centeredlastline \spac_align_set_horizontal_centered_last_line \let\flushedrightlastline\spac_align_set_horizontal_flushedright_last_line \let\ttraggedright \spac_align_set_horizontal_right_tt % a plain command \let\forgetragged \spac_align_set_horizontal_none \appendtoks \spac_align_set_horizontal_none \to \everyforgetall % Box commands. \unexpanded\def\ibox {\vbox\bgroup \forgetall \let\\\endgraf \ifdoublesided\signalinnerrealign\fi \doifelserightpage\spac_align_set_horizontal_right\spac_align_set_horizontal_left \let\next} \unexpanded\def\obox {\vbox\bgroup \forgetall \let\\\endgraf \ifdoublesided\signalouterrealign\fi \doifelserightpage\spac_align_set_horizontal_left\spac_align_set_horizontal_right \let\next} \let\raggedbox\relax \def\dosetraggedvbox#1% can be more keys .. how about caching here (but seldom used) {\let\raggedbox\vbox \processcommacommand[#1]\spac_align_set_ragged_vbox} \def\dosetraggedhbox#1% can be more keys .. how about caching here (but seldom used) {\let\raggedbox\hbox \processcommacommand[#1]\spac_align_set_ragged_hbox} \def\spac_align_set_ragged_vbox#1% {\ifcsname\??alignvertical#1\endcsname \lastnamedcs \quitcommalist \fi} \def\spac_align_set_ragged_hbox#1% {\ifcsname\??alignhorizontal#1\endcsname \lastnamedcs \quitcommalist \fi} % \def\usealignparametersethbox#1% % {\edef\p_spac_align{#1\c!align}% % \let\raggedbox\hbox % \ifx\p_spac_align\empty \else % \processcommacommand[\p_spac_align]\spac_align_set_ragged_hbox % \fi} % % \def\usealignparametersetvbox#1% % {\edef\p_spac_align{#1\c!align}% % \let\raggedbox\vbox % \ifx\p_spac_align\empty \else % \processcommacommand[\p_spac_align]\spac_align_set_ragged_vbox % \fi} \setvalue{\??alignvertical \v!left }{\let\raggedbox\lbox} \setvalue{\??alignvertical \v!right }{\let\raggedbox\rbox} \setvalue{\??alignvertical \v!middle }{\let\raggedbox\cbox} \setvalue{\??alignvertical \v!inner }{\let\raggedbox\ibox} \setvalue{\??alignvertical \v!outer }{\let\raggedbox\obox} \setvalue{\??alignvertical \v!flushleft }{\let\raggedbox\rbox} \setvalue{\??alignvertical \v!flushright}{\let\raggedbox\lbox} \setvalue{\??alignvertical \v!center }{\let\raggedbox\cbox} \setvalue{\??alignvertical \v!no }{\def\raggedbox{\vbox\bgroup\spac_align_set_horizontal_right\let\next=}]} % maybe \let's \setvalue{\??alignhorizontal\v!left }{\def\raggedbox{\doalignedline\v!left }} \setvalue{\??alignhorizontal\v!right }{\def\raggedbox{\doalignedline\v!right }} \setvalue{\??alignhorizontal\v!middle }{\def\raggedbox{\doalignedline\v!middle}} \setvalue{\??alignhorizontal\v!inner }{\def\raggedbox{\doalignedline\v!inner }} \setvalue{\??alignhorizontal\v!outer }{\def\raggedbox{\doalignedline\v!outer }} \setvalue{\??alignhorizontal\v!flushleft }{\def\raggedbox{\doalignedline\v!right }} \setvalue{\??alignhorizontal\v!flushright}{\def\raggedbox{\doalignedline\v!left }} \setvalue{\??alignhorizontal\v!center }{\def\raggedbox{\doalignedline\v!middle}} % The next one can be in use so we keep it around but oen should % be aware of possible interference. \unexpanded\def\setraggedskips#1#2#3#4#5#6#7% never change this name (todo: inline this one .. less tracingall) {\unexpanded\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}% \updateraggedskips} \def\dosetraggedskips#1#2#3#4#5#6#7% {\raggedstatus #1\relax \leftskip 1\leftskip \s!plus#2\relax \rightskip 1\rightskip\s!plus#3\relax \spaceskip #4\relax \xspaceskip #5\relax \parfillskip \zeropoint\s!plus#6\relax \parindent #7\relax \c_attr_alignstate\ifcase\raggedstatus\attributeunsetvalue\else\raggedstatus\fi} % older (context) names: \let\spaceamount \interwordspace \let\emspaceamount\emwidth % tracing: \def\spac_show_par_data#1% {\ifx#1\relax\else \hbox{\string#1: \the#1}\endgraf \expandafter\spac_show_par_data \fi} \unexpanded\def\showpardata {\edef\thepardata {\hbox{font: \fontname\font}\endgraf \spac_show_par_data \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace \hsize \vsize \leftskip \rightskip \spaceskip \xspaceskip \parindent \parfillskip \hyphenpenalty \exhyphenpenalty \automatichyphenpenalty \explicithyphenpenalty \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty \doublehyphendemerits \finalhyphendemerits \adjdemerits \relax}% \dontleavehmode \begingroup \inleftmargin{\vsmash{\infofont\framed[\c!align=\v!right]{\thepardata}}}% \endgroup \let\showpardata\relax} \unexpanded\def\startshowpardata {\begingroup \showstruts \tracingparagraphs\maxdimen \appendtoksonce\showpardata\to\everypar} \unexpanded\def\stopshowpardata {\endgraf \endgroup} % Structure: \unexpanded\def\startalignment {\par \begingroup \setupalign} \unexpanded\def\stopalignment {\par \endgroup} \setnewconstant\alignstrutmode\plusone % see later for the real definition, which in the simple case is: \newtoks \everyleftofalignedline \newtoks \everyrightofalignedline \unexpanded\def\shiftalignedline#1#2#3#4% left, right, inner, outer {\rightorleftpageaction {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}% \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}} {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}% \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}} \def\doalignline#1#2% \\ == newline {\noindentation % was \noindent \dontleavehmode % added in marrakesch at TUG 2006\begingroup \begingroup \setlocalhsize % new \protected\def\\{\egroup\par\doalignline{#1}{#2}\bgroup}% \dowithnextbox {\hbox to \localhsize {\ifcase\alignstrutmode\or\strut\fi \the\everyleftofalignedline #1\unhbox\nextbox#2\relax \the\everyrightofalignedline}% \endgroup} \hbox} % plain commands \ifdefined\line \else \def\line {\hbox to\hsize} \fi \ifdefined\leftline \else \def\leftline #1{\line{#1\hss}} \fi \ifdefined\rightline \else \def\rightline #1{\line{\hss#1}} \fi \ifdefined\centerline \else \def\centerline#1{\line{\hss#1\hss}} \fi % direct commands \installcorenamespace{alignwrapper} \setuvalue{\??alignwrapper\v!left }{\doalignline\relax \hss } \setuvalue{\??alignwrapper\v!middle}{\doalignline\hss \hss } \setuvalue{\??alignwrapper\v!right }{\doalignline\hss \relax} \setuvalue{\??alignwrapper\v!max }{\doalignline\relax \relax} \def\spac_align_wrapper_middle {\doalignline\hss \hss} \def\spac_align_wrapper_handle#1% %{\csname\??alignwrapper\ifcsname\??alignwrapper#1\endcsname#1\else\v!middle\fi\endcsname} {\ifcsname\??alignwrapper#1\endcsname\expandafter\lastnamedcs\else\expandafter\spac_align_wrapper_middle\fi} \unexpanded\def\spac_align_wrapper_start[#1]% {\spac_align_wrapper_handle{#1}% \bgroup\ignorespaces} \unexpanded\def\spac_align_wrapper_stop {\removeunwantedspaces\egroup} \unexpanded\def\startlinealignment {\dosingleempty\spac_align_wrapper_start} \let\stoplinealignment\spac_align_wrapper_stop \unexpanded\def\startleftaligned {\spac_align_wrapper_start[\v!left ]} \let\stopleftaligned \spac_align_wrapper_stop \unexpanded\def\startmiddlealigned{\spac_align_wrapper_start[\v!middle]} \let\stopmiddlealigned\spac_align_wrapper_stop \unexpanded\def\startrightaligned {\spac_align_wrapper_start[\v!right ]} \let\stoprightaligned \spac_align_wrapper_stop \unexpanded\def\startmaxaligned {\spac_align_wrapper_start[\v!max ]} \let\stopmaxaligned \spac_align_wrapper_stop \let\startmidaligned \startmiddlealigned \let\stopmidaligned \stopmiddlealigned \let\startcenteraligned\startmiddlealigned \let\stopcenteraligned\stopmiddlealigned \unexpanded\def\leftaligned {\spac_align_wrapper_handle\v!left } \unexpanded\def\middlealigned{\spac_align_wrapper_handle\v!middle} \unexpanded\def\rightaligned {\spac_align_wrapper_handle\v!right } \unexpanded\def\maxaligned {\spac_align_wrapper_handle\v!max } \let\midaligned \middlealigned \let\centeraligned\middlealigned \installcorenamespace{alignline} \letvalue{\??alignline\v!left }\leftaligned \letvalue{\??alignline\v!right }\rightaligned \letvalue{\??alignline\v!middle }\midaligned \letvalue{\??alignline\v!flushleft }\rightaligned % beware, makes no sense in locations / we will have a special locations handler \letvalue{\??alignline\v!flushright}\leftaligned % beware, makes no sense in locations / we will have a special locations handler \letvalue{\??alignline\v!center }\midaligned \letvalue{\??alignline\v!max }\maxaligned \def\doalignedline#1{\resetrealignsignal\csname\??alignline#1\endcsname} %D Experimental (will be redone when floats are redone as it's real messy %D now). It can also be made faster (if needed). \def\doxalignline#1#2#3#4#5#6% {\noindentation % was \noindent \dontleavehmode % added in marrakesch at TUG 2006\begingroup \begingroup \setlocalhsize \protected\def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient \dowithnextbox {\hbox to \localhsize {#1\hskip\ifdone#2\else#3\fi#4% \hbox to \localhsize {\the\everyleftofalignedline \ifcase\alignstrutmode\or\strut\fi \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi \the\everyrightofalignedline}% \hss}% \endgroup} \hbox} \def\doxcheckline % used for floats so multipass anyway {\signalrightpage\doifelserightpage\donetrue\donefalse} \setvalue{\??alignline\v!inner }{\doxalignline\doxcheckline++\zeropoint \relax\hss } \setvalue{\??alignline\v!outer }{\doxalignline\doxcheckline++\zeropoint \hss \relax} \setvalue{\??alignline\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss } \setvalue{\??alignline\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss \relax} \setvalue{\??alignline\v!inneredge }{\doxalignline\doxcheckline-+\inneredgetotal \relax\hss } \setvalue{\??alignline\v!outeredge }{\doxalignline\doxcheckline+-\outeredgetotal \hss \relax} \setvalue{\??alignline\v!backspace }{\doxalignline\doxcheckline-+\backspace \relax\hss } \setvalue{\??alignline\v!cutspace }{\doxalignline\doxcheckline+-\cutspace \hss \relax} \setvalue{\??alignline\v!leftmargin }{\doxalignline\donefalse --\leftmargintotal \hss \relax} \setvalue{\??alignline\v!rightmargin}{\doxalignline\donefalse ++\rightmargintotal\relax\hss } \setvalue{\??alignline\v!leftedge }{\doxalignline\donefalse --\leftedgetotal \hss \relax} \setvalue{\??alignline\v!rightedge }{\doxalignline\donefalse ++\rightedgetotal \relax\hss } \def\doalignedline#1% unchecked {\csname\??alignline#1\endcsname} % no \resetrealignsignal here ? \def\alignedline#1#2% setting default % {\csname\??alignline\ifcsname\??alignline#1\endcsname#1\else#2\fi\endcsname} {\ifcsname\??alignline#1\endcsname \expandafter\lastnamedcs \else \csname\??alignline#2\expandafter\endcsname \fi} % beware: \wordright{whatever\kern-\rightskip} should work! % so, no funny boxing here \unexpanded\def\wordright {\dosingleempty\spac_word_right} \def\spac_word_right[#1]% {% don't change \groupedcommand {\removeunwantedspaces \hfill \allowbreak % changed back from \hskip\zeropoint \strut \hfill \quad % decent spacing \hbox} {\doifelse{#1}\v!right{\kern-\rightskip}{\doifsomething{#1}{\kern-#1}}% \parfillskip\zeropoint \finalhyphendemerits\zerocount % yes or no (see hyhenation/specialcases-001.tex) \par}} % \dorecurse{5}{something} \wordright{--someone} \endgraf % \dorecurse{6}{something} \wordright{--someone} \endgraf % \dorecurse{7}{something} \wordright{--someone} \endgraf % % \dorecurse{5}{something} \wordright{--someone else entirely} \endgraf % \dorecurse{6}{something} \wordright{--someone else entirely} \endgraf % \dorecurse{7}{something} \wordright{--someone else entirely} \endgraf % % \wordright[\rightskip]{whatever} % Trick posted by WS on mailing list, generalized a bit. The bottom text only shows % op when there is one line space available. We could add some extra space if needed. % \unexpanded\def\bottomword % {\par % \dowithnextbox % {\leaders\box\nextbox\vfil\page} % \vbox to \lineheight} % % \unexpanded\def\bottomword % {\par % \groupedcommand % {\leaders % \vbox to \lineheight\bgroup} % {\egroup % \vfil % \page}} % \simplealignedbox{2cm}{right}{x} \installcorenamespace{alignsimple} \installcorenamespace{alignsimplereverse} % todo: also handle \bgroup ... \egroup \unexpanded\def\spac_align_simple_left #1{{#1\hss}} \unexpanded\def\spac_align_simple_right #1{{\hss#1}} \unexpanded\def\spac_align_simple_middle#1{{\hss#1\hss}} \letvalue{\??alignsimple \v!right }\spac_align_simple_left \letvalue{\??alignsimple \v!outer }\spac_align_simple_left % not managed! see linenumbers \letvalue{\??alignsimple \v!flushleft }\spac_align_simple_left \letvalue{\??alignsimple \v!left }\spac_align_simple_right \letvalue{\??alignsimple \v!inner }\spac_align_simple_right % not managed! see linenumbers \letvalue{\??alignsimple \v!flushright}\spac_align_simple_right \letvalue{\??alignsimple \v!middle }\spac_align_simple_middle \letvalue{\??alignsimplereverse\v!right }\spac_align_simple_right \letvalue{\??alignsimplereverse\v!outer }\spac_align_simple_right % not managed! see linenumbers \letvalue{\??alignsimplereverse\v!flushleft }\spac_align_simple_right \letvalue{\??alignsimplereverse\v!left }\spac_align_simple_left \letvalue{\??alignsimplereverse\v!inner }\spac_align_simple_left % not managed! see linenumbers \letvalue{\??alignsimplereverse\v!flushright}\spac_align_simple_left \letvalue{\??alignsimplereverse\v!middle }\spac_align_simple_middle \unexpanded\def\simplealignedbox#1#2% {\hbox \ifdim#1>\zeropoint to #1 \ifcsname\??alignsimple#2\endcsname \doubleexpandafter\lastnamedcs \else \doubleexpandafter\spac_align_simple_left \fi \fi} \unexpanded\def\simplealignedspreadbox#1#2% {\hbox \ifdim#1>\zeropoint spread #1 \ifcsname\??alignsimple#2\endcsname \doubleexpandafter\lastnamedcs \else \doubleexpandafter\spac_align_simple_left \fi \fi} \unexpanded\def\simplealignedboxplus#1#2#3% {\hbox #3 \ifdim#1>\zeropoint to #1 \ifcsname\??alignsimple#2\endcsname \doubleexpandafter\lastnamedcs \else \doubleexpandafter\spac_align_simple_left \fi \fi} \newconditional\alignsimplelefttoright \settrue\alignsimplelefttoright \unexpanded\def\simplereversealignedbox#1#2% {\hbox \ifdim#1>\zeropoint to #1 \ifcsname\??alignsimplereverse#2\endcsname \doubleexpandafter\lastnamedcs \else \doubleexpandafter\spac_align_simple_left \fi \fi} \unexpanded\def\simplereversealignedboxplus#1#2#3% {\hbox #3 \ifdim#1>\zeropoint to #1 \ifcsname\??alignsimplereverse#2\endcsname \doubleexpandafter\lastnamedcs \else \doubleexpandafter\spac_align_simple_left \fi \fi} % \installnamespace{alignsets} % % \setvalue{\??alignsets\v!right }#1#2{\let#1\relax\let#2\hss } % \setvalue{\??alignsets\v!left }#1#2{\let#1\hss \let#2\relax} % \setvalue{\??alignsets\v!flushright}#1#2{\let#1\hss \let#2\relax} % \setvalue{\??alignsets\v!flushleft }#1#2{\let#1\relax\let#2\hss } % \setvalue{\??alignsets\v!middle }#1#2{\let#1\hss \let#2\hss } % \setvalue{\??alignsets\v!low }#1#2{\let#1\vss \let#2\relax} % \setvalue{\??alignsets\v!high }#1#2{\let#1\relax\let#2\vss } % \setvalue{\??alignsets\v!lohi }#1#2{\let#1\vss \let#2\vss } % \setvalue{\??alignsets\s!unknown }#1#2{\let#1\relax\let#2\relax} % % \unexpanded\def\spac_align_set_ss#1% % {\csname\??alignsetss\ifcsname\??alignsetss#1\endcsname#1\else\s!unknown\fi\endcsname} % Some obsolete (old) helpers: \unexpanded\def\definehbox {\dodoubleargument\spac_align_definehbox} \def\spac_align_definehbox[#1][#2]% {\setvalue{hbox#1}##1{\hbox to #2{\begstrut##1\endstrut\hss}}} %D Some direction related helpers: \installcorenamespace {reverse} \setvalue{\??reverse\v!normal }{\ifconditional\inlinelefttoright\else\s!reverse\fi} \setvalue{\??reverse\v!reverse}{\ifconditional\inlinelefttoright \s!reverse\fi} \let\usedirectionparameterreverse\gobbleoneargument \protect \endinput