%D \module
%D   [       file=pack-box,
%D        version=2026-03-16, % 2002.04.12
%D          title=\CONTEXT\ Packaging Macros,
%D       subtitle=Boxes,
%D         author={Hans Hagen & Wolfgang Schuster},
%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]#*[#S#3]#*[#S#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[##S##1]##*[##S##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:\the\c_pack_anchors_n]%
   \putboxincache\v!anchor{\the\c_pack_anchors_n}\b_pack_anchors
   \xtoksapp\t_pack_anchors_flush{\pack_anchors_flush{\the\c_pack_anchors_n}{#1}{#2}}%
 % \doglobal\appendetoks
 %   \pack_anchors_flush{\the\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
   \expand\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]#*[#S#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
     \c_pack_boxes_collector_valid_box\conditionaltrue
     \expandafter\let\expandafter\b_pack_boxes_collector\lastnamedcs
   \else
     \c_pack_boxes_collector_valid_box\conditionalfalse
     \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}

\lettonothing\p_collector_corner
\lettonothing\p_collector_rotation
\lettonothing\p_collector_state

\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{\collectorparameter\c!x+\collectorparameter\c!hoffset}%
   \d_pack_layers_y_position{\collectorparameter\c!y+\collectorparameter\c!voffset}%
   \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{%
        -\d_pack_layers_x_size
        +\d_pack_layers_x_position
         \ifdim\boxhdisplacement<\zeropoint
           -\boxhdisplacement
         \fi
      }%
      \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]#*[#S#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{\wd\b_pack_boxes_collector+\collectorparameter\c!hoffset}%
     \global\ht\b_pack_boxes_collector{\ht\b_pack_boxes_collector+\collectorparameter\c!voffset}%
   \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]#*[#S#2]% for captions
  {\pack_boxes_collector_text[#1][#2]}

\def\pack_boxes_collector_text[#1][#S#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
         \expanded{\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]#*[#S#2]#*[#S#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]%
        {\fontattributeisset\conditionalfalse
         \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]#*[#S#2]% takes another argument
%   {\bgroup
%    \doifelseassignment{#1}%
%      {\letdummyparameter\c!alternative\v!a
%       \getdummyparameters[#1]%
%       \ifcstok{\directdummyparameter\c!alternative}\v!a
%         \egroup\expandafter\collectedtext
%       \else
%         \egroup\expandafter\layeredtext
%       \fi[#1][#2]}%
%      {\egroup\csname#1\endcsname}}
%
% \permanent\tolerant\protected\def\defineornament[#1]#*[#2]#*[#3]%
%   {\protected\frozen\instance\defcsname#1\endcsname{\ornamenttext[#2][#3]}}

%D This more indirect method permits checking if an ornament is defined so that we
%D can use them as caption location.

\installcorenamespace {ornament}

\permanent\tolerant\protected\def\ornamenttext[#1]#*[#S#2]% takes another argument
  {\bgroup
   \doifelseassignment{#1}%
     {\letdummyparameter\c!alternative\v!a
      \getdummyparameters[#1]%
      \ifcstok{\directdummyparameter\c!alternative}\v!a
        \egroup\expandafter\collectedtext
      \else
        \egroup\expandafter\layeredtext
      \fi[#1][#2]}%
     {\egroup\csname#1\endcsname}}

\permanent\tolerant\protected\def\defineornament[#1]#*[#2]#*[#3]%
  {\begingroup
   \ifhastok={#2}%
     \letdummyparameter\c!alternative\v!a
     \letdummyparameter\c!define\v!yes
     \getdummyparameters[#2]%
     \ifcstok{\directdummyparameter\c!alternative}\v!a
       \expanded{\endgroup\pack_box_define_ornament_yes{#1}{\dummyparameter\c!define}}\collectedtext[#2][#3]%
     \else
       \expanded{\endgroup\pack_box_define_ornament_yes{#1}{\dummyparameter\c!define}}\layeredtext[#2][#3]%
     \fi
   \else
     \expanded{\endgroup\pack_box_define_ornament_nop{#1}{\dummyparameter\c!define}{#2}}[#3]%
   \fi}

\protected\def\pack_box_define_ornament_yes#1#2#3[#4][#5]%
  {\protected\frozen\instance\defcsname\??ornament#1\endcsname{#3[#4][#5]}%
   \ifcstok{#2}\v!yes
     \aliased\letcsname#1\expandafter\endcsname\csname\??ornament#1\endcsname
   \fi}

\protected\def\pack_box_define_ornament_nop#1#2#3[#4]%
  {\protected\frozen\instance\edefcsname\??ornament#1\endcsname{\noexpand\csname#3\endcsname[#4]}%
   \ifcstok{#2}\v!yes
     \aliased\letcsname#1\expandafter\endcsname\csname\??ornament#1\endcsname
   \fi}

% \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}

\installcommandhandler \??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

\appendtoks
    \ifcstok{\bleedingparameter\c!define}\v!yes
        \protected\frozen\instance\edefcsname\currentbleeding\endcsname{\pack_boxes_bleeding{\currentbleeding}}%
    \fi
\to \everydefinebleeding

\newdimension \bleedingwidth
\newdimension \bleedingheight

\permanent\def\bleedwidth {\the\hsize} % these are global !
\permanent\def\bleedheight{\the\vsize} % these are global !

\newconditional\c_pack_boxes_l % left
\newconditional\c_pack_boxes_r % right
\newconditional\c_pack_boxes_t % top
\newconditional\c_pack_boxes_b % bottom

\installcorenamespace{bleedinglocation}

\defcsname\??bleedinglocation  t\endcsname{\c_pack_boxes_t\conditionaltrue\scratchhoffset\zeropoint}
\defcsname\??bleedinglocation  b\endcsname{\c_pack_boxes_b\conditionaltrue\scratchhoffset\zeropoint}
\defcsname\??bleedinglocation  l\endcsname{\c_pack_boxes_l\conditionaltrue\scratchvoffset\zeropoint}
\defcsname\??bleedinglocation  r\endcsname{\c_pack_boxes_r\conditionaltrue\scratchvoffset\zeropoint}
\defcsname\??bleedinglocation bl\endcsname{\c_pack_boxes_l\conditionaltrue\c_pack_boxes_b\conditionaltrue}
\defcsname\??bleedinglocation lb\endcsname{\c_pack_boxes_l\conditionaltrue\c_pack_boxes_b\conditionaltrue}
\defcsname\??bleedinglocation br\endcsname{\c_pack_boxes_r\conditionaltrue\c_pack_boxes_b\conditionaltrue}
\defcsname\??bleedinglocation rb\endcsname{\c_pack_boxes_r\conditionaltrue\c_pack_boxes_b\conditionaltrue}
\defcsname\??bleedinglocation tl\endcsname{\c_pack_boxes_l\conditionaltrue\c_pack_boxes_t\conditionaltrue}
\defcsname\??bleedinglocation lt\endcsname{\c_pack_boxes_l\conditionaltrue\c_pack_boxes_t\conditionaltrue}
\defcsname\??bleedinglocation tr\endcsname{\c_pack_boxes_r\conditionaltrue\c_pack_boxes_t\conditionaltrue}
\defcsname\??bleedinglocation rt\endcsname{\c_pack_boxes_r\conditionaltrue\c_pack_boxes_t\conditionaltrue}

\mutable\lettonothing\currentbleedposition
\mutable\lettonothing\currentpageposition

% \permanent\tolerant\protected\def\bleed[#1]%
%   {\hbox\bgroup

\newuserunit \bleedingwidth  bw
\newuserunit \bleedingheight bh
\newuserunit \paperbleed     be % bleedingextra

\def\pack_boxes_bleeding_constrain
  {\beginlocalcontrol
   \constrained\bleedingwidth \bleedingwidth
   \constrained\bleedingheight\bleedingheight
   \endlocalcontrol}

\tolerant\protected\def\pack_boxes_bleeding_preset#1#*[#2]%
  {\global\advanceby\c_pack_boxes_bleeds\plusone
   %
   \retained\bleedingwidth \hsize
   \retained\bleedingheight\vsize
   \enforced\permanent\xdef\bleedwidth {\the\bleedingwidth }%
   \enforced\permanent\xdef\bleedheight{\the\bleedingheight}%
   %
   \edef\currentbleedposition{bleed:\the\c_pack_boxes_bleeds}%
   \edef\currentpageposition {page:0}% todo: per page
   %
   \cdef\currentbleeding{#1}%
   \setupcurrentbleeding[#2]%
   %
   \scratchwidth  {\bleedingparameter\c!width}%
   \scratchheight {\bleedingparameter\c!height}%
   \scratchoffset {\bleedingparameter\c!offset}%
   \scratchhoffset{\bleedingparameter\c!hoffset}% \default: \scratchoffset
   \scratchvoffset{\bleedingparameter\c!voffset}% \default: \scratchoffset
   %
   \c_pack_boxes_l\conditionalfalse
   \c_pack_boxes_r\conditionalfalse
   \c_pack_boxes_t\conditionalfalse
   \c_pack_boxes_b\conditionalfalse
   %
   \csname\??bleedinglocation\bleedingparameter\c!location\endcsname
   %
   \ifcstok{\bleedingparameter\c!stretch}\v!yes
     \donetrue
   \else
     \donefalse
   \fi
   %
   \retained\bleedingwidth{%
     \ifdone
       \ifconditional\c_pack_boxes_l
         \scratchwidth+\jobposx\currentbleedposition-\jobposx\currentpageposition
       \orelse\ifconditional\c_pack_boxes_r
         \paperwidth  -\jobposx\currentbleedposition+\jobposx\currentpageposition % not checked
       \else
         \scratchwidth
       \fi
     \else
       \scratchwidth
     \fi+\scratchhoffset
   }%
   \retained\bleedingheight{%
     \ifdone
       \ifconditional\c_pack_boxes_t
         \paperheight  -\jobposy\currentbleedposition+\jobposy\currentpageposition % not checked
       \orelse\ifconditional\c_pack_boxes_b
         \scratchheight+\jobposy\currentbleedposition-\jobposy\currentpageposition + \jobposh\currentbleedposition % not checked (\MPh added)
       \else
         \scratchheight
       \fi
     \else
       \scratchheight
     \fi+\scratchvoffset
   }%
   \enforced\permanent\xdef\bleedwidth {\the\bleedingwidth }%
   \enforced\permanent\xdef\bleedheight{\the\bleedingheight}}

\tolerant\protected\def\pack_boxes_bleeding#1#*[#2]%
  {\pack_boxes_bleeding_constrain
   \hbox\bgroup
   \pack_boxes_bleeding_preset{#1}[#2]%
   \dowithnextboxcontentcs\pack_boxes_bleed_settings\pack_boxes_bleed_finish\hbox}

\tolerant\protected\def\startbleeding[#1]#*[#2]%
  {\pack_boxes_bleeding_constrain
   \hpack\bgroup
   \pack_boxes_bleeding_preset{#1}[#2]%
   \setbox\nextbox\hbox\bgroup
   \pack_boxes_bleed_settings
   \ignorespaces}

\tolerant\protected\def\stopbleeding
  {\removeunwantedspaces
   \egroup
   \pack_boxes_bleed_finish}  % ends with egroup

\def\pack_boxes_bleed_settings
  {\hsize\bleedingwidth
   \vsize\bleedingheight}

\def\pack_boxes_bleed_finish
  {\ifcstok{\bleedingparameter\c!page}\v!yes
     \setbox\nextbox\topskippedbox{\box\nextbox}%
   \fi
% todo \boxoffset\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
       \boxyoffset\nextbox{-\ht\nextbox+\bleedheight}%
   \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]

\definebleeding
  [bleed]
  [\c!define=\v!yes] % \v!bleed

\permanent\protected\def\bleeding[#1]{\pack_boxes_bleeding{#1}}

% \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]#*[#S#2]#*[#S#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]#*[#S#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[#S#1]%
  {\bgroup
   \pack_boxes_offset_check[#1]%
   \dowithnextboxcs\pack_boxes_offsetfinish}

\permanent\tolerant\protected\def\offset[#S#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
     \ifcstok{\offsetboxparameter\c!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[#S#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{\localcontrolledrepeat\scratchnx{\copy\nextbox}}%
       \setbox\nextbox\vpack{\localcontrolledrepeat\scratchny{\copy\nextbox\endgraf}}%
     \or % x
       \setbox\nextbox\hpack{\localcontrolledrepeat\scratchnx{\copy\nextbox}}%
     \or % y
       \setbox\nextbox\vpack{\localcontrolledrepeat\scratchny{\copy\nextbox\endgraf}}%
     \fi
   \fi
   \ifdim\wd\nextbox>\scratchwidth
     \setbox\nextbox\hpack to \scratchwidth{\hss\box\nextbox\hss}%
     \setbox\nextbox\hpack{\expanded{\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{\expanded{\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
       {\expanded{\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
       {\expanded{\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]#*[#S#2]%
  {\begingroup
   \dostarttaggednodetail\t!ornament
   \dowithnextbox
     {\cdef\currentanchorbox{#1}%
      \setupboxanchor[#2]%
      \scratchcounterone\csname\??boxanchorbox#1\endcsname\relax
      \scratchxoffset{\boxanchorparameter\c!xoffset}%
      \scratchyoffset{\boxanchorparameter\c!yoffset}%
      \boxtarget\nextbox \namedanchorbox {#1}\relax
      \boxanchors\nextbox
        % target
        {%
          \ifcsname\??boxpreset\boxanchorparameter\c!target\endcsname
            \lastnamedcs
          \else
            \halfwaytotallistanchorcode
          \fi
        }%
        % source
        {%
          \ifcsname\??boxpreset\boxanchorparameter\c!source\endcsname
            \lastnamedcs
          \else
            \halfwaytotallistanchorcode
          \fi
        }%
      \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
      \dostoptagged
      \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\protected\def\doifnotanchorbox#1%
  {\ifcsname\??boxanchors\boxanchoringclass:#1\endcsname
     \expandafter\gobbleoneargument
   \orelse\ifcsname\??boxanchors#1\endcsname
     \expandafter\gobbleoneargument
   \else
     \expandafter\firstofoneargument
   \fi}

% \permanent\def\namedboxanchor#1%
%   {\expanded{\ifcsname\??boxanchors#1\endcsname\lastnamedcs\orelse\ifchknum#1\or#1\else\zerocount\fi}}

\permanent\def\namedboxanchor#1%
  {\expanded{%
     \ifcsname\??boxanchors\boxanchoringclass:#1\endcsname
       \lastnamedcs
     \orelse\ifcsname\??boxanchors#1\endcsname
       \lastnamedcs
     \orelse\ifchknum#1\or
       #1%
     \else
       \zerocount
     \fi
    }}

\permanent\def\namespacedboxanchor#1% used for positions
  {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]#*[#S#2]#*[#S#3]#*% assumes \defineboxanchor[#1]
  {\begingroup
   \dostarttaggednodetail\t!ornament
   \dowithnextbox
     {\ifhastok={#2}%
        \setupcurrentboxanchorcontent[#2]%
      \else
        \cdef\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}%
      \dostoptagged
      \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{#2}\relax}

% to be used as:
%
% \scratchcounter\registeredboxanchor
%
% \registeranchorbox
%   \scratchcounter
%   \plusone
%   \ruledhbox{...}
%
% \hbox source \scratchcounter

% \negatexlistsigncode
% \negateylistsigncode
% \negatelistsigncode

%D Per 2026 we have two more box interfaces, one for horizontal and one for vertical. We
%D can if needed add abit more checking (for dimensions) but then also will do that in
%D other places.
%D
%D \start
%D
%D \startbuffer
%D \setuphorizontalbox [strut=yes]
%D
%D \definehorizontalbox [max] [width=max]
%D
%D \definehorizontalbox [left]   [max] [right=\hss]
%D \definehorizontalbox [middle] [max] [left=\hss,right=\hss]
%D \definehorizontalbox [right]  [max] [left=\hss]
%D
%D \definehorizontalbox [rlap] [left]  [width=\zeropoint]
%D \definehorizontalbox [llap] [right] [width=\zeropoint]
%D \stopbuffer
%D
%D \typebuffer \getbuffer
%D
%D \startbuffer
%D \horizontalbox[left]  {left}
%D \horizontalbox[middle]{middle}
%D \horizontalbox[right] {right}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \horizontalbox[left][style=bold,color=red]{text}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \horizontalbox[middle][stretch=\emwidth]{text}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \starthorizontalbox[max]
%D \horizontalbox[rlap]  {left}%
%D \horizontalbox[middle]{middle}%
%D \horizontalbox[llap]  {right}%
%D \stophorizontalbox
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \startalignment[lefttoright]
%D \dontleavehmode\horizontalbox[left]                       {left}\par
%D \dontleavehmode\horizontalbox[left][direction=lefttoright]{left}\par
%D \dontleavehmode\horizontalbox[left][direction=righttoleft]{left}\par
%D \dontleavehmode\horizontalbox[left][direction=reverse]    {left}\par
%D \stopalignment
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \startalignment[righttoleft]
%D \dontleavehmode\horizontalbox[left]                       {left}\par
%D \dontleavehmode\horizontalbox[left][direction=lefttoright]{left}\par
%D \dontleavehmode\horizontalbox[left][direction=righttoleft]{left}\par
%D \dontleavehmode\horizontalbox[left][direction=reverse]    {left}\par
%D \stopalignment
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \startnarrower[middle]
%D \dontleavehmode\horizontalbox[left][width=local]{left}
%D \stopnarrower
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \dontleavehmode
%D \horizontalbox{one}
%D \horizontalbox[yoffset=1sh]{one}
%D \horizontalbox{one}
%D \horizontalbox[xoffset=\spaceamount]{one}
%D \horizontalbox{one}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[hbox] \getbuffer \stoplinecorrection
%D
%D \stop

\installcorenamespace                   {horizontalbox}
\installcommandhandler \??horizontalbox {horizontalbox} \??horizontalbox

\tolerant\permanent\protected\def\horizontalbox[#1]#*[#2]%
  {\hpack\bgroup
   \ifarguments
     \lettonothing\currenthorizontalbox
   \or
     \ifhastok={#1}%
       \lettonothing\currenthorizontalbox
       \setupcurrenthorizontalbox[#1]%
     \else
       \cdef\currenthorizontalbox{#1}%
     \fi
   \or
     \cdef\currenthorizontalbox{#1}%
     \setupcurrenthorizontalbox[#2]%
   \fi
   \horizontalbox_indeed}

\tolerant\permanent\protected\def\starthorizontalbox[#1]#*[#2]%
  {\hpack\bgroup
   \ifarguments
     \lettonothing\currenthorizontalbox
   \or
     \ifhastok={#1}%
       \lettonothing\currenthorizontalbox
       \setupcurrenthorizontalbox[#1]%
     \else
       \cdef\currenthorizontalbox{#1}%
     \fi
   \or
     \cdef\currenthorizontalbox{#1}%
     \setupcurrenthorizontalbox[#2]%
   \fi
   \horizontalbox_indeed\bgroup\ignorespaces}

\protected\def\stophorizontalbox
  {\removeunwantedspaces\egroup}

\def\horizontalbox_indeed
  {\forgetall
   \hbox
     % width parameter
     \ifcstok{\horizontalboxparameter\c!width}\v!max
       \s!to \hsize
     \orelse\iflastnamedcs\v!local
       \s!to \localhsize
     \orunless\ifempty\lastnamedcs
       \s!to {\lastnamedcs}%
     \fi
     % stretch parameter
     \ifempty{\horizontalboxparameter\c!stretch}\else
       \s!spread {\lastnamedcs}%
     \fi
   % \ifchkdimension\horizontalboxparameter\c!stretch\or
   %   \s!spread \lastchkdimension
   % \fi
     % direction parameter
     \ifcstok{\horizontalboxparameter\c!direction}\v!reverse
       \s!reverse
     \orelse\iflastnamedcs\v!lefttoright
       \s!direction \directionlefttoright
     \orelse\iflastnamedcs\v!righttoleft
       \s!direction \directionrighttoleft
     \fi
     % xoffset parameter
     \ifempty{\horizontalboxparameter\c!xoffset}\else
       \s!xoffset {\lastnamedcs}%
     \fi
   % \ifchkdimension\horizontalboxparameter\c!xoffset\or
   %   \s!xoffset \lastchkdimension
   % \fi
     % yoffset parameter
     \ifempty{\horizontalboxparameter\c!yoffset}\else
       \s!yoffset {\lastnamedcs}%
     \fi
   % \ifchkdimension\horizontalboxparameter\c!yoffset\or
   %   \s!yoffset \lastchkdimension
   % \fi
     \bgroup
       \usehorizontalboxstyleandcolor\c!style\c!color
     % \aftergrouped  {\egroup}%
       \aftergroup     \egroup
       \atendofgrouped{\horizontalboxparameter\c!right\relax}%
       \horizontalboxparameter\c!left\relax
       \ifcstok{\horizontalboxparameter\c!strut}\v!yes \strut \fi
       \let\next=}

\installcorenamespace                 {verticalbox}
\installcommandhandler \??verticalbox {verticalbox} \??verticalbox

\tolerant\permanent\protected\def\verticalbox[#1]#*[#2]%
  {\vpack\bgroup
   \ifarguments
     \lettonothing\currentverticalbox
   \or
     \ifhastok={#1}%
       \lettonothing\currentverticalbox
       \setupcurrentverticalbox[#1]%
     \else
       \cdef\currentverticalbox{#1}%
     \fi
   \or
     \cdef\currentverticalbox{#1}%
     \setupcurrentverticalbox[#2]%
   \fi
   \verticalbox_indeed}

\tolerant\permanent\protected\def\startverticalbox[#1]#*[#2]%
  {\vpack\bgroup
   \ifarguments
     \lettonothing\currentverticalbox
   \or
     \ifhastok={#1}%
       \lettonothing\currentverticalbox
       \setupcurrentverticalbox[#1]%
     \else
       \cdef\currentverticalbox{#1}%
     \fi
   \or
     \cdef\currentverticalbox{#1}%
     \setupcurrentverticalbox[#2]%
   \fi
   \verticalbox_indeed\bgroup\ignorespaces}

\protected\def\stopverticalbox
  {\removeunwantedspaces\egroup}

\def\verticalbox_indeed
  {\forgetall
   \ifcstok{\verticalboxparameter\c!alternative}\v!top\vtop\else\vbox\fi
     % height parameter
     \ifcstok{\verticalboxparameter\c!height}\v!max
       \s!to \vsize
     \orunless\ifempty\lastnamedcs
       \s!to {\lastnamedcs}%
     \fi
     % direction parameter
     \ifcstok{\verticalboxparameter\c!direction}\v!reverse
       \s!reverse
     \orelse\iflastnamedcs\v!lefttoright
       \s!direction \directionlefttoright
     \orelse\iflastnamedcs\v!righttoleft
       \s!direction \directionrighttoleft
     \fi
     % xoffset parameter
     \ifempty{\verticalboxparameter\c!xoffset}\else
       \s!xoffset {\lastnamedcs}%
     \fi
   % \ifchkdimension\verticalboxparameter\c!xoffset\or
   %   \s!xoffset \lastchkdimension
   % \fi
     % yoffset parameter
     \ifempty{\verticalboxparameter\c!yoffset}\else
       \s!yoffset {\lastnamedcs}%
     \fi
   % \ifchkdimension\verticalboxparameter\c!yoffset\or
   %   \s!yoffset \lastchkdimension
   % \fi
     \bgroup
       \usealignparameter    \verticalboxparameter
       \useindentingparameter\verticalboxparameter
       \useverticalboxstyleandcolor\c!style\c!color
     % \aftergrouped  {\egroup}%
       \aftergroup     \egroup
       \atendofgrouped{\ifcstok{\verticalboxparameter\c!strut}\v!yes \endstrut \fi}%
       \atendofgrouped{\verticalboxparameter\c!bottom\relax}%
       % width parameter
       \ifcstok{\verticalboxparameter\c!width}\v!local
         \hsize\localhsize\relax
       \orunless\ifempty\lastnamedcs
         \hsize{\lastnamedcs}\relax
       \fi
       \verticalboxparameter\c!top\relax
       \ifcstok{\verticalboxparameter\c!strut}\v!yes \begstrut \fi
       \let\next=}

%D \start
%D
%D \startbuffer
%D \setupverticalbox [strut=yes]
%D \stopbuffer
%D
%D \typebuffer \getbuffer
%D
%D \startbuffer
%D \verticalbox[width=.75tw]{\samplefile{lorem}}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \dontleavehmode
%D \verticalbox[width=2cm]                      {line 1\\line 2\\line 3}
%D \verticalbox[width=2cm,alternative=top]      {line 1\\line 2\\line 3}
%D \verticalbox[width=2cm,alternative=bottom]   {line 1\\line 2\\line 3}
%D \verticalbox[width=2cm,yoffset={-1sh-1sd}]   {line 1\\line 2\\line 3}
%D \verticalbox[width=2cm,xoffset=-\spaceamount]{line 1\\line 2\\line 3}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \startnarrower[middle]
%D \dontleavehmode\verticalbox[width=local]{\samplefile{lorem}}
%D \stopnarrower
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \verticalbox[align={middle,broad,nothyphenated}]{\samplefile{lorem}}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \verticalbox[indenting={yes,big}]{\samplefile{lorem}}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \verticalbox[style=italic,color=green]{\samplefile{lorem}}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \verticalbox[height=max,top=\vss,bottom=\vss,align=middle]{text}
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \startalignment[lefttoright]
%D \dontleavehmode\verticalbox                       {text}\par
%D \dontleavehmode\verticalbox[direction=lefttoright]{text}\par
%D \dontleavehmode\verticalbox[direction=righttoleft]{text}\par
%D \dontleavehmode\verticalbox[direction=reverse]    {text}\par
%D \stopalignment
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \startbuffer
%D \startalignment[righttoleft]
%D \dontleavehmode\verticalbox                       {text}\par
%D \dontleavehmode\verticalbox[direction=lefttoright]{text}\par
%D \dontleavehmode\verticalbox[direction=righttoleft]{text}\par
%D \dontleavehmode\verticalbox[direction=reverse]    {text}\par
%D \stopalignment
%D \stopbuffer
%D
%D \typebuffer \startlinecorrection \showmakeup[vbox,vtop] \getbuffer \stoplinecorrection
%D
%D \stop

\protect \endinput
