%D \module %D [ file=pack-box, %D version=2002.04.12, %D title=\CONTEXT\ Packaging Macros, %D subtitle=Boxes, %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 / Boxes} %D This module contains all kind of macros for moving content around. Many %D macros here come from other modules, but depencies made it more clear %D to isolate them. We invite users to document the macros. They can be %D handy shortcuts for otherwise complex tasks. \unprotect %D We need to set the size, else we get dimensions depending on the content, %D which in itself is ok, but can lead to loops due to rounding errors (happened %D in demo-obv). % \definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] % \definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] % \definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] % \definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] \definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] \definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] \definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] \definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] \permanent\protected\def\internaltextoverlay#1% will become more generic and installable {\startoverlay % i.e. probably an overlay by itself {\positionregionoverlay\textanchor{\v!text#1}}% see later {\composedlayer {\v!text#1}}% \stopoverlay} \defineoverlay[\v!text-2][\internaltextoverlay{-2}] \defineoverlay[\v!text-1][\internaltextoverlay{-1}] \defineoverlay[\v!text+1][\internaltextoverlay{+1}] \defineoverlay[\v!text+2][\internaltextoverlay{+2}] \installcorenamespace {anchor} % produces a box too % % \anchor[text-1][preset=lefttop][framed settings]{HELLO WORLD} \mutable\lettonothing\currentanchor \permanent\tolerant\protected\def\defineanchor[#1]#*[#2]#*[#3]#*[#4]% name targetlayer layersetting framedsetting {\defcsname\??anchor#1\endcsname{\pack_anchors_process_defined{#2}{#3}{#4}}} \let\pack_anchors_process_defined_indeed\gobbletwooptionals \def\pack_anchors_process_defined#1#2#3% brrr {\tolerant\def\pack_anchors_process_defined_indeed[##1]##*[##2]% {\ifarguments \def\next{\pack_anchors_process_indeed{#1}{#2}{#3}}% \or \def\next{\pack_anchors_process_indeed{#1}{#2,##1}{#2,##1}}% \or \def\next{\pack_anchors_process_indeed{#1}{#2,##1}{#3,##2}}% \fi \next}% picks up a box \pack_anchors_process_defined_indeed} \permanent\protected\def\anchor[#1]% {\begingroup \edef\currentanchor{#1}% \ifcsname\??anchor\currentanchor\endcsname \expandafter\lastnamedcs \else \expandafter\pack_anchor_notdefined \fi} \tolerant\def\pack_anchor_notdefined[#1]#*[#2]% {\ifarguments \expandafter\gobbletwoarguments \or \expandafter\pack_anchor_notdefined_one \else \expandafter\pack_anchor_notdefined_two \fi{#1}{#2}} \def\pack_anchor_notdefined_one #1#2{\dowithnextbox{\pack_anchors_process_finish\currentanchor{#1}{#1}}\vbox} \def\pack_anchor_notdefined_two #1#2{\dowithnextbox{\pack_anchors_process_finish\currentanchor{#1}{#2}}\vbox} \def\pack_anchors_process_indeed#1#2#3{\dowithnextbox{\pack_anchors_process_finish {#1}{#2}{#3}}\vbox} \newbox \b_pack_anchors \newdimension\d_pack_anchors_width \newdimension\d_pack_anchors_height \newdimension\d_pack_anchors_depth % \definelayer[anchor] \newinteger\c_pack_anchors_n \newtoks \t_pack_anchors_flush \protected\def\pack_anchors_register#1#2% {\global\advanceby\c_pack_anchors_n\plusone \pagereference[\v!layer:\v!anchor:\number\c_pack_anchors_n]% \putboxincache\v!anchor{\number\c_pack_anchors_n}\b_pack_anchors % \xtoksapp\t_pack_anchors_flush{\pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}}% \doglobal\appendetoks \pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}% \to \t_pack_anchors_flush \glet\pack_anchors_flush_all\pack_anchors_flush_all_indeed} \protected\def\pack_anchors_flush#1#2#3% {\doifelseboxincache\v!anchor{#1} {\doifelsereferencefound{\v!layer:\v!anchor:#1} {\ifnum\currentreferencerealpage=\realpageno\relax \setlayer[#2][#3,\c!position=\v!no]{\directboxfromcache\v!anchor{#1}}% \else \donetrue \fi }\donetrue}% \donetrue}% \protected\def\pack_anchors_flush_all_indeed {\donefalse \the\t_pack_anchors_flush \ifdone\else \global\t_pack_anchors_flush\emptytoks \glet\pack_anchors_flush_all\relax \fi} \let\pack_anchors_flush_all\relax \appendtoks \pack_anchors_flush_all \to \everybeforepagebody \def\pack_anchors_process_finish#1#2#3% brrr: we need to apply offset only once .. a bit messy {\checkpositionoverlays \setbox\b_pack_anchors\box\nextbox \framed % could be a predefined framed but used seldom [\c!offset=\v!overlay,\c!frame=\v!off,#3] {\pack_anchors_register{#1}{#2}% \novrule % hm, not needed as we frame the size (but kind of default) \s!width \wd\b_pack_anchors \s!height\ht\b_pack_anchors \s!depth \dp\b_pack_anchors}% \endgroup} % \setlayeranchored[text-1][preset=lefttop]{HELLO WORLD} produces a simple (empty) hbox % synchronizes per page \permanent\tolerant\protected\def\setlayeranchored[#1]#*[#2]% {\begingroup \ifarguments \dowithnextbox {\endgroup}% \else \dowithnextbox {\checkpositionoverlays \setbox\b_pack_anchors\box\nextbox \dontleavehmode\hpack{\pack_anchors_register{#1}{#2}}% \endgroup}% \fi \hbox} % collectors \installcorenamespace{collectorbox} \installcorenamespace{collector} \installcommandhandler \??collector {collector} \??collector \setupcollector [\c!state=\v!start, \c!x=\zeropoint, \c!y=\zeropoint, \c!offset=\zeropoint, \c!rotation=, % geen 0 ! \c!hoffset=\zeropoint, \c!voffset=\zeropoint, \c!location=rb, \c!corner=] \appendtoks \ifcsname\??collectorbox\currentcollector\endcsname \else \expandafter\newbox\csname\??collectorbox\currentcollector\endcsname \fi \to \everydefinecollector \permanent\protected\def\resetcollector[#1]% {\ifcsname\??collectorbox#1\endcsname \global\setbox\lastnamedcs\emptybox \fi} \newconditional\c_pack_boxes_collector_valid_box \mutable\let\b_pack_boxes_collector\scratchbox \def\pack_boxes_collector_check_box#1% {\edef\currentcollector{#1}% \ifcsname\??collectorbox\currentcollector\endcsname \settrue\c_pack_boxes_collector_valid_box \expandafter\let\expandafter\b_pack_boxes_collector\lastnamedcs \else \setfalse\c_pack_boxes_collector_valid_box \writestatus{collector}{unknown collector \currentcollector}% \fi} \permanent\tolerant\protected\def\setcollector[#1]#*[#2]% todo: keep reference point {\bgroup \pack_boxes_collector_check_box{#1}% \ifconditional\c_pack_boxes_collector_valid_box \setupcurrentcollector[#2]% \expandafter\pack_boxes_collector_yes \else \expandafter\pack_boxes_collector_nop \fi} \def\pack_boxes_collector_yes {\forgetall \dontcomplain \dowithnextboxcs\pack_boxes_collector_finish\hbox} \let\pack_boxes_collector_nop\egroup \installcorenamespace{collectorcorners} \defcsname\??collectorcorners\v!middle\endcsname {\ifdim\d_pack_layers_x_size>\zeropoint \advanceby\d_pack_layers_x_position.5\d_pack_layers_x_size \fi \ifdim\d_pack_layers_y_size>\zeropoint \advanceby\d_pack_layers_y_position.5\d_pack_layers_y_size \fi} \defcsname\??collectorcorners\v!bottom\endcsname {\ifdim\d_pack_layers_y_size>\zeropoint \advanceby\d_pack_layers_y_position-\d_pack_layers_y_size \d_pack_layers_y_position-\d_pack_layers_y_position \fi} \defcsname\??collectorcorners\v!right\endcsname {\ifdim\d_pack_layers_x_size>\zeropoint \advanceby\d_pack_layers_x_position-\d_pack_layers_x_size \d_pack_layers_x_position-\d_pack_layers_x_position \fi} \def\pack_boxes_collector_check_corner#1% {\ifcsname\??collectorcorners#1\endcsname \lastnamedcs \fi} \def\pack_boxes_collector_finish {\edef\p_collector_rotation{\collectorparameter\c!rotation}% \edef\p_collector_corner {\collectorparameter\c!corner}% \ifempty\p_collector_rotation \else \setbox\nextbox\hpack {\rotate [\c!location=\v!high, \c!rotation=\p_collector_rotation] {\box\nextbox}}% \fi \d_pack_layers_x_size\wd\b_pack_boxes_collector \d_pack_layers_y_size\htdp\b_pack_boxes_collector \d_pack_layers_x_position\dimexpr\collectorparameter\c!x+\collectorparameter\c!hoffset\relax \d_pack_layers_y_position\dimexpr\collectorparameter\c!y+\collectorparameter\c!voffset\relax \rawprocesscommacommand[\p_collector_corner]\pack_boxes_collector_check_corner \setbox\nextbox\hpack {\alignedbox[\collectorparameter\c!location]\vpack{\box\nextbox}}% \boxmaxdepth\zeropoint % really needed, nice example \global\advanceby\boxhdisplacement\d_pack_layers_x_position \ifdim\boxhdisplacement<\zeropoint \global\setbox\b_pack_boxes_collector\hpack {\kern-\boxhdisplacement \box\b_pack_boxes_collector}% \fi \global\advanceby\boxvdisplacement\d_pack_layers_y_position \ifdim\boxvdisplacement<\zeropoint \global\setbox\b_pack_boxes_collector\hpack {\lower-\boxvdisplacement \box\b_pack_boxes_collector}% \fi \d_pack_layers_x_size\wd\b_pack_boxes_collector \d_pack_layers_y_size\htdp\b_pack_boxes_collector \global\setbox\b_pack_boxes_collector\hpack {\box\b_pack_boxes_collector \kern\dimexpr -\d_pack_layers_x_size +\d_pack_layers_x_position \ifdim\boxhdisplacement<\zeropoint -\boxhdisplacement \fi \relax \lower\d_pack_layers_y_position\hpack {\ifdim\boxvdisplacement<\zeropoint \lower-\boxvdisplacement \fi \box\nextbox}}% % combine height and depth into depth only (later flushed as height) \global\setbox\b_pack_boxes_collector\hpack {\lower\ht\b_pack_boxes_collector\box\b_pack_boxes_collector}% % just to be sure \ifdim\wd\b_pack_boxes_collector<\d_pack_layers_x_size \wd\b_pack_boxes_collector\d_pack_layers_x_size \fi \egroup} \permanent\protected\def\flushcollector[#1]% {\bgroup \pack_boxes_collector_check_box{#1}% \ifconditional\c_pack_boxes_collector_valid_box \edef\p_collector_state{\collectorparameter\c!state}% \ifx\p_collector_state\v!stop \else \vpack{\hpack{\raise \dp\b_pack_boxes_collector \ifx\p_collector_state\v!repeat\copy\else\box\fi\b_pack_boxes_collector}}% \fi \fi \egroup} \permanent\protected\def\composedcollector#1% no [], handy as argument {\flushcollector[#1]} \permanent\tolerant\protected\def\adaptcollector[#1]#*[#2]% % a typical case where \global\wd looks better in the code {\begingroup \pack_boxes_collector_check_box{#1}% \ifconditional\c_pack_boxes_collector_valid_box \letcollectorparameter\c!hoffset\zeropoint \letcollectorparameter\c!voffset\zeropoint \setupcurrentcollector[#2]% \global\wd\b_pack_boxes_collector\dimexpr\wd\b_pack_boxes_collector+\collectorparameter\c!hoffset\relax \global\ht\b_pack_boxes_collector\dimexpr\ht\b_pack_boxes_collector+\collectorparameter\c!voffset\relax \fi \endgroup} %\definecollector[test] %\setcollector[test] % [location=rb] % {\externalfigure[koe][frame=on,width=3cm]} %\setcollector[test] % [corner={right,bottom},location={left,top}] % {\framed{gans}} %\composedcollector{test} \definecollector [caption] \permanent\tolerant\protected\def\collectedtext[#1]#*[#2]% for captions {\pack_boxes_collector_text[#1][#2]} \def\pack_boxes_collector_text[#1][#2]#3% #3 is mandate so no tolerant here, so still two step {\bgroup \dowithnextbox {\setcollector [caption] {\box\nextbox}% \setcollector [caption][#1]% {\resetdummyparameter\c!style \resetdummyparameter\c!color \getdummyparameters[#2]% \dousestyleparameter{\directdummyparameter\c!style}% \setupinterlinespace \normalexpanded{\framed[\c!foregroundcolor=\directdummyparameter\c!color,\c!foregroundstyle=\directdummyparameter\c!style},\c!frame=\v!overlay,#2]{#3}}% \composedcollector{caption}% \egroup}% \hbox} % \collectedtext % [corner={right,bottom},location={left,top}] % [background=color,backgroundcolor=white,offset=0pt] % {gans} % {\externalfigure[koe][width=3cm]} % % \collectedtext % [rotation=90,corner={right,bottom},location={right,top}] % [frame=on,offset=0pt] % {gans} % {\externalfigure[koe][width=3cm]} % % \collectedtext % [rotation=90,corner={left,bottom},location={left,top}] % [frame=on,offset=0pt] % {gans} % {\externalfigure[koe][width=3cm]} \installcorenamespace {layeredtext} \installcorenamespace {layeredtextlayer} \installcorenamespace {layeredtextframed} \installsimpleframedcommandhandler \??layeredtext {layeredtext} \??layeredtext \newdimension\d_pack_layeredtexts_width \newdimension\d_pack_layeredtexts_height \definelayer % private [\??layeredtextlayer] \setuplayer % private [\??layeredtextlayer] [\c!width=\d_pack_layeredtexts_width, \c!height=\d_pack_layeredtexts_height] \defineframed % private [\??layeredtextframed] [\c!offset=\v!overlay, \c!frame=\v!off, \c!background={\v!foreground,\??layeredtextlayer}, \c!width=\d_pack_layeredtexts_width, \c!height=\d_pack_layeredtexts_height] \setuplayeredtext % public (the attached data, usually small stuff, not the main thing) [\c!frame=\v!overlay, \c!color=, \c!style=, \c!foregroundcolor=\layeredtextparameter\c!color, \c!foregroundstyle=\layeredtextparameter\c!style] \permanent\tolerant\protected\def\placelayeredtext[#1]#*[#2]#*[#3]#4% tag layersettings content(framed)settings content {\bgroup \edef\currentlayeredtext{#1}% \checklayeredtextparent % bonus \setupcurrentlayeredtext[#3]% \dowithnextbox {\d_pack_layeredtexts_width \wd\nextbox \d_pack_layeredtexts_height\ht\nextbox \begingroup % preserve \nextbox \setlayer [\??layeredtextlayer]% [#2]% {\setfalse\fontattributeisset \uselayeredtextstyleparameter\c!style \ifconditional\fontattributeisset \setupinterlinespace \fi \inheritedlayeredtextframed{#4}}% \endgroup \placeframed[\??layeredtextframed]{\flushnextbox}% \egroup}% \hbox} \permanent\protected\def\layeredtext {\placelayeredtext[]} % \layeredtext % [corner={right,bottom},location={left,top}] % [background=color,backgroundcolor=white,offset=0pt] % {gans} % {\externalfigure[koe][width=3cm]} % % \layeredtext % [rotation=90,corner={right,bottom},location={right,top}] % [frame=on,offset=0pt] % {gans} % {\externalfigure[koe][width=3cm]} % % \layeredtext % [rotation=90,corner={left,bottom},location={left,top}] % [frame=on,offset=0pt] % {gans} % {\externalfigure[koe][width=3cm]} \permanent\tolerant\protected\def\ornamenttext[#1]#*[#2]% takes another argument {\bgroup \doifelseassignment{#1}% {\letdummyparameter\c!alternative\v!a \getdummyparameters[#1]% \doifelse{\directdummyparameter\c!alternative}\v!a {\egroup\collectedtext}% {\egroup\layeredtext }% [#1][#2]}% {\egroup\csname#1\endcsname}} \permanent\tolerant\protected\def\defineornament[#1]#*[#2]#*[#3]% {\protected\frozen\instance\defcsname#1\endcsname{\ornamenttext[#2][#3]}} % \defineornament % [affiliation] % [rotation=90,corner={right,bottom},location={right,top}, % hoffset=-.25ex] % [frame=on,background=color,backgroundcolor=red,offset=0pt] % % \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}} % % \defineornament % [affiliation] % [rotation=90,corner={right,bottom},location={right,top}, % hoffset=-.25ex,alternative=b] % [frame=on,background=color,backgroundcolor=red,offset=0pt] % % \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}} % % \defineornament % [affiliation] % [rotation=90,corner={right,bottom},location={left,top}, % hoffset=.25ex,voffset=.25ex,alternative=a] % [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt] % % \affiliation{photo}{\externalfigure[molen][width=3cm]} % % \defineornament % [affiliation] % [rotation=90,corner={right,bottom},location={left,top}, % hoffset=.25ex,voffset=.25ex,alternative=b] % [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt] % % \affiliation{drawing}{\externalfigure[hakker][width=3cm]} \newinteger\c_pack_boxes_bleeds \installcorenamespace {bleeding} \installdirectcommandhandler \??bleeding {bleeding} % \??bleeding \setupbleeding [\c!location=l, \c!stretch=\v!yes, \c!width=3cm, \c!height=3cm, \c!offset=2mm, \c!page=\v!no, \c!voffset=\scratchoffset, % is set to \bleedingparameter\c!offset \c!hoffset=\scratchoffset] % which often saves one resolve \permanent\def\bleedwidth {\the\hsize} % these are global ! \permanent\def\bleedheight{\the\vsize} % these are global ! \newconditional\c_pack_boxes_l \newconditional\c_pack_boxes_r \newconditional\c_pack_boxes_t \newconditional\c_pack_boxes_b \installcorenamespace{bleedinglocation} \defcsname\??bleedinglocation t\endcsname{\settrue\c_pack_boxes_t\scratchhoffset\zeropoint} \defcsname\??bleedinglocation b\endcsname{\settrue\c_pack_boxes_b\scratchhoffset\zeropoint} \defcsname\??bleedinglocation l\endcsname{\settrue\c_pack_boxes_l\scratchvoffset\zeropoint} \defcsname\??bleedinglocation r\endcsname{\settrue\c_pack_boxes_r\scratchvoffset\zeropoint} \defcsname\??bleedinglocation bl\endcsname{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_b} \defcsname\??bleedinglocation lb\endcsname{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_b} \defcsname\??bleedinglocation br\endcsname{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_b} \defcsname\??bleedinglocation rb\endcsname{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_b} \defcsname\??bleedinglocation tl\endcsname{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_t} \defcsname\??bleedinglocation lt\endcsname{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_t} \defcsname\??bleedinglocation tr\endcsname{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_t} \defcsname\??bleedinglocation rt\endcsname{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_t} \mutable\lettonothing\currentbleedposition \mutable\lettonothing\currentpageposition \permanent\tolerant\protected\def\bleed[#1]% {\hbox\bgroup \global\advanceby\c_pack_boxes_bleeds\plusone % \enforced\permanent\xdef\bleedwidth {\the\hsize}% \enforced\permanent\xdef\bleedheight{\the\vsize}% % \edef\currentbleedposition{bleed:\number\c_pack_boxes_bleeds}% \edef\currentpageposition {page:0}% todo: per page % \setupcurrentbleeding[#1]% % \scratchwidth \bleedingparameter\c!width \scratchheight \bleedingparameter\c!height \scratchoffset \bleedingparameter\c!offset \scratchhoffset\bleedingparameter\c!hoffset \scratchvoffset\bleedingparameter\c!voffset % \setfalse\c_pack_boxes_l % left \setfalse\c_pack_boxes_r % right \setfalse\c_pack_boxes_t % top \setfalse\c_pack_boxes_b % bottom % \csname\??bleedinglocation\bleedingparameter\c!location\endcsname % \doifelse{\bleedingparameter\c!stretch}\v!yes\donetrue\donefalse % \enforced\permanent\xdef\bleedwidth{\the\dimexpr \ifdone \ifconditional\c_pack_boxes_l \scratchwidth+\MPx\currentbleedposition-\MPx\currentpageposition \orelse\ifconditional\c_pack_boxes_r \paperwidth -\MPx\currentbleedposition+\MPx\currentpageposition % not checked \else \scratchwidth \fi \else \scratchwidth \fi+\scratchhoffset \relax}% \enforced\permanent\xdef\bleedheight{\the\dimexpr \ifdone \ifconditional\c_pack_boxes_t \paperheight -\MPy\currentbleedposition+\MPy\currentpageposition % not checked \orelse\ifconditional\c_pack_boxes_b \scratchheight+\MPy\currentbleedposition-\MPy\currentpageposition + \MPh\currentbleedposition % not checked (\MPh added) \else \scratchheight \fi \else \scratchheight \fi+\scratchvoffset \relax}% \dowithnextboxcontentcs\pack_boxes_bleed_settings\pack_boxes_bleed_finish\hbox} \def\pack_boxes_bleed_settings {\hsize\bleedwidth \vsize\bleedheight} \def\pack_boxes_bleed_finish {\doif{\bleedingparameter\c!page}\v!yes {\setbox\nextbox\topskippedbox{\box\nextbox}}% \setbox\nextbox\hpack to \scratchwidth {\ifconditional\c_pack_boxes_l\hss\fi \box\nextbox \ifconditional\c_pack_boxes_r\hss\fi}% \ifconditional\c_pack_boxes_b \setbox\nextbox\hpack {\lower\bleedheight\hpack{\raise\scratchheight\box\nextbox}}% \fi \wd\nextbox\scratchwidth \ht\nextbox\scratchheight \dp\nextbox\zeropoint \ifdone \hpos\currentbleedposition{\box\nextbox}% \else \box\nextbox \fi \egroup} \defineexternalfigure [bleed] % should be \v!bleed [\c!width=\bleedwidth, \c!height=\bleedheight] % \placefigure[left]{none} % {\bleed[width=5cm,height=3cm,location=lt]{\externalfigure[koe][bleed]}} % % \input tufte % % \placefigure[left]{none} % {\bleed[width=5cm,height=3cm,location=l]{\externalfigure[koe][bleed]}} % % \input tufte % % \placefigure[right]{none} % {\bleed[width=5cm,height=3cm,location=r]{\externalfigure[koe][bleed]}} % % \input tufte % % \placefigure % [top,none] % {} % no caption % {\bleed % [hoffset=-\backspace, % voffset=3mm, % width=0cm, % height=6\lineheight, % page=yes, % correct for topskip % location=lt] % {\externalfigure[koe][bleed][frame=on]}} % \setlayerframed[layer id][layer settings][framed setting]{data} % \setlayerframed[layer id][combined settings]{data} % tricky: offsets apply to both the layer and the framed; it makes sense to % only apply the offset to ... \permanent\tolerant\protected\def\setlayerframed[#1]#*[#2]#*[#3] {\ifarguments % error \or \expandafter\pack_layers_set_framed_s \or \expandafter\pack_layers_set_framed_d \or \expandafter\pack_layers_set_framed_t \fi[#1][#2][#3]} \def\pack_layers_set_framed_s[#1][#2][#3]% {\setlayer[#1][\c!width=\wd\nextbox,\c!height=\ht\nextbox,\c!offset=\zeropoint]% \normalframedwithsettings[\c!location=\v!normal]} % different kind of location \def\pack_layers_set_framed_d[#1][#2][#3]% {\setlayer[#1][\c!width=\wd\nextbox,\c!height=\ht\nextbox,#2,\c!offset=\zeropoint]% \normalframedwithsettings[\c!location=\v!normal,#2]} % different kind of location \def\pack_layers_set_framed_t[#1][#2][#3]% {\setlayer[#1][#2]% \normalframedwithsettings[#3]} \permanent\tolerant\protected\def\setlayertext[#1]#*[#2]#*[#3]% {\bgroup \resetdummyparameter\c!align \letdummyparameter \c!width\hsize \resetdummyparameter\c!color \resetdummyparameter\c!style \getdummyparameters[#3]% \dowithnextboxcontent {\forgetall \hsize\directdummyparameter\c!width \usealignparameter\directdummyparameter \dousestyleparameter{\directdummyparameter\c!style}} {\setlayer[#1][#2]{\strut\dousecolorparameter{\directdummyparameter\c!color}\flushnextbox}% maybe expand the color \egroup}% \vtop} % \setupbackgrounds % [page] % [background=pagefigures] % % \definelayer % [pagefigures] % [x=-2mm, % y=-2mm, % width=\paperwidth, % height=\paperheight] % % \definelayerpreset [lefttop] [corner={left,top},location={right,bottom}] % \definelayerpreset [righttop] [corner={right,top},location={left,bottom}] % \definelayerpreset [leftbottom] [corner={left,bottom},location={right,top}] % \definelayerpreset [rightbottom] [corner={right,bottom},location={left,top}] % \definelayerpreset [middle] [corner=middle,location=middle] % % \setlayer[pagefigures][preset=lefttop] % \setlayer[pagefigures][preset=righttop] % \setlayer[pagefigures][preset=leftbottom] % \setlayer[pagefigures][preset=rightbottom] \definelayerpreset [\v!left\v!top] [\c!corner={\v!left,\v!top},\c!location={\v!right,\v!bottom}] \definelayerpreset [\v!right\v!top] [\c!corner={\v!right,\v!top},\c!location={\v!left,\v!bottom}] \definelayerpreset [\v!left\v!bottom] [\c!corner={\v!left,\v!bottom},\c!location={\v!right,\v!top}] \definelayerpreset [\v!right\v!bottom] [\c!corner={\v!right,\v!bottom},\c!location={\v!left,\v!top}] \definelayerpreset [\v!middle] [\c!corner=\v!middle,\c!location=\v!middle] \definelayerpreset [\v!middle\v!top] [\c!location=\v!bottom,\c!corner=\v!top,\c!dx=.5\layerwidth] \definelayerpreset [\v!middle\v!bottom] [\c!location=\v!top,\c!corner=\v!bottom,\c!dx=.5\layerwidth] \definelayerpreset [\v!middle\v!left] [\c!location=\v!right,\c!corner=\v!left,\c!dy=.5\layerheight] \definelayerpreset [\v!middle\v!right] [\c!location=\v!left,\c!corner=\v!right,\c!dy=.5\layerheight] % left and right hanging: \definelayerpreset [\v!left\v!top\v!left] [\c!location={\v!left,\v!bottom},\c!corner={\v!left,\v!top}] \definelayerpreset [\v!right\v!top\v!right] [\c!location={\v!right,\v!bottom},\c!corner={\v!right,\v!top}] \installcorenamespace{alignedboxes} \permanent\tolerant\protected\def\alignedbox[#1]{\bgroup\serializecommalist[#1]\dowithnextboxcs\pack_boxes_aligned_finish} \permanent\tolerant\protected\def\aligned [#1]{\bgroup\serializecommalist[#1]\dowithnextboxcs\pack_boxes_aligned_finish\hbox} \def\pack_boxes_aligned_finish {\ifcsname\??alignedboxes\serializedcommalist\endcsname \expandafter\lastnamedcs \else \expandafter\middlebox \fi{\flushnextbox}% \egroup} \letcsname\??alignedboxes \endcsname\middlebox \letcsname\??alignedboxes\v!middle \endcsname\middlebox \letcsname\??alignedboxes\v!middle\v!middle\endcsname\middlebox \letcsname\??alignedboxes\v!left \endcsname\leftbox \letcsname\??alignedboxes\v!left \v!top \endcsname\lefttopbox \letcsname\??alignedboxes\v!left \v!bottom\endcsname\leftbottombox \letcsname\??alignedboxes\v!right \endcsname\rightbox \letcsname\??alignedboxes\v!right \v!top \endcsname\righttopbox \letcsname\??alignedboxes\v!right \v!bottom\endcsname\rightbottombox \letcsname\??alignedboxes\v!bottom \endcsname\bottombox \letcsname\??alignedboxes\v!bottom\v!left \endcsname\bottomleftbox \letcsname\??alignedboxes\v!bottom\v!right \endcsname\bottomrightbox \letcsname\??alignedboxes\v!top \endcsname\topbox \letcsname\??alignedboxes\v!top \v!left \endcsname\topleftbox \letcsname\??alignedboxes\v!top \v!right \endcsname\toprightbox \letcsname\??alignedboxes\v!line \endcsname\baselinemiddlebox % \v!grid is taken \letcsname\??alignedboxes\v!line \v!left \endcsname\baselineleftbox \letcsname\??alignedboxes\v!line \v!middle\endcsname\baselinemiddlebox \letcsname\??alignedboxes\v!line \v!right \endcsname\baselinerightbox \letcsname\??alignedboxes c\endcsname\middlebox \letcsname\??alignedboxes l\endcsname\leftbox \letcsname\??alignedboxes r\endcsname\rightbox \letcsname\??alignedboxes b\endcsname\bottombox \letcsname\??alignedboxes t\endcsname\topbox \letcsname\??alignedboxes lt\endcsname\lefttopbox \letcsname\??alignedboxes lb\endcsname\leftbottombox \letcsname\??alignedboxes rt\endcsname\righttopbox \letcsname\??alignedboxes rb\endcsname\rightbottombox \letcsname\??alignedboxes tl\endcsname\topleftbox \letcsname\??alignedboxes bl\endcsname\bottomleftbox \letcsname\??alignedboxes tr\endcsname\toprightbox \letcsname\??alignedboxes br\endcsname\bottomrightbox \letcsname\??alignedboxes m\endcsname\middlebox \letcsname\??alignedboxes g\endcsname\baselinemiddlebox \letcsname\??alignedboxes gl\endcsname\baselineleftbox \letcsname\??alignedboxes gc\endcsname\baselinemiddlebox \letcsname\??alignedboxes gr\endcsname\baselinerightbox % left/right/top/bottomoffset -> dimensions change % x/y | method=fixed -> dimensions don't change \installcorenamespace{offsetbox} \installautocommandhandler \??offsetbox {offsetbox} \??offsetbox \setupoffsetbox [\c!x=\zeropoint, \c!y=\zeropoint, \c!width=\wd\nextbox, \c!height=\ht\nextbox, \c!depth=\dp\nextbox, \c!location=, \c!leftoffset=\zeropoint, \c!rightoffset=\zeropoint, \c!topoffset=\zeropoint, \c!bottomoffset=\zeropoint, \c!method=] \aliased\let\setupoffset\setupoffsetbox \permanent\tolerant\protected\def\offsetbox[#1]% {\bgroup \pack_boxes_offset_check[#1]% \dowithnextboxcs\pack_boxes_offsetfinish} \permanent\tolerant\protected\def\offset[#1]% {\bgroup \pack_boxes_offset_check[#1]% \dowithnextboxcs\pack_boxes_offsetfinish\hbox} \newinteger\c_pack_boxes_offset_level \def\pack_boxes_offset_check {\advanceby\c_pack_boxes_offset_level\plusone \edef\currentoffsetbox{\the\c_pack_boxes_offset_level}% \checkoffsetboxparent \setupcurrentoffsetbox} \def\pack_boxes_offsetfinish {\donefalse \scratchxposition \offsetboxparameter\c!x \scratchyposition \offsetboxparameter\c!y \scratchleftoffset \offsetboxparameter\c!leftoffset \scratchrightoffset \offsetboxparameter\c!rightoffset \scratchtopoffset \offsetboxparameter\c!topoffset \scratchbottomoffset\offsetboxparameter\c!bottomoffset \relax % really needed \ifzeropt\scratchleftoffset \else\donetrue\fi \ifzeropt\scratchrightoffset \else\donetrue\fi \ifzeropt\scratchtopoffset \else\donetrue\fi \ifzeropt\scratchbottomoffset\else\donetrue\fi \ifdone \edef\p_method{\offsetboxparameter\c!method}% \ifx\p_method\v!fixed % new \ifzeropt\scratchleftoffset \ifzeropt\scratchrightoffset \else \scratchxposition-\scratchrightoffset \scratchrightoffset\zeropoint \fi \else \scratchxposition\scratchleftoffset \scratchleftoffset\zeropoint \fi \ifzeropt\scratchtopoffset \ifzeropt\scratchbottomoffset \else \scratchyposition-\scratchbottomoffset \scratchbottomoffset\zeropoint \fi \else \scratchyposition\scratchtopoffset \scratchtopoffset\zeropoint \fi \donefalse \fi \fi \ifdone \setbox\nextbox\vpack {\forgetall % already done \offinterlineskip \kern\scratchtopoffset \hpack {\kern\scratchleftoffset \box\nextbox \kern\scratchrightoffset}% \kern\scratchbottomoffset}% \ht\nextbox\htdp\nextbox \dp\nextbox\zeropoint \fi \scratchwidth \offsetboxparameter\c!width \scratchheight\offsetboxparameter\c!height \scratchdepth \offsetboxparameter\c!depth \edef\p_location{\offsetboxparameter\c!location}% \setbox\nextbox\hpack {\kern\scratchxposition \lower\scratchyposition\hpack {\ifempty\p_location \box\nextbox \else \alignedbox[\p_location]\hpack{\box\nextbox}% \fi}}% \wd\nextbox\scratchwidth \ht\nextbox\scratchheight \dp\nextbox\scratchdepth \box\nextbox \egroup} %D \starttyping %D \framed[offset=overlay]{\offset[leftoffset=1cm] %D {\framed[offset=overlay]{\offset[rightoffset=1cm] %D {\externalfigure[koe][width=1cm]}}}} %D %D \blank %D %D \framed[offset=overlay]{\offset[leftoffset=1cm] {\externalfigure[koe][width=5cm]}} \blank %D \framed[offset=overlay]{\offset[rightoffset=1cm] {\externalfigure[koe][width=5cm]}} \blank %D \framed[offset=overlay]{\offset[topoffset=1cm] {\externalfigure[koe][width=5cm]}} \blank %D \framed[offset=overlay]{\offset[bottomoffset=1cm]{\externalfigure[koe][width=5cm]}} \blank %D \stoptyping % \useMPlibrary[pre] \setupbackgrounds[page][background=pagegrid] % % \placefigure[left,none]{}{\offset[leftoffset=1cm] {\externalfigure[cow][width=3cm]}} \input tufte % \placefigure[left,none]{}{\offset[rightoffset=1cm] {\externalfigure[cow][width=3cm]}} \input tufte % \placefigure[left,none]{}{\offset[topoffset=1cm] {\externalfigure[cow][width=3cm]}} \input tufte % \placefigure[left,none]{}{\offset[bottomoffset=1cm]{\externalfigure[cow][width=3cm]}} \input tufte % Some old code: % % \ltabbed{\romannumerals{3}}{\romannumerals{1}} test \endgraf % \ltabbed{\romannumerals{3}}{\romannumerals{2}} test \endgraf % \ltabbed{\romannumerals{3}}{\romannumerals{3}} test \endgraf % % \rtabbed{\romannumerals{3}}{\romannumerals{1}} test \endgraf % \rtabbed{\romannumerals{3}}{\romannumerals{2}} test \endgraf % \rtabbed{\romannumerals{3}}{\romannumerals{3}} test \endgraf % % \ctabbed{\romannumerals{3}}{\romannumerals{1}} test \endgraf % \ctabbed{\romannumerals{3}}{\romannumerals{2}} test \endgraf % \ctabbed{\romannumerals{3}}{\romannumerals{3}} test \endgraf \def\pack_boxes_tabbed#1#2#3#4% {\dontleavehmode \begingroup \setbox\scratchbox\hpack{#3}% \hpack to \wd\scratchbox{#1#4#2}% \endgroup} \permanent\protected\def\ltabbed{\pack_boxes_tabbed\relax\hss} \permanent\protected\def\rtabbed{\pack_boxes_tabbed\hss \relax} \permanent\protected\def\ctabbed{\pack_boxes_tabbed\hss \hss} \aliased\let\mtabbed\ctabbed % to be documented \permanent\protected\def\phantombox[#1]% == \framed[\c!empty=\v!yes,\c!offset=\v!overlay,#1]{} {\hpack\bgroup \letdummyparameter\c!width \zeropoint \letdummyparameter\c!height\zeropoint \letdummyparameter\c!depth \zeropoint \getdummyparameters[#1]% \setbox\scratchbox\emptyhbox \wd\scratchbox\directdummyparameter\c!width \ht\scratchbox\directdummyparameter\c!height \dp\scratchbox\directdummyparameter\c!depth \box\scratchbox \egroup} % \backgroundimage{1}{\hsize}{\vsize}{\externalfigure[cow][\c!width=3cm]} % \framed[offset=overlay,width=6cm,height=3cm]{\backgroundimage {1}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=6cm,height=3cm]{\backgroundimage {2}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=6cm,height=3cm]{\backgroundimage {3}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}} % % \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[mill]}} % \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[mill]}} % \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[mill]}} % \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[mill]}} % \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[mill]}} % \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[mill]}} \permanent\protected\def\backgroundimage#1#2#3% repeat hsize vsize {\bgroup \forgetall \scratchcounter#1\relax \scratchwidth #2\relax \scratchheight #3\relax \dowithnextboxcs\pack_boxes_background_image\hbox} \def\pack_boxes_background_image {\offinterlineskip \ifcase\scratchcounter % just one \else \scratchdimen\scratchwidth \divideby\scratchdimen\wd\nextbox\scratchnx\scratchdimen\advanceby\scratchnx\plusone\relax \scratchdimen\scratchheight\divideby\scratchdimen\ht\nextbox\scratchny\scratchdimen\advanceby\scratchny\plusone\relax % to be considered: methods \ifcase\scratchcounter \or % x and y \setbox\nextbox\hpack{\dorecurse\scratchnx{\copy\nextbox}}% \setbox\nextbox\vpack{\dorecurse\scratchny{\copy\nextbox\endgraf}}% \or % x \setbox\nextbox\hpack{\dorecurse\scratchnx{\copy\nextbox}}% \or % y \setbox\nextbox\vpack{\dorecurse\scratchny{\copy\nextbox\endgraf}}% \fi \fi \ifdim\wd\nextbox>\scratchwidth \setbox\nextbox\hpack to \scratchwidth{\hss\box\nextbox\hss}% \setbox\nextbox\hpack{\normalexpanded{\clip[\c!width=\the\scratchwidth,\c!height=\the\ht\nextbox]{\box\nextbox}}}% \fi \ifdim\ht\nextbox>\scratchheight \setbox\nextbox\vpack to \scratchheight{\vss\box\nextbox\vss}% \setbox\nextbox\hpack{\normalexpanded{\clip[\c!width=\the\wd\nextbox,\c!height=\the\scratchheight]{\box\nextbox}}}% \fi \box\nextbox \egroup} \permanent\protected\def\backgroundimagefill#1#2#3% repeat hsize vsize {\bgroup \forgetall \scratchcounter#1\relax \scratchwidth #2\relax \scratchheight #3\relax \dowithnextboxcs\pack_boxes_background_image_fill\hbox} \def\pack_boxes_background_image_fill {\offinterlineskip \setbox\nextbox\hpack\bgroup \ifdim\scratchwidth>\scratchheight \scale[\c!width=\the\scratchwidth]{\box\nextbox}% \else \scale[\c!height=\the\scratchheight]{\box\nextbox}% \fi \egroup \ifdim\wd\nextbox>\scratchwidth \setbox\nextbox\hpack to \scratchwidth {\ifcase\scratchcounter \hss\box\nextbox\hss \or \box\nextbox\hss \or \hss\box\nextbox \else \hss\box\nextbox\hss \fi}% \setbox\nextbox\hpack {\normalexpanded{\clip[\c!width=\the\scratchwidth,\c!height=\the\ht\nextbox]{\box\nextbox}}}% \fi \ifdim\ht\nextbox>\scratchheight \setbox\nextbox\vpack to \scratchheight {\ifcase\scratchcounter \vss\box\nextbox\vss \or \box\nextbox\vss \or \vss\box\nextbox \else \vss\box\nextbox\vss \fi}% \setbox\nextbox\hpack {\normalexpanded{\clip[\c!width=\the\wd\nextbox,\c!height=\the\scratchheight]{\box\nextbox}}}% \fi \box\nextbox \egroup} \permanent\protected\def\overlayimage#1% {\vpack to \overlayheight\bgroup \vss \hpack to \overlaywidth\bgroup \hss \externalfigure[#1][\c!factor=\v!min,\c!equalwidth=\overlaywidth,\c!equalheight=\overlayheight]% \hss \egroup \vss \egroup} \permanent\protected\def\clippedoverlayimage#1% {\clip [\c!width=\overlaywidth,\c!height=\overlayheight] {\overlayimage{#1}}} %D Here is an end December 2021 experimental feature: anchored boxes. \installcorenamespace{boxanchor} \installcorenamespace{boxanchorid} \installcorenamespace{boxanchorbox} \installcorenamespace{boxpreset} \installcorenamespace{boxanchors} \installparameterhandler \??boxanchor {boxanchor} \installsetuphandler \??boxanchor {boxanchor} \setupboxanchor [\c!xoffset=\zeropoint, \c!yoffset=\zeropoint] \newinteger\c_boxes_n_of_anchors \permanent\protected\def\defineanchorbox[#1]% {\ifcsname\??boxanchorid#1\endcsname \box\lastnamedcs\emptybox \else \global\advanceby\c_boxes_n_of_anchors\plusone \expandafter\integerdef\csname\??boxanchorid #1\endcsname\c_boxes_n_of_anchors \expandafter\newbox \csname\??boxanchorbox#1\endcsname \fi} \permanent\protected\def\defineanchorboxoverlay[#1]% {\defineanchorbox[#1:\v!background]% \defineanchorbox[#1:\v!foreground]% \defineoverlay[#1:\v!background][\overlayanchorbox{#1:\v!background}]% \defineoverlay[#1:\v!foreground][\overlayanchorbox{#1:\v!foreground}]} \permanent\def\namedanchorbox#1% {\begincsname\??boxanchorid#1\endcsname} % no checking \permanent\protected\def\overlayanchorbox#1% {\begingroup \scratchcounter\csname\??boxanchorbox#1\endcsname \ifvoid\scratchcounter\else \boxsource\scratchcounter\namedanchorbox{#1}% \wd\scratchcounter\d_overlay_width \ht\scratchcounter\d_overlay_height \dp\scratchcounter\d_overlay_depth \box\scratchcounter \fi \endgroup} \mutable\lettonothing\currentanchorbox \permanent\tolerant\protected\def\setanchorbox[#1]#*[#2]% {\begingroup \dowithnextbox {\def\currentanchorbox{#1}% \setupboxanchor[#2]% \scratchcounterone\csname\??boxanchorbox#1\endcsname\relax \scratchxoffset\boxanchorparameter\c!xoffset\relax \scratchyoffset\boxanchorparameter\c!yoffset\relax \boxtarget\nextbox \namedanchorbox {#1}\relax \boxanchors\nextbox % target \numexpr \ifcsname\??boxpreset\boxanchorparameter\c!target\endcsname \lastnamedcs \else \halfwaytotallistanchorcode \fi \relax % source \numexpr \ifcsname\??boxpreset\boxanchorparameter\c!source\endcsname \lastnamedcs \else \halfwaytotallistanchorcode \fi \relax \ifzeropt\scratchxoffset\else \boxxoffset\nextbox\scratchxoffset \fi \ifzeropt\scratchyoffset\else \boxyoffset\nextbox\scratchyoffset \fi \global\setbox\scratchcounterone\hpack\bgroup \unhbox\scratchcounterone \kern-\wd\nextbox \box\nextbox \egroup \endgroup}} \expandafter\integerdef\csname\??boxpreset\v!left \endcsname\leftoriginlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!left,\v!height \endcsname\leftheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!left,\v!top \endcsname\leftheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!left,\v!depth \endcsname\leftdepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!left,\v!bottom \endcsname\leftdepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!right \endcsname\rightoriginlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!right,\v!height \endcsname\rightheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!right,\v!top \endcsname\rightheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!right,\v!depth \endcsname\rightdepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!right,\v!bottom \endcsname\rightdepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!line \endcsname\centeroriginlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!height \endcsname\centerheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!depth \endcsname\centerdepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle \endcsname\halfwaytotallistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle,\v!height\endcsname\halfwayheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle,\v!top \endcsname\halfwayheightlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle,\v!depth \endcsname\halfwaydepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle,\v!bottom\endcsname\halfwaydepthlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle,\v!left \endcsname\halfwayleftlistanchorcode \expandafter\integerdef\csname\??boxpreset\v!middle,\v!right \endcsname\halfwayrightlistanchorcode % Musical timestamp: 2022-02-07 while listening Hypneurotic from The Blurred Horizon (n times); % Jim Matheos with Gavin Harrison; very hypnotic indeed. \permanent\def\boxanchorpresetcode#1% {\ifcsname\??boxpreset#1\endcsname\lastnamedcs\else\halfwaytotallistanchorcode\fi} \newinteger\registeredboxanchor \installmacrostack\boxanchoringclass \mutable\lettonothing\boxanchoringclass \newinteger\c_anchor_auto_box_class \permanent\protected\def\startboxanchoring[#1]% + == auto {\push_macro_boxanchoringclass \iftok{#1}{+}% \global\advanceby\c_anchor_auto_box_class\plusone \edef\boxanchoringclass{\the\c_anchor_auto_box_class::}% \else \edef\boxanchoringclass{#1} \fi} \permanent\protected\def\stopboxanchoring {\pop_macro_boxanchoringclass} \permanent\protected\def\registerboxanchor {\global\advanceby\registeredboxanchor\minusone} \permanent\protected\def\defineboxanchor[#1]% {\registerboxanchor \global\expandafter\integerdef\csname\??boxanchors#1\endcsname\registeredboxanchor} \permanent\protected\def\doifnotanchorbox#1% {\ifcsname\??boxanchors#1\endcsname \expandafter\gobbleoneargument \else \expandafter\firstofoneargument \fi} \permanent\def\namedboxanchor#1% {\normalexpanded{\ifcsname\??boxanchors#1\endcsname\lastnamedcs\orelse\ifchknum#1\or#1\else\zerocount\fi}} \permanent\def\namespacedboxanchor#1% {boxanchor:\number\namedboxanchor{#1}} \installcorenamespace{boxanchorcontent} % \installparameterhandler \??boxanchorcontent {boxanchorcontent} % \installautosetuphandler \??boxanchorcontent {boxanchorcontent} \installcommandhandler \??boxanchorcontent {boxanchorcontent} \??boxanchorcontent % no real need but let's have a define too \setupboxanchorcontent [\c!yoffset=\zeropoint, \c!xoffset=\zeropoint, \c!width=\zeropoint, \c!location=\v!height, \c!corner=\v!depth] \permanent\tolerant\protected\def\setboxanchor[#1]#*[#2]#*[#3]#*% assumes \defineboxanchor[#1] {\begingroup \dowithnextbox {\ifhastok={#2}% \setupcurrentboxanchorcontent[#2]% \else \def\currentboxanchorcontent{#2}% \setupcurrentboxanchorcontent[#3]% \fi \scratchxoffset\boxanchorcontentparameter\c!xoffset \scratchyoffset\boxanchorcontentparameter\c!yoffset \scratchcounter\namedboxanchor{#1}% \registeranchorbox \scratchcounter \plusone % order \hbox \s!anchors % check order of these: \boxanchorpresetcode{\boxanchorcontentparameter\c!corner} \boxanchorpresetcode{\boxanchorcontentparameter\c!location} \ifzeropt\scratchxoffset\else \s!xoffset \scratchxoffset\fi \ifzeropt\scratchyoffset\else \s!yoffset \scratchyoffset\fi \s!target \scratchcounter {\box\nextbox}% \endgroup}} %D The name might change: \permanent\protected\def\mathrowanchored #1{\alignmentwrapsource\namedboxanchor{#1}\relax} \permanent\protected\def\mathcellanchored#1{\alignmentcellsource\namedboxanchor{#1}\relax} %permanent\protected\def\mathboxanchored#1#2{#2\Umathsource\namedboxanchor{#1}\relax} \permanent\tolerant\protected\def\mathboxanchored[#1]#:#2#3% {#3\Umathsource\iftok{#1}{nucleus}#1\fi\namedboxanchor{\boxanchoringclass:#2}\relax} % to be used as: % % \scratchcounter\registeredboxanchor % % \registeranchorbox % \scratchcounter % \plusone % \ruledhbox{...} % % \hbox source \scratchcounter % \negatexlistsigncode % \negateylistsigncode % \negatelistsigncode \protect \endinput