%D \module %D [ file=pack-com, % used to be in core-mis, %D version=20120111, %D title=\CONTEXT\ Packing Macros, %D subtitle=Combinations, %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 Packaging Macros / Combinations} \unprotect % \startfloatcombination will be redone ... we can decouple the floatcontent % and caption and pass them to combinations so that we get better fit when the % caption is wider than the float, testcase: % % \startfloatcombination [2*2] % \placefigure[local]{alpha}{\externalfigure[cow.pdf][width=1cm]}% % \placefigure[local]{beta} {\externalfigure[cow.pdf][width=2cm]}% % \placefigure[local]{gamma}{\externalfigure[cow.pdf][width=3cm]} % \placefigure[local]{delta}{\externalfigure[cow.pdf][width=4cm]} % \stopfloatcombination %D We could of course map combinations onto one of the table %D mechanisms but as it has served us well for ages we keep %D this one. The code has been cleaned up a bit and mkiv'd. %D %D Okay ... I might luafy this one eventually. % \startcombination {alpha} {a} {beta} {b} \stopcombination % \startcombination[2*1] {alpha} {a} {beta} {b} \stopcombination % \startcombination[1*2] {alpha} {a} {beta} {b} \stopcombination % \startcombination[2] {alpha} {a} {beta} {b} \stopcombination % \startcombination[2] \combination {alpha} {a} \combination{beta} {b} \stopcombination %D We do support some structure but the order matters and currently it's %D only window dressing: %D %D \starttyping %D \let\startcontent\bgroup %D \let\stopcontent \egroup %D \let\startcaption\bgroup %D \let\stopcaption \egroup %D \stoptyping %D %D Of course we should have started with more structure as it would %D simply the code. %D %D \starttyping %D \startcombination %D \startcontent %D \externalfigure[cow] %D \stopcontent %D \startcaption %D Some cow. %D \stopcaption %D \startcontent %D \externalfigure[cow] %D \stopcontent %D \startcaption %D The same cow. %D \stopcaption %D \stopcombination %D \stoptyping \ifdefined\dotagcombination \else \let\dotagcombination\relax \fi \newsystemmode{combination} \appendtoks \globalresetsystemmode{combination}% \to \everyinsidefloat \newcount\c_pack_combinations_nesting % local \newcount\c_pack_combinations_x % global \newcount\c_pack_combinations_y % global \newcount\c_pack_combinations_max % global \newbox \b_pack_combinations_captions % global \newbox \b_pack_combinations_temp % global \newbox \b_pack_combinations_content % local \newbox \b_pack_combinations_caption % local \installcorenamespace{combination} \installcommandhandler \??combination {combination} \??combination \initializeboxstack{\??combination captions} \initializeboxstack{\??combination temp} \newcount\c_pack_combinations_x_saved \newcount\c_pack_combinations_y_saved \newcount\c_pack_combinations_max_saved \newbox \b_pack_combinations_captions_saved \newbox \b_pack_combinations_temp_saved \newbox \b_pack_combinations_content_saved \newbox \b_pack_combinations_caption_saved \setfalse\c_strc_constructions_define_commands \def\pack_combinations_push {\advance\c_pack_combinations_nesting\plusone \ifnum\c_pack_combinations_nesting>\plusone \c_pack_combinations_x_saved \c_pack_combinations_x \c_pack_combinations_y_saved \c_pack_combinations_y \c_pack_combinations_max_saved\c_pack_combinations_max \setbox\b_pack_combinations_captions_saved\box\b_pack_combinations_captions \setbox\b_pack_combinations_temp_saved \box\b_pack_combinations_temp \setbox\b_pack_combinations_content_saved \box\b_pack_combinations_content \setbox\b_pack_combinations_caption_saved \box\b_pack_combinations_caption \else \globalsetsystemmode{combination}% why global \fi} \def\pack_combinations_pop {\ifnum\c_pack_combinations_nesting>\plusone \global\c_pack_combinations_x \c_pack_combinations_x_saved \global\c_pack_combinations_y \c_pack_combinations_y_saved \global\c_pack_combinations_max\c_pack_combinations_max_saved \global\setbox\b_pack_combinations_captions\box\b_pack_combinations_captions_saved \global\setbox\b_pack_combinations_temp \box\b_pack_combinations_temp_saved \setbox\b_pack_combinations_content \box\b_pack_combinations_content_saved \setbox\b_pack_combinations_caption \box\b_pack_combinations_caption_saved \else \globalresetsystemmode{combination}% why global \fi \advance\c_pack_combinations_nesting\minusone} \definelabel [\v!combination] % handy for configuring [\c!numberconversion=\v!character, \c!text=] \settrue\c_strc_constructions_define_commands \setupcombination [\c!width=\v!fit, \c!height=\v!fit, \c!distance=\emwidth, \c!location=\v!bottom, % can be something {top,left} \c!before=\blank, \c!after=, \c!inbetween={\blank[\v!medium]}, %\c!style=, %\c!color=, \c!nx=2, % new \c!ny=1, % new \c!align=\v!middle] \let\setupcombinations\setupcombination % for the moment (we might distinguish) \installcorenamespace{combinationlocation} \installcorenamespace{combinationalternative} \appendtoks \setfalse\c_strc_constructions_define_commands \normalexpanded {\definelabel [\v!combination:\currentcombination]% [\v!combination\ifx\currentcombinationparent\empty\else:\currentcombinationparent\fi]}% [\s!counter=\currentcombination,\c!levels=1]% \settrue\c_strc_constructions_define_commands \to \everydefinecombination \setvalue{\??combinationlocation\v!left }{\let\m_pack_combinations_leftfiller\relax} \setvalue{\??combinationlocation\v!right }{\let\m_pack_combinations_rightfiller\relax} \setvalue{\??combinationlocation\v!top }{\let\m_pack_combinations_valigner\depthonlybox} \setvalue{\??combinationlocation\v!middle}{\let\m_pack_combinations_valigner\halfwaybox} \def\pack_combinations_location_reset {\let\m_pack_combinations_rightfiller\hfil \let\m_pack_combinations_leftfiller \hfil \let\m_pack_combinations_valigner \firstofoneargument} \pack_combinations_location_reset \def\pack_combinations_location_step#1% {\csname\??combinationlocation#1\endcsname} \unexpanded\def\startcombination {\bgroup % so we can grab a group \pack_combinations_push \dodoubleempty\pack_combinations_start} % formally ok: % % \unexpanded\def\stopcombination % {\egroup % \egroup} % % more robust: % % \unexpanded\def\stopcombination % {{}{}{}{}{}{}{}{}% catches (at most 4) missing entries % \egroup % \egroup} % % even better: % % \unexpanded\def\stopcombination % {\bgroup % \scratchtoks{{}}% % \dorecurse\c_pack_combinations_y % {\toksapp{{}{}}}% % \expandafter\egroup\the\scratchtoks % \egroup % \dostoptagged % \egroup} % % faster \unexpanded\def\pack_common_content_start{\bgroup\ignorespaces} \unexpanded\def\pack_common_content_stop {\removeunwantedspaces\egroup} \unexpanded\def\pack_common_caption_start{\bgroup\ignorespaces} \unexpanded\def\pack_common_caption_stop {\removeunwantedspaces\egroup} \unexpanded\def\stopcombination {\bgroup\normalexpanded{\egroup{}\ntimes{{}{}}\c_pack_combinations_y}% brr \dostoptagged \egroup \pack_combinations_pop \egroup} \newtoks\everycombination % \def\pack_combinations_start[#1][#2]% needs a cleanup, also nx ny (pretty old, this one) % {\edef\currentcombination{#1}% % \edef\currentcombinationspec{#2}% % \ifx\currentcombinationspec\empty % \doifelseassignment{#1}% % {\let\currentcombination\empty % \setupcurrentcombination[#1]% % \edef\currentcombinationspec{\combinationparameter\c!nx*\combinationparameter\c!ny*}} % {\doifelseinstring{*}\currentcombination % {\edef\currentcombinationspec{\currentcombination*\plusone*}% % \let\currentcombination\empty} % {\doifelsenumber\currentcombination % {\edef\currentcombinationspec{\currentcombination*\plusone*}% % \let\currentcombination\empty} % {\edef\currentcombinationspec{\combinationparameter\c!nx*\combinationparameter\c!ny*}}}}% % \else % \doifelseassignment{#2}% % {\setupcurrentcombination[#2]% % \edef\currentcombinationspec{\combinationparameter\c!nx*\combinationparameter\c!ny*}} % {\edef\currentcombinationspec{\currentcombinationspec*\plusone*}}% % \fi % % % \forgetall % % % \the\everycombination % % % \let\startcontent\pack_common_content_start % \let\stopcontent \pack_common_content_stop % \let\startcaption\pack_common_caption_start % \let\stopcaption \pack_common_caption_stop % % % \edef\p_height {\combinationparameter\c!height}% % \edef\p_width {\combinationparameter\c!width}% % \edef\p_location{\combinationparameter\c!location}% % \edef\p_distance{\combinationparameter\c!distance}% % % % \pack_combinations_location_reset % \rawprocesscommacommand[\p_location]\pack_combinations_location_step % % % \dostarttaggedchained\t!combination\currentcombination\??combination % \vbox \ifx\p_height\v!fit\else to \p_height \fi \bgroup % \let\combination\empty % permits \combination{}{} handy for cld % \normalexpanded{\pack_combinations_start_indeed[\currentcombinationspec]}} \def\pack_combinations_start[#1][#2]% needs a cleanup, also nx ny (pretty old, this one) {\edef\currentcombination{#1}% \edef\currentcombinationspec{#2}% \ifx\currentcombinationspec\empty \ifcondition\validassignment{#1}% \let\currentcombination\empty \setupcurrentcombination[#1]% \edef\currentcombinationspec{\combinationparameter\c!nx*\combinationparameter\c!ny*}% \else \doifelseinstring{*}\currentcombination {\edef\currentcombinationspec{\currentcombination*\plusone*}% \let\currentcombination\empty} {\doifelsenumber\currentcombination {\edef\currentcombinationspec{\currentcombination*\plusone*}% \let\currentcombination\empty} {\edef\currentcombinationspec{\combinationparameter\c!nx*\combinationparameter\c!ny*}}}% \fi \else \ifcondition\validassignment{#2}% \setupcurrentcombination[#2]% \edef\currentcombinationspec{\combinationparameter\c!nx*\combinationparameter\c!ny*}% \else \edef\currentcombinationspec{\currentcombinationspec*\plusone*}% \fi \fi % \forgetall % \the\everycombination % \let\startcontent\pack_common_content_start \let\stopcontent \pack_common_content_stop \let\startcaption\pack_common_caption_start \let\stopcaption \pack_common_caption_stop % \edef\p_height {\combinationparameter\c!height}% \edef\p_width {\combinationparameter\c!width}% \edef\p_location{\combinationparameter\c!location}% \edef\p_distance{\combinationparameter\c!distance}% % \pack_combinations_location_reset \rawprocesscommacommand[\p_location]\pack_combinations_location_step % \dostarttaggedchained\t!combination\currentcombination\??combination \vbox \ifx\p_height\v!fit\else to \p_height \fi \bgroup \let\combination\empty % permits \combination{}{} handy for cld \normalexpanded{\pack_combinations_start_indeed[\currentcombinationspec]}} \let\pack_combinations_check_x_y\relax \unexpanded\def\pack_combinations_start_indeed[#1*#2*#3]% {\global\c_pack_combinations_x#1\relax \global\c_pack_combinations_y#2\relax \setexpandedcombinationparameter\c!nx{\the\c_pack_combinations_x}% in case we access it \setexpandedcombinationparameter\c!ny{\the\c_pack_combinations_y}% in case we access it \pack_combinations_check_x_y \dotagcombination \global\setbox\b_pack_combinations_captions\emptybox \global\c_pack_combinations_max\c_pack_combinations_x \multiply\c_pack_combinations_y\c_pack_combinations_x \tabskip\zeropoint \halign \ifx\p_width\v!fit\else to \p_width \fi \bgroup % repetitive preamble \aligntab \m_pack_combinations_leftfiller \alignmark\alignmark \m_pack_combinations_rightfiller \aligntab \tabskip\zeropoint \s!plus 1fill % \fillskip \alignmark\alignmark \cr \pack_combinations_pickup} % \def\pack_combinations_pickup_content % we want to add struts but still ignore an empty box % {\dostoptagged % \setbox\b_pack_combinations_content\box\nextbox % \dostarttagged\t!combinationcaption\empty % \dowithnextboxcs\pack_combinations_pickup_caption\vtop\bgroup % \afterassignment\pack_combinations_caption_first % \let\nexttoken=} % I've first considered using a constructor directly but it's more overhead % and some settings conflict with already used combination settings so instead % we plug in labels. This also permits extensions later on. \appendtoks \edef\p_pack_combinations_alternative{\combinationparameter\c!alternative}% \to \everydefinecombination \def\pack_combinations_pickup {\dostarttagged\t!combinationpair\empty % better make this text \dostarttagged\t!combinationcontent\empty \assumelongusagecs\pack_combinations_pickup_content_indeed} \def\pack_combinations_pickup_content_indeed {\dowithnextboxcs\pack_combinations_pickup_content\hbox} \def\pack_combinations_pickup_content % we want to add struts but still ignore an empty box {\dostoptagged \setbox\b_pack_combinations_content\box\nextbox \dostarttagged\t!combinationcaption\empty \expandnamespacemacro\??combinationalternative\p_pack_combinations_alternative\v!text} \setvalue{\??combinationalternative\v!text}% {\assumelongusagecs\pack_combinations_alternative_text_indeed} \setvalue{\??combinationalternative\v!label}% {\assumelongusagecs\pack_combinations_alternative_label_indeed} \def\pack_combinations_alternative_text_indeed {\dowithnextboxcs\pack_combinations_pickup_caption\vtop\bgroup \afterassignment\pack_combinations_caption_first \let\nexttoken=} \def\pack_combinations_alternative_label_indeed {\dowithnextboxcs\pack_combinations_pickup_caption\vtop\bgroup \hsize\wd\b_pack_combinations_content \usealignparameter\combinationparameter \usecombinationstyleandcolor\c!style\c!color \begstrut \normalexpanded{\strc_labels_command{\v!combination\ifx\currentcombination\empty\else:\currentcombination\fi}}% \endstrut \egroup} \appendtoks \edef\p_pack_combinations_alternative{\combinationparameter\c!alternative}% \ifx\p_pack_combinations_alternative\v!label \edef\p_continue{\combinationparameter\c!continue}% \ifx\p_continue\v!yes \else \normalexpanded{\strc_labels_reset{\v!combination\ifx\currentcombination\empty\else:\currentcombination\fi}{1}}% \fi \fi \to \everycombination \def\pack_combinations_pickup_caption {\dostoptagged \dostoptagged \setbox\b_pack_combinations_caption\box\nextbox \pack_combinations_pickup_package_pair} \def\pack_combinations_caption_first {\futurelet\nexttoken\pack_combinations_caption_second} \def\pack_combinations_caption_second {\ifx\nexttoken\egroup % the caption is empty \else\ifx\nexttoken\stopcaption % the caption is empty (new per 2014-05-24) \else % todo: \p_pack_combinations_alternative\v!none: no style, strut etc \hsize\wd\b_pack_combinations_content \usealignparameter\combinationparameter \usecombinationstyleandcolor\c!style\c!color \bgroup \aftergroup\endstrut \aftergroup\egroup \begstrut \fi\fi} \def\pack_combinations_pickup_package_pair % we need to store the caption row {\vbox {\forgetall \m_pack_combinations_valigner{\box\b_pack_combinations_content}% % we need to save the caption for a next alignment line \pack_combinations_save_caption}% \ifnum\c_pack_combinations_y>\plusone \global\advance\c_pack_combinations_y\minusone \global\advance\c_pack_combinations_x\minusone \ifcase\c_pack_combinations_x \doubleexpandafter\pack_combinations_pickup_package_pair_a \else \doubleexpandafter\pack_combinations_pickup_package_pair_b \fi \else \singleexpandafter\pack_combinations_pickup_package_pair_c \fi} \def\pack_combinations_pickup_package_pair_a {\cr \pack_combinations_flush_captions \noalign {\forgetall \global\setbox\b_pack_combinations_captions\emptybox \nointerlineskip \combinationparameter\c!after \combinationparameter\c!before \vss \nointerlineskip}% \global\c_pack_combinations_x\c_pack_combinations_max \pack_combinations_pickup} \def\pack_combinations_pickup_package_pair_b {\aligntab \aligntab \aligntab \kern\p_distance \aligntab \pack_combinations_pickup} \def\pack_combinations_pickup_package_pair_c {\cr \pack_combinations_flush_captions \egroup} \def\pack_combinations_save_caption {\global\setbox\b_pack_combinations_captions\hpack {\hpack{\box\b_pack_combinations_caption}% \unhbox\b_pack_combinations_captions}} \def\pack_combinations_flush_captions {\noalign {\ifdim\ht\b_pack_combinations_captions>\zeropoint \nointerlineskip % indeed \combinationparameter\c!inbetween \global\c_pack_combinations_x\c_pack_combinations_max \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes \else \global\setbox\b_pack_combinations_captions\emptybox \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop \fi}% \pack_combinations_flush_captions_indeed \crcr} \def\pack_combinations_flush_captions_yes {\global\setbox\b_pack_combinations_captions\hpack {\unhbox\b_pack_combinations_captions \global\setbox\b_pack_combinations_temp\lastbox}% \box\b_pack_combinations_temp \global\advance\c_pack_combinations_x\minusone\relax \ifnum\c_pack_combinations_x>\zerocount \expandafter\pack_combinations_flush_captions_yes_followup \else \global\setbox\b_pack_combinations_captions\emptybox \fi} \let\pack_combinations_flush_captions_nop\donothing \def\pack_combinations_flush_captions_yes_followup {\aligntab \aligntab \aligntab \aligntab \pack_combinations_flush_captions_indeed} %D \macros %D {startfloatcombination} %D %D \setupexternalfigures[directory={../sample}] %D \startbuffer %D \placefigure %D [left,none] %D {} %D {\startfloatcombination[2*2] %D \placefigure{alpha}{\externalfigure[cow.pdf][width=1cm]} %D \placefigure{beta} {\externalfigure[cow.pdf][width=2cm]} %D \placefigure{gamma}{\externalfigure[cow.pdf][width=3cm]} %D \placefigure{delta}{\externalfigure[cow.pdf][width=4cm]} %D \stopfloatcombination} %D %D \input tufte %D \stopbuffer %D %D \typebuffer \getbuffer \unexpanded\def\startfloatcombination {\dodoubleempty\pack_combinations_start_float} \let\stopfloatcombination\relax \unexpanded\def\pack_combinations_float_hack_a#1% {\strc_floats_build_box_separate_split{\getlocalfloat{#1}}% \box\b_strc_floats_separate_content} \unexpanded\def\pack_combinations_float_hack_b#1% {\box\b_strc_floats_separate_caption} \def\pack_combinations_start_float[#1][#2]% {\ifinsidefloat\else\dontleavehmode\fi % tricky, floatcombinations fail to align well otherwise \vbox\bgroup \strc_floats_build_box_separate_set %\insidecolumnstrue % trick, forces no centering, todo: proper switch/feature \postcenterfloatmethod\zerocount \forcelocalfloats \unexpanded\def\stopfloatcombination{\pack_combinations_stop_float{#1}}} \def\pack_combinations_float_check_x_y {\ifnum\numexpr\c_pack_combinations_x*\c_pack_combinations_y\relax<\noflocalfloats\relax \global\c_pack_combinations_x\noflocalfloats \global\c_pack_combinations_y\plusone \fi \let\pack_combinations_check_x_y\relax}% \def\pack_combinations_stop_float#1% {\scratchtoks\emptytoks \dorecurse\noflocalfloats {\appendetoks {\pack_combinations_float_hack_a{\recurselevel}}% {\pack_combinations_float_hack_b{\recurselevel}}% \to\scratchtoks}% brrr \let\pack_combinations_check_x_y\pack_combinations_float_check_x_y \expanded{\startcombination[#1]\the\scratchtoks}\stopcombination \resetlocalfloats \egroup} %D \macros %D {definepairedbox, setuppairedbox, placepairedbox} %D %D Paired boxes, formally called legends, but from now on a %D legend is just an instance, are primarily meant for %D typesetting some text alongside an illustration. Although %D there is quite some variation possible, the functionality is %D kept simple, if only because in most cases such pairs are %D typeset sober. %D %D The location specification accepts a pair, where the first %D keyword specifies the arrangement, and the second one the %D alignment. The first key of the location pair is one of %D \type {left}, \type {right}, \type {top} or \type {bottom}, %D while the second key can also be \type {middle}. %D %D The first box is just collected in an horizontal box, but %D the second one is a vertical box that gets passed the %D bodyfont and alignment settings. %D In many cases the table builders can be used instead, but as %D this mechanism is a traditional \CONTEXT\ one we keep it %D around. %D \macros %D {setuplegend, placelegend} %D %D It makes sense to typeset a legend to a figure in \TEX\ %D and not in a drawing package. The macro \type {\placelegend} %D combines a figure (or something else) and its legend. This %D command is just a paired box. %D %D The legend is placed according to \type {location}, being %D \type {bottom} or \type {right}. The macro macro is used as %D follows. %D %D \starttyping %D \placefigure %D {whow} %D {\placelegend %D {\externalfigure[cow]} %D {\starttabulate %D \NC 1 \NC head \NC \NR %D \NC 2 \NC legs \NC \NR %D \NC 3 \NC tail \NC \NR %D \stoptabulate}} %D %D \placefigure %D {whow} %D {\placelegend %D {\externalfigure[cow]} %D {\starttabulate[|l|l|l|l|] %D \NC 1 \NC head \NC 3 \NC tail \NC \NR %D \NC 2 \NC legs \NC \NC \NC \NR %D \stoptabulate}} %D %D \placefigure %D {whow} %D {\placelegend[n=2] %D {\externalfigure[cow]} %D {\starttabulate %D \NC 1 \NC head \NC \NR %D \NC 2 \NC legs \NC \NR %D \NC 3 \NC tail \NC \NR %D \stoptabulate}} %D %D \placefigure %D {whow} %D {\placelegend[n=2] %D {\externalfigure[cow]} %D {head \par legs \par tail}} %D %D \placefigure %D {whow} %D {\placelegend[n=2] %D {\externalfigure[cow]} %D {\startitemize[packed] %D \item head \item legs \item tail \item belly \item horns %D \stopitemize}} %D %D \placefigure %D {whow} %D {\placelegend[n=2,width=.8\hsize] %D {\externalfigure[cow]} %D {\startitemize[packed] %D \item head \item legs \item tail \item belly \item horns %D \stopitemize}} %D %D \def\MytTestTwo#1#2% %D {\placefigure %D {whow} %D {\placelegend[location={#1,#2}] %D {\externalfigure[cow]} %D {\starttabulate %D \NC 1 \NC head \NC \NR %D \NC 2 \NC legs \NC \NR %D \NC 3 \NC tail \NC \NR %D \stoptabulate}}} %D %D \def\MytTestOne#1{\processcommalist[left,right,top,bottom]{\MytTestTwo{#1}}} %D %D \processcommalist[left,right,top,bottom,middle]\MytTestOne %D \stoptyping %D %D More structure is also possible (the order matters!): %D %D \starttyping %D \startplacefigure[title=whow] %D \startplacelegend[location={bottom,middle},color=red] %D \startcontent %D \externalfigure[cow] %D \stopcontent %D \startcaption %D \starttabulate[|l|l|] %D \NC 1 \NC head \NC \NR %D \NC 2 \NC legs \NC \NR %D \NC 3 \NC tail \NC \NR %D \stoptabulate %D \stopcaption %D \stopplacelegend %D \stopplacefigure %D \stoptyping % todo: natural size \newsystemmode{pairedbox} \appendtoks \globalresetsystemmode{pairedbox}% \to \everyinsidefloat \installcorenamespace {pairedbox} \installcommandhandler \??pairedbox {pairedbox} \??pairedbox \setuppairedbox [\c!n=1, \c!distance=\bodyfontsize, %\c!before=, %\c!after=, %\c!color=, %\c!style=, \c!inbetween={\blank[\v!medium]}, \c!width=\hsize, \c!height=\vsize, \c!maxwidth=\textwidth, % \makeupwidth, \c!maxheight=\textheight, % \makeupheight, %\c!bodyfont=, %\c!align=, \c!location=\v!bottom] % watch the hsize/vsize tricks \newbox \b_pack_pairedboxes_first \newbox \b_pack_pairedboxes_second \newdimen\s_pack_pairedboxes_size \appendtoks \setuevalue{\e!setup\currentpairedbox\e!endsetup}{\setuppairedbox [\currentpairedbox]}% \setuevalue{\e!place\currentpairedbox }{\placepairedbox [\currentpairedbox]}% one argument is mandate anyway \setuevalue{\e!start\e!place\currentpairedbox }{\startplacepairedbox[\currentpairedbox]}% one argument is mandate anyway \setuevalue{\e!stop\e!place \currentpairedbox }{\stopplacepairedbox }% \to \everydefinepairedbox \unexpanded\def\placepairedbox[#1]% {\bgroup \edef\currentpairedbox{#1}% \doifelsenextoptionalcs\pack_pairedboxes_place\pack_pairedboxes_place_indeed} \unexpanded\def\startplacepairedbox[#1]% {\bgroup \edef\currentpairedbox{#1}% \doifelsenextoptionalcs\pack_pairedboxes_place\pack_pairedboxes_place_indeed} \unexpanded\def\stopplacepairedbox {} \def\pack_pairedboxes_place[#1]% {\setupcurrentpairedbox[#1]% \pack_pairedboxes_place_indeed} \def\pack_pairedboxes_place_indeed {\pairedboxparameter\c!before \bgroup \edef\p_location{\pairedboxparameter\c!location}% \edef\p_n {\pairedboxparameter\c!n}% % \let\startcontent\pack_common_content_start \let\stopcontent \pack_common_content_stop \let\startcaption\pack_common_caption_start \let\stopcaption \pack_common_caption_stop % \globalsetsystemmode{pairedbox}% \pack_pairedboxes_before \assumelongusagecs\pack_pairedboxes_first_pickup} \def\pack_pairedboxes_first_pickup {\dowithnextboxcs\pack_pairedboxes_first\hbox \bgroup \let\next=} \def\pack_pairedboxes_first {\pack_pairedboxes_between \assumelongusagecs\pack_pairedboxes_second_pickup} \def\pack_pairedboxes_second_pickup {\dowithnextboxcs\pack_pairedboxes_second\vbox \bgroup \pack_pairedboxes_inside_second \let\next=} \def\pack_pairedboxes_second {\pack_pairedboxes_after \egroup \pairedboxparameter\c!after \egroup} \newconditional\c_pack_pairedboxes_horizontal \settrue\c_pack_pairedboxes_horizontal \installcorenamespace{pairedboxnature} \installcorenamespace{pairedboxalign} \let\pack_pairedboxes_fill_top \relax \let\pack_pairedboxes_fill_bottom\relax \setvalue{\??pairedboxnature\v!left}% {\settrue\c_pack_pairedboxes_horizontal \let\pack_pairedboxes_flush\pack_pairedboxes_flush_left} \setvalue{\??pairedboxnature\v!right}% {\settrue\c_pack_pairedboxes_horizontal \let\pack_pairedboxes_flush\pack_pairedboxes_flush_right} \setvalue{\??pairedboxnature\v!top}% {\setfalse\c_pack_pairedboxes_horizontal \let\pack_pairedboxes_fill_top\relax \let\pack_pairedboxes_fill_bottom\vss \let\pack_pairedboxes_flush\pack_pairedboxes_flush_top} \setvalue{\??pairedboxnature\v!bottom}% {\setfalse\c_pack_pairedboxes_horizontal \let\pack_pairedboxes_fill_top\vss \let\pack_pairedboxes_fill_bottom\relax \let\pack_pairedboxes_flush\pack_pairedboxes_flush_bottom} \def\pack_pairedboxes_flush_left {\box\b_pack_pairedboxes_second \kern\pairedboxparameter\c!distance \box\b_pack_pairedboxes_first} \def\pack_pairedboxes_flush_right {\box\b_pack_pairedboxes_first \kern\pairedboxparameter\c!distance \box\b_pack_pairedboxes_second} \def\pack_pairedboxes_flush_top {\box\b_pack_pairedboxes_second \endgraf \nointerlineskip \pairedboxparameter\c!inbetween \box\b_pack_pairedboxes_first} \def\pack_pairedboxes_flush_bottom {\box\b_pack_pairedboxes_first \endgraf \nointerlineskip \pairedboxparameter\c!inbetween \box\b_pack_pairedboxes_second} \setvalue{\??pairedboxalign\v!left}% 0 {\let\pack_pairedboxes_align_l\relax \let\pack_pairedboxes_align_r\hss \let\pack_pairedboxes_align_t\relax \let\pack_pairedboxes_align_b\relax} \setvalue{\??pairedboxalign\v!right}% 1 {\let\pack_pairedboxes_align_l\hss \let\pack_pairedboxes_align_r\relax \let\pack_pairedboxes_align_t\relax \let\pack_pairedboxes_align_b\relax} \setvalue{\??pairedboxalign\v!high}% 2 {\let\pack_pairedboxes_align_l\relax \let\pack_pairedboxes_align_r\relax \let\pack_pairedboxes_align_t\relax \let\pack_pairedboxes_align_b\vss} \setvalue{\??pairedboxalign\v!low}% 3 {\let\pack_pairedboxes_align_l\relax \let\pack_pairedboxes_align_r\relax \let\pack_pairedboxes_align_t\vss \let\pack_pairedboxes_align_b\relax} \setvalue{\??pairedboxalign\v!middle}% 4 {\let\pack_pairedboxes_align_l\hss \let\pack_pairedboxes_align_r\hss \let\pack_pairedboxes_align_t\vss \let\pack_pairedboxes_align_b\vss} \setvalue{\??pairedboxalign\v!bottom}{\getvalue{\??pairedboxalign\v!low }} \setvalue{\??pairedboxalign \v!top}{\getvalue{\??pairedboxalign\v!high}} \def\pack_pairedbox_valign#1{\setbox#1\vpack to \s_pack_pairedboxes_size{\pack_pairedboxes_align_t\box#1\pack_pairedboxes_align_b}} \def\pack_pairedbox_halign#1{\setbox#1\hpack to \s_pack_pairedboxes_size{\pack_pairedboxes_align_l\box#1\pack_pairedboxes_align_r}} \def\pack_pairedboxes_before {\ifx\p_location\empty \csname\??pairedboxnature\v!left \endcsname \csname\??pairedboxalign \v!middle\endcsname \else \getfromcommacommand[\p_location][1]% \csname\??pairedboxnature \ifcsname\??pairedboxnature\commalistelement\endcsname\commalistelement\else\v!left\fi \endcsname \getfromcommacommand[\p_location][2]% \csname\??pairedboxalign \ifcsname\??pairedboxalign\commalistelement\endcsname\commalistelement\else\v!middle\fi \endcsname \fi} \def\pack_pairedboxes_between {\usebodyfontparameter\pairedboxparameter \setbox\b_pack_pairedboxes_first\box\nextbox \ifconditional\c_pack_pairedboxes_horizontal \pack_pairedboxes_between_horizontal \else \pack_pairedboxes_between_vertical \fi \ifnum\p_n>\plusone \setrigidcolumnhsize\hsize{\pairedboxparameter\c!distance}\p_n \fi} % \def\pack_pairedboxes_between_horizontal % {\setlocalhsize % \hsize\wd\b_pack_pairedboxes_first % trick % \hsize\pairedboxparameter\c!width % can be \hsize % \scratchdimen\dimexpr\wd\b_pack_pairedboxes_first+\pairedboxparameter\c!distance\relax % \ifdim\dimexpr\hsize+\scratchdimen\relax>\pairedboxparameter\c!maxwidth\relax % \hsize\dimexpr\pairedboxparameter\c!maxwidth-\scratchdimen\relax % \fi} \def\pack_pairedboxes_between_horizontal {\scratchdistance\pairedboxparameter\c!distance \scratchwidth\pairedboxparameter\c!maxwidth\relax \setlocalhsize \hsize\dimexpr\availablehsize-\wd\b_pack_pairedboxes_first-\scratchdistance\relax \hsize\pairedboxparameter\c!width\relax % can be \hsize \scratchdimen\dimexpr\wd\b_pack_pairedboxes_first+\scratchdistance\relax \ifdim\dimexpr\hsize+\scratchdimen\relax>\scratchwidth \hsize\dimexpr\scratchwidth-\scratchdimen\relax \fi} \def\pack_pairedboxes_between_vertical {\scratchwidth\pairedboxparameter\c!maxwidth\relax \hsize\wd\b_pack_pairedboxes_first \hsize\pairedboxparameter\c!width\relax % can be \hsize \ifdim\hsize>\scratchwidth\relax \hsize\scratchwidth \fi} \def\pack_pairedboxes_after {\setbox\b_pack_pairedboxes_second\vpack {\ifnum\p_n>\plusone \rigidcolumnbalance\nextbox \else \box\nextbox \fi}% \ifconditional\c_pack_pairedboxes_horizontal \pack_pairedboxes_pack_horizontal \else \pack_pairedboxes_pack_vertical \fi} \def\pack_pairedboxes_pack_horizontal {\dontleavehmode\hbox\bgroup \forgetall \s_pack_pairedboxes_size\ht \ifdim\ht\b_pack_pairedboxes_first>\ht\b_pack_pairedboxes_second \b_pack_pairedboxes_first \else \b_pack_pairedboxes_second \fi \vsize\s_pack_pairedboxes_size \ifdim\s_pack_pairedboxes_size<\pairedboxparameter\c!height\relax % can be \vsize \s_pack_pairedboxes_size\pairedboxparameter\c!height \fi \ifdim\s_pack_pairedboxes_size>\pairedboxparameter\c!maxheight\relax \s_pack_pairedboxes_size\pairedboxparameter\c!maxheight \fi \pack_pairedbox_valign\b_pack_pairedboxes_first \pack_pairedbox_valign\b_pack_pairedboxes_second \pack_pairedboxes_flush \egroup} \def\pack_pairedboxes_pack_vertical {\dontleavehmode\vpack\bgroup \forgetall \s_pack_pairedboxes_size\wd \ifdim\wd\b_pack_pairedboxes_first>\wd\b_pack_pairedboxes_second \b_pack_pairedboxes_first \else \b_pack_pairedboxes_second \fi \pack_pairedbox_halign\b_pack_pairedboxes_first \pack_pairedbox_halign\b_pack_pairedboxes_second \s_pack_pairedboxes_size\ht\b_pack_pairedboxes_second \vsize\s_pack_pairedboxes_size \ifdim\ht\b_pack_pairedboxes_second<\pairedboxparameter\c!height\relax % can be \vsize \s_pack_pairedboxes_size\pairedboxparameter\c!height\relax % \relax needed \fi \ifdim\s_pack_pairedboxes_size>\pairedboxparameter\c!maxheight\relax % todo: totale hoogte \s_pack_pairedboxes_size\pairedboxparameter\c!maxheight\relax % \relax needed \fi \ifdim\s_pack_pairedboxes_size>\ht\b_pack_pairedboxes_second \setbox\b_pack_pairedboxes_second\vpack to \s_pack_pairedboxes_size {\pack_pairedboxes_fill_top \box\b_pack_pairedboxes_second \pack_pairedboxes_fill_bottom}% \kern\zeropoint \fi \pack_pairedboxes_flush \egroup} \def\pack_pairedboxes_inside_second {\forgetall \setupalign[\pairedboxparameter\c!align]% \usepairedboxstyleandcolor\c!style\c!color \tolerantTABLEbreaktrue % hm. \blank[\v!disable]% use fast one \everypar{\begstrut}} % also flushers here (see bTABLE) \definepairedbox[\v!legend] \unexpanded\def\placeontopofeachother{\bgroup\dowithnextboxcs\pack_topofeachother_one\hbox} \unexpanded\def\placesidebyside {\bgroup\dowithnextboxcs\pack_sidebyside_one \hbox} \def\pack_topofeachother_one{\bgroup\setbox\scratchboxone\box\nextbox\dowithnextboxcs\pack_topofeachother_two\hbox} \def\pack_sidebyside_one {\bgroup\setbox\scratchboxone\box\nextbox\dowithnextboxcs\pack_sidebyside_two \hbox} \def\pack_topofeachother_two{\setbox\scratchboxtwo\box\nextbox \halign{\hss\alignmark\alignmark\hss\cr\box\scratchboxone\cr\box\scratchboxtwo\cr}% \egroup\egroup} \def\pack_sidebyside_two {\setbox\scratchboxtwo\box\nextbox \valign{\vss\alignmark\alignmark\vss\cr\box\scratchboxone\cr\box\scratchboxtwo\cr}% \egroup\egroup} \protect \endinput