%D \module
%D   [       file=strc-flt,
%D        version=2008.10.20,
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Float Numbering,
%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 Structure Macros / Float Numbering}

\registerctxluafile{strc-flt}{1.001}

\unprotect

% todo: delay caption creation and make setups for each method instead
%       so that we can have a list of methods and redo them as we can
%       keep the list or even better: recreate it
%
% todo: strc_floats_analyze_variables_two could trigger a setup
%       and we could have nofmethods of them
%
% todo: move variables from page-flt to strc-flt
%
% todo: p_name etc
%
% todo: less globals!
%
% todo: do all options in lua

%D This module is being converted into a mkvi one.
%D
%D - rename macros
%D - get rid of dead code
%D - less gobal mess
%D - more mkiv-ish

\installcorenamespace{float}
\installcorenamespace{floatbuilder}
\installcorenamespace{floatcaption}

\installframedcommandhandler \??float        {float}        \??float
\installframedcommandhandler \??floatcaption {floatcaption} \??floatcaption

\let\setupfloats  \setupfloat
\let\setupcaption \setupfloatcaption
\let\setupcaptions\setupfloatcaption

\unexpanded\def\dohandlenextfloatindent
  {\useindentnextparameter\floatparameter
   \dorechecknextindentation}

\setupcaptions
  [\c!location=\v!bottom,
   \c!grid=,
   \c!before=, % not used (yet)
   \c!inbetween={\blank[\v!medium]},
   \c!after=, % not used (yet)
   \c!spacebefore=,
   \c!spaceinbetween=, % replaces fuzzy inbetween dual usage
   \c!spaceafter=,
   \c!width=\v!fit,
   \c!minwidth=\v!fit, % id est: the width of the floatbox in some cases
   \c!headstyle=\v!bold,
   \c!headcolor=,
   \c!leftmargin=\zeropoint,
   \c!rightmargin=\zeropoint,
   \c!outermargin=\zeropoint,
   \c!innermargin=\zeropoint,
   \c!setups=,
   \c!style=\v!normal,
   \c!color=,
   \c!textstyle=,
   \c!textcolor=,
   \c!align=,
   \c!number=\v!yes,
 % \c!expansion=\v!no
 % \c!prefix=\v!no,
 % \c!prefixconnector=.,
 % \c!way=\v!by\v!chapter,
 % \c!prefixsegments=2:2,
 % \c!way=\@@nrway,
 % \c!blockway=\@@nrblockway,
 % \c!sectionnumber=\@@nrsectionnumber,
 % \c!separator=\@@koseparator,
 % \c!starter=\@@kostarter,
 % \c!stopper=\@@kostopper,
   \c!suffixseparator=, % currently rather hard coded
   \c!suffix=\floatcaptionsuffix,
   \c!distance=1em,
   \c!conversion=\v!numbers,
   \c!command=]

% we can comment some of these

\setupfloats
  [\c!location=\v!middle,
   \c!width=8\lineheight,
   \c!height=6\lineheight,
   \c!offset=\v!overlay,
   \c!frame=\v!off,
   \c!strut=\v!no,
   \c!radius=.5\bodyfontsize,
   \c!corner=\v!rectangular,
  %\c!background=,
  %\c!backgroundcolor=,
   \c!backgroundoffset=\!!zeropoint,
  %\c!topframe=,
  %\c!bottomframe=,
  %\c!leftframe=,
  %\c!rightframe=,
   \c!frameoffset=\!!zeropoint,
  %\c!before=,
  %\c!after=,
   \c!spacebefore=\v!big,
   \c!spaceafter=\v!big,
   \c!sidespacebefore=\rootfloatparameter\c!spacebefore,
   \c!sidespaceafter=\rootfloatparameter\c!spaceafter,
   \c!sidealign=\v!normal,
   \c!textmethod=\ifgridsnapping2\else0\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) % THIS WILL CHANGE
   \c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) % THIS WILL CHANGE
   \c!indentnext=\v!no,
   \c!margin=1\emwidth,
   \c!method=1,
   \c!cache=\v!yes, % when no, then intermediate flush
   \c!leftmargin=\zeropoint,  % displacement in 'normal floats'
   \c!rightmargin=\zeropoint, % idem
   \c!innermargin=\zeropoint, % idem
   \c!outermargin=\zeropoint, % idem
   \c!leftmargindistance=\zeropoint,
   \c!rightmargindistance=\floatparameter\c!leftmargindistance,
   \c!ntop=2,
   \c!nbottom=0,
   \c!nlines=4, % used?
  %\c!local=,
  %\c!bottombefore=, % e.g. \vfill
  %\c!bottomafter=,
  %\c!default=, % default location
   \c!numbering=\v!yes]

%D Individial settings:

\installcounterassociation{floatcaption}

\appendtoks
    \let\currentfloat\currentfloatcaption % ?
    \synchronizefloatcaptioncounters
\to \everysetupfloatcaption

\appendtoks
    \let\currentfloat\currentfloatcaption % ?
    \synchronizefloatcaptioncounters
\to \everydefinefloatcaption

%D Definitions:

\let\strc_floats_define_saved\definefloat

\unexpanded\def\definefloat
  {\dotripleempty\strc_floats_define}

\def\strc_floats_define[#1][#2][#3]% #1=naam #2=meervoud #3=parent
  {\ifthirdargument
     \strc_floats_define_cloned[#1][#2][#3]%
   \else\ifsecondargument
     \strc_floats_define_normal[#1][#2]%
   \else
     \strc_floats_define_normal[#1][#1]%
   \fi\fi}

\def\strc_floats_define_normal[#1][#2]%
  {\registerfloatcaptioncounter{#1}%
   \definefloatcaption[#1]%
   \definecounter[#1]%
   \definelist[#1]%
   \presetlabeltext[#1=\Word{#1}~]%
   \presetheadtext[#2=\Word{#2}]%
   \strc_floats_define_saved[#1]%
   \strc_floats_define_commands{#1}{#2}}

\def\strc_floats_define_cloned[#1][#2][#3]%
  {\definefloatcaption[#1][#3]%
   \definecounter[#1][#3]%
   \definelist[#1][#3]%
   \presetlabeltext[#1=\Word{#3}~]%
   \presetheadtext[#2=\Word{#2}]%
   \strc_floats_define_saved[#1][#3]%
   \strc_floats_define_commands{#1}{#2}}

\def\strc_floats_define_commands#1#2%
  {\setuvalue         {\e!place\e!listof#2}{\dodoubleempty\strc_lists_place[#1]}% call will change
   \setuvalue      {\e!complete\e!listof#2}{\dotripleempty\strc_lists_complete_indeed[#1][#2]}% call will change
   \setuevalue                 {\e!place#1}{\strc_floats_place{#1}}%
   \setuevalue         {\e!start\e!place#1}{\strc_floats_start_place{#1}}%
   \setuevalue          {\e!stop\e!place#1}{\strc_floats_stop_place}%
   \setuevalue          {\e!start#1\e!text}{\strc_floats_start_text{#1}}%
   \setuevalue           {\e!stop#1\e!text}{\strc_floats_stop_text}%
   % these will become obsolete:
   \setuevalue               {\e!reserve#1}{\strc_floats_reserve{#1}}%
   \setuevalue{\e!start\e!reserve#1\e!text}{\strc_floats_start_reserve_text{#1}}%
   \setuevalue {\e!stop\e!reserve#1\e!text}{\strc_floats_stop_reserve_text}}

%D Fallback float body:

\unexpanded\def\strc_floats_place_empty_box % \inheritedfloatframed
  {\framed
     [\c!frame=\v!on,
      \c!width=\rootfloatparameter\c!width,
      \c!height=\rootfloatparameter\c!height,
      \c!location=\v!normal,
      \c!offset=\rootfloatparameter\c!offset]%
     {\getmessage\m!floatblocks{12}\empty}}

%D Data. We can generalize this to lists.

\newif\ifnofloatcaption
\newif\ifnofloatnumber
\newif\ifemptyfloatcaption

\installstructurelistprocessor\s!float{\usestructurelistprocessor{number+title}}

\unexpanded\def\thecurrentfloatnumbersuffix
  {\doifsomething{\floatcaptionparameter\c!suffix}
     {\floatcaptionparameter\c!suffixseparator
      \floatcaptionparameter\c!suffix
      \floatcaptionparameter\c!suffixstopper}}

\unexpanded\def\thecurrentfloatnumber
  {\ifnofloatcaption \else \ifnofloatnumber \else
     \ifx\currentfloatnumber\relax\else
       \namedtaggedlabeltexts
         \t!floatlabel \currentfloat
         \t!floatnumber\currentfloat
         {\ctxcommand{savedlistprefixednumber("\currentfloat",\currentfloatnumber)}%
          \thecurrentfloatnumbersuffix}%
     \fi
   \fi \fi}

\unexpanded\def\thecurrentfloatcaption
  {\ifnofloatcaption \else
     \ifx\currentfloatnumber\relax\else
       \dostarttagged\t!floattext\empty
       \ctxcommand{savedlisttitle("\currentfloat",\currentfloatnumber)}%
       \dostoptagged
     \fi
   \fi}

%D Captions.

\let\floatcaptionsuffix\empty % an optional suffix
\let\floatcaptionnumber\empty % a logical counter

% the split is needed when for instance the float goes into
% a multi page field and the list of figs becomes larger than
% one page: cycle between 'only flush when object ref ok'
% and 'one/many page fig list'; see "uguide finometer"
%
% potential sync bug with sectionblocks, see uguide.tex

% begin of todo

\unexpanded\def\placefloatcaption{\dodoubleempty\strc_floats_place_caption}
\unexpanded\def\setfloatcaption  {\dodoubleempty\strc_floats_set_caption}

\def\strc_floats_place_caption[#tag][#reference]#caption{[not supported]}
\def\strc_floats_set_caption  [#tag][#reference]#caption{[not supported]}

\unexpanded\def\placefloatcaptiontext     [#tag]{[not suported yet]}
\unexpanded\def\placefloatcaptionnumber   [#tag]{[not suported yet]}
\unexpanded\def\placefloatcaptionreference[#tag]{[not suported yet]}

\let\placefloatlabel         \placefloatcaption
\let\placefloatlabeltext     \placefloatcaptiontext
\let\placefloatlabelreference\placefloatcaptionreference

% end of todo

\newbox  \b_strc_floats_caption
\newbox  \b_strc_floats_content
\newdimen\d_strc_floats_caption_height
\newdimen\d_strc_floats_caption_depth

\def\strc_floats_make_complete_caption
  {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}%
   \synchronizedisplaydirection % temp hack, till we have a proper model
   \noindent
   \gdef\lastcaptiontag{\strut\thecurrentfloatnumber}% was xdef ... needs checking
   \begingroup
     \usefloatcaptionstyleandcolor\c!style\c!color
     \ifnofloatnumber
     \else
       \hbox{\usefloatcaptionstyleandcolor\c!headstyle\c!headcolor\strut\thecurrentfloatnumber}%
       \ifnofloatcaption \else \ifemptyfloatcaption \else
         \doifelsenothing{\floatcaptionparameter\c!spaceinbetween}
           {\scratchskip\floatcaptionparameter\c!distance\relax
            \dotfskip\scratchskip\emergencystretch.5\scratchskip}
           {\blank[\floatcaptionparameter\c!spaceinbetween]}%
       \fi \fi
     \fi
     \ifnofloatcaption
       \global\d_strc_floats_caption_height\zeropoint
       \global\d_strc_floats_caption_depth \zeropoint
     \else
       \usefloatcaptionstyleandcolor\c!textstyle\c!textcolor
       \global\d_strc_floats_caption_height\strutheight
       \global\d_strc_floats_caption_depth \strutdepth
       \begstrut\thecurrentfloatcaption\endstrut\endgraf
     \fi
   \endgroup
   \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}}

% \newif\iftracecaptions
%
% \def\settracedcaptionbox
%   {\iftracecaptions\setbox\b_strc_floats_caption\ruledhbox{\box\b_strc_floats_caption}\fi}

% \definefloat  [figure-1] [figure]
% \definefloat  [figure-2] [figure]
% \setupfloat   [figure-1] [location=left,leftmargin=10mm]
% \setupfloat   [figure-2] [location=left,leftmargin=-5mm]
% \setupcaption [figure-1] [align=flushleft]
% \setupcaption [figure-2] [align=flushleft,leftmargin=15mm]
%
% \startsetups somefigure
%     \ifdim\wd\nextbox>\textwidth
%         \placefloat[figure-2][][]{}{\box\nextbox}
%     \else
%         \placefloat[figure-1][][]{}{\box\nextbox}
%     \fi
% \stopsetups
%
% \unexpanded\def\setupswithbox[#1]{\dowithnextbox{\setups[#1]}\vbox}
%
% test \setupswithbox[somefigure]{\framed[width=3cm]                         {}} test
% test \setupswithbox[somefigure]{\framed[width=\dimexpr\textwidth+3cm\relax]{}} test

% temporary removed ... was not applied systematically
%
% \def\dosetcaptionthings
%   {\usesetupsparameter\floatcaptionparameter}

\def\strc_floats_check_caption_content
  {\ifnofloatcaption
   \else
     \setbox\b_strc_floats_caption\hbox
       {\settrialtypesetting
        \notesenabledfalse
        \strc_floats_make_complete_caption}%
     % new, \placefigure{\xmlfirst{#1}{somecaption}}{} passes earlier empty check
     % so here we misuse the scratch box; actually this means that the previous
     % test can go away (some day, when i redo this module)
     \ifdim\wd\b_strc_floats_caption=\zeropoint
       \global\emptyfloatcaptiontrue
       \ifnofloatnumber
         \global\nofloatcaptiontrue
       \fi
     \else
       \global\emptyfloatcaptionfalse
       \setbox\b_strc_floats_caption\hbox{\hskip\leftskip\box\b_strc_floats_caption}%
     \fi
   \fi}

% The tricky part of getting float related two pass data is
% that we should fetch is early but can only save it with
% the composed float box; this determines the order: get it
% before saving it.

% We had this:
%
% \definetwopasslist{\s!float\s!data} \newcounter\noffloatdata
%
% \let\strc_float_realpage\realpageno % used for odd/even determination, can be combined with nodelocation
%
% \def\strc_float_save_data % \expanded ... will change in mkiv
%   {\doglobal\increment\noffloatdata
%    \lazysavetaggedtwopassdata{\s!float\s!data}{\noffloatdata}{\noffloatpages}{\noexpand\realfolio}}% later {}{}{}{} and \getfirst...
%
% \def\strc_float_load_data % precedes save !
%   {\doglobal\increment\noffloatpages
%    \findtwopassdata{\s!float\s!data}{\noffloatpages}%
%    \ifconditional\twopassdatafound
%      \globallet\strc_float_realpage\twopassdata
%    \else
%      \globallet\strc_float_realpage\realpageno % \realfolio
%    \fi}

%D We can do this ...
%D
%D \starttyping
%D \newcount\c_strc_floats_n
%D
%D \definedataset[\s!float][\c!delay=\v!yes]
%D
%D \let\strc_float_realpage\realpageno
%D
%D \def\strc_float_save_data
%D   {\setdataset[\s!float][\number\c_strc_floats_n][]}
%D
%D \def\strc_float_load_data % precedes save !
%D   {\global\advance\c_strc_floats_n\plusone
%D    \xdef\strc_float_realpage{\datasetvariable\s!float{\number\c_strc_floats_n}\s!page}%
%D    \ifx\strc_float_realpage\empty
%D      \globallet\strc_float_realpage\realpageno % \realfolio
%D    \fi}
%D \stoptyping
%D
%D ... but this is more efficient:

\definepagestate[\s!float][\c!delay=\v!yes]

\newcount\c_strc_floats_n

\let\strc_float_realpage\realpageno

\def\strc_float_save_data
  {\setpagestate[\s!float][\number\c_strc_floats_n]}

\def\strc_float_load_data % precedes save !
  {\global\advance\c_strc_floats_n\plusone
   \xdef\strc_float_realpage{\pagestaterealpage\s!float{\number\c_strc_floats_n}}%
   \ifx\strc_float_realpage\empty
     \globallet\strc_float_realpage\realpageno % \realfolio
   \fi}

%D test case:
%D
%D \starttyping
%D \setupfloat[figure][criterium=\marginwidth,fallback=bottom]
%D \dorecurse{3}{
%D     \chapter{test}
%D     \placefigure[bottom]{1}{\framed{bottom}}
%D     test
%D     \placetable[bottom]{1}{\framed{table}}
%D     test
%D     \placetable{2}{\framed{table}}
%D     test
%D     \placefigure[left]{2}{\framed{left but way too wide}}
%D     \input tufte
%D     \placefigure[left]{3}{\framed{left but ok}}
%D     \input tufte }
%D \stoptyping

% A complication is that we may have to handle a pagebreak
% first, which in turn may issue a (postponed) float.
% Therefore we may not trust on variable assignments before
% we're really dealing with the float. Some day I'll root out
% the global settings.

\let\lastplacedfloat\empty

\def\strc_floats_set_current_tag#tag%
  {\edef\currentfloat{#tag}%
   \ifx\currentfloat\empty
     \let\currentfloat\v!figure % a bit of a hack
   \fi
   \global\let\lastplacedfloat\currentfloat
   \let\m_strc_floats_saved_userdata\empty
   \let\currentfloatcaption\currentfloat}

\def\strc_floats_reset_variables
  {\global\emptyfloatcaptionfalse
   \global\nofloatcaptionfalse
   \global\nofloatnumberfalse}

% place

\def\strc_floats_analyze_location
  {% moved here, will do more
   \let\floatlabel \empty
   \let\floatcolumn\empty
   \let\floatrow   \empty
   \setfloatmethodvariables\floatlocation}

\unexpanded\def\strc_floats_place#tag%
  {\flushnotes
   \page_otr_command_flush_side_floats % here !
   \strc_floats_begin_group
   \strc_floats_set_current_tag{#tag}%
   \dodoubleempty\strc_floats_place_indeed}

\def\strc_floats_place_indeed[#location][#reference]#caption%
  {\strc_floats_reset_variables
   \edef\floatlocation{#location}%
   \ifx\floatlocation\empty
      \edef\floatlocation{\floatparameter\c!default}% beware of a clash between alignment locations
   \fi
   \strc_floats_analyze_location
   \setupcurrentfloatcaption[\c!reference={#reference},\c!title={#caption},\c!marking=,\c!list=,\c!bookmark=]%
   \doifinsetelse\v!split\floatlocation\strc_floats_place_next_box_split\strc_floats_place_next_box_normal}

\unexpanded\def\placefloat
  {\flushnotes
   \page_otr_command_flush_side_floats % here !
   \strc_floats_begin_group
   \dotripleempty\strc_floats_place_float}

\def\strc_floats_place_float[#tag]%
  {\strc_floats_set_current_tag{#tag}%
   \strc_floats_place_indeed}

% start-stop

% \startplacefigure[title=oeps][subtitle=whatever]
%     \framed[width=10cm,height=5cm]{\floatuserdataparameter{subtitle}}
% \stopplacefigure

\installcorenamespace{floatuserdata}

\installsetuponlycommandhandler \??floatuserdata {floatuserdata}

\let\m_strc_floats_saved_userdata\empty % todo: reset this in non start|stop cases

\unexpanded\def\strc_floats_start_place#tag%
  {\flushnotes
   \page_otr_command_flush_side_floats % here !
   \strc_floats_begin_group
   \strc_floats_set_current_tag{#tag}%
   \dodoubleempty\strc_floats_start_place_indeed}

\def\strc_floats_start_place_indeed[#settings][#userdata]%
  {\strc_floats_reset_variables
   \edef\savedfloatlocation{\floatcaptionparameter\c!location}%
   \setupcurrentfloatcaption[\c!location=,\c!reference=,\c!title=,\c!marking=,\c!list=,\c!bookmark=,#settings]%
   \def\m_strc_floats_saved_userdata{#2}%
   \edef\floatlocation{\floatcaptionparameter\c!location}%
   \setupcurrentfloatcaption[\c!location=\savedfloatlocation]%
   \ifx\floatlocation\empty
      \edef\floatlocation{\floatparameter\c!default}%
   \fi
   \ifsecondargument
     \setupcurrentfloatuserdata[#userdata]%
   \fi
   \strc_floats_analyze_location
   \doifinsetelse\v!split\floatlocation\strc_floats_place_next_box_split\strc_floats_place_next_box_normal
   \bgroup
   \ignorespaces}

\unexpanded\def\strc_floats_stop_place
  {\removeunwantedspaces
   \egroup}

\unexpanded\def\startplacefloat
  {\flushnotes
   \page_otr_command_flush_side_floats % here !
   \strc_floats_begin_group
   \dodoubleempty\strc_floats_start_place_float}

\def\strc_floats_start_place_float[#tag]%
  {\strc_floats_set_current_tag{#tag}%
   \strc_floats_start_place_indeed}

\let\stopplacefloat\strc_floats_stop_place

% reserve

\unexpanded\def\strc_floats_reserve#tag%
  {\flushnotes
   \page_otr_command_flush_side_floats % here !
   \strc_floats_begin_group
   \strc_floats_set_current_tag{#tag}%
   \dotripleempty\strc_floats_reserve_indeed}

\def\strc_floats_reserve_indeed[#settings][#location][#reference]#caption% maybe check for #settings
  {\strc_floats_place_indeed[#location][#reference]{#caption}{\strc_floats_reserve_box{#settings}}}

\def\strc_floats_reserve_box#settings%
  {\begingroup
   \setupcurrentfloat[\c!frame=\v!on,#settings]%
   \inheritedfloatframed{}%
   \endgroup}

% text

\unexpanded\def\strc_floats_start_text#tag%
  {\flushnotes      % Here indeed?
   \page_otr_command_flush_side_floats % Here indeed?
   \strc_floats_begin_text_group
   \strc_floats_set_current_tag{#tag}%
   \dodoubleempty\strc_floats_start_text_indeed}

\def\strc_floats_start_text_indeed[#location][#reference]%
  {\strc_floats_place_indeed[\v!text,#location,\v!left][#reference]}

\unexpanded\def\strc_floats_stop_text
  {\strc_floats_stop_text_indeed}

% reserved text

\unexpanded\def\strc_floats_start_reserve_text#tag%
  {\flushnotes
   \page_otr_command_flush_side_floats
   \strc_floats_begin_text_group
   \strc_floats_set_current_tag{#tag}%
   \dotripleempty\strc_floats_start_reserve_text_indeed}

\def\strc_floats_start_reserve_text_indeed[#settings][#location][#reference]#caption%
  {\strc_floats_place_indeed[\v!text,#location,\v!left][#reference]{#caption}{\strc_floats_reserve_box{#settings}}}

\unexpanded\def\strc_floats_stop_reserve_text
  {\strc_floats_stop_text_indeed}

% special hack

\def\strc_floats_begin_group     {\begingroup}
\def\strc_floats_end_group       {\carryoverpar\endgroup}
\def\strc_floats_end_split_group {\endgroup}
\def\strc_floats_begin_text_group{\begingroup\let\strc_floats_end_group\relax}
\def\strc_floats_end_text_group  {\endgroup}

% implementation

%setnewconstant\c_page_one_float_method  \zerocount % 0=raw 1=safe (.99) 2=tight (-1pt) / belongs in page-one
\setnewconstant\c_strc_floats_rotation   \zerocount % 0 90 180 270
\newconditional\c_strc_floats_par_float

\ifdefined\page_margin_strc_floats_before    \else \let\page_margin_strc_floats_before   \relax \fi
\ifdefined\page_margin_strc_floats_set_hsize \else \let\page_margin_strc_floats_set_hsize\relax \fi

\def\flushfloatslist
  {\v!left,\v!right,\v!inner,\v!outer,%
   \v!backspace,\v!cutspace,%
   \v!inleft,\v!inright,\v!inmargin,%
   \v!leftmargin,\v!rightmargin,\v!leftedge,\v!rightedge,%
   \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,%
   \v!text,\v!opposite}% \v!page

\unexpanded\def\strc_floats_place_next_box_split
  {\let\splitfloatfinalizer\strc_floats_end_split_group
   \let\strc_floats_end_group\relax
   \splitfloat{\strc_floats_place_next_box_normal}}

\unexpanded\def\strc_floats_place_next_box_normal
  {\ifconditional\c_page_floats_some_waiting
     % this was \checkwaitingfloats spread all over
     \doifinsetelse\v!always\floatlocation
       {\showmessage\m!floatblocks5\empty}
       {\doifcommonelse\floatlocation\flushfloatslist\page_otr_command_flush_floats\donothing}%
     % but which should be done before using box \floatbox
   \fi
   \page_margin_strc_floats_before % todo: each float handler gets a before
   \global\insidefloattrue
   \dostarttagged\t!float\currentfloat
   \page_margin_strc_floats_set_hsize % todo: each float handler gets a set_hsize
   \the\everyinsidefloat
   \strc_floats_analyze_variables_one
   \dostarttagged\t!floatcontent\empty
   \dowithnextboxcontent
     {\strc_floats_set_local_hsize
      \floatparameter\c!inner
      \postponenotes} % new
     {\dostoptagged
      \strc_floats_finish_placement}
     \vbox}

\def\strc_floats_finish_placement
  {\doifsomething{\floatparameter\c!criterium}
     {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax
        \edef\forcedfloatmethod{\floatparameter\c!fallback}%
        \ifx\forcedfloatmethod\empty\let\forcedfloatmethod\v!here\fi
      \fi}%
   \strc_floats_check_extra_actions
   \strc_floats_analyze_variables_two
   \strc_floats_place_packaged_boxes
   \dostoptagged % tricky .... needs checking
   % we need to carry over the par because of side floats
   \global\d_page_sides_downshift \zeropoint
   \global\d_page_sides_extrashift\zeropoint
   \ifconditional\c_strc_floats_par_float
     \doifinset\v!reset\floatlocation\page_sides_forget_floats
     \doinhibitblank
   \fi
   \strc_floats_end_group}

% nicer is a bunch of states and one loop that sets those states

\def\strc_floats_analyze_variables_two
  {\ifinsidecolumns
     \global\setfalse\c_strc_floats_par_float
   \else
     \doifcommonelse\floatlocation\flushfloatslist
       {\global\settrue \c_strc_floats_par_float}
       {\global\setfalse\c_strc_floats_par_float}%
   \fi
   \global\d_page_sides_shift      \zeropoint
   \global\d_page_sides_maximum    \zeropoint
   \global\c_page_sides_method     \floatparameter\c!sidemethod
   \global\c_page_one_float_method \floatparameter\c!textmethod
   \global\c_page_sides_align      \zerocount
   \global\c_strc_floats_rotation  \zerocount
   \strc_floats_calculate_skips
   \ifconditional\c_strc_floats_par_float
     \processaction
       [\floatparameter\c!sidealign]
       [\v!height=>\global\c_page_sides_align\plusone  ,%
          \v!line=>\global\c_page_sides_align\plustwo  ,% (***)
         \v!depth=>\global\c_page_sides_align\plusthree,%
          \v!grid=>\global\c_page_sides_align\plusfour ,%
      \v!halfline=>\global\c_page_sides_align\plusfive ]%
     \ifcase\c_page_sides_align\relax % todo: optie v!lokaal => \else
       \doifinset\v!height  \floatlocation{\global\c_page_sides_align\plusone  }%
       \doifinset\v!line    \floatlocation{\global\c_page_sides_align\plustwo  }%
       \doifinset\v!depth   \floatlocation{\global\c_page_sides_align\plusthree}%
       \doifinset\v!grid    \floatlocation{\global\c_page_sides_align\plusfour }%
       \doifinset\v!halfline\floatlocation{\global\c_page_sides_align\plusfive }% meant for 'none'
     \fi
     \doifinset\v!high\floatlocation{\global\d_page_sides_topskip   \zeropoint}%
     \doifinset\v!low \floatlocation{\global\d_page_sides_bottomskip\zeropoint}%
     \doifinset\v!fit \floatlocation
       {\global\d_page_sides_topskip   \zeropoint
        \global\d_page_sides_bottomskip\zeropoint
        \global\d_strc_floats_margin   \zeropoint}%
   \else
     \processallactionsinset
       [\floatlocation]
       [ 90=>\global\c_strc_floats_rotation\commalistelement\relax,%
        180=>\global\c_strc_floats_rotation\commalistelement\relax,%
        270=>\global\c_strc_floats_rotation\commalistelement\relax]%
   \fi
   \doifinsetelse\v!nonumber\floatlocation
     {\global\nofloatnumbertrue}
     {\doifelse{\floatcaptionparameter\c!number}\v!yes
        {\global\nofloatnumberfalse}
        {\global\nofloatnumbertrue}}%
   \doifinsetelse\v!none\floatlocation
     {\global\nofloatcaptiontrue}
     {\global\nofloatcaptionfalse}%
   \doif{\floatcaptionparameter\c!number}\v!none % new
     {\global\nofloatcaptiontrue}%
   \ifemptyfloatcaption \ifnofloatnumber
     \global\nofloatcaptiontrue
   \fi \fi}

% documenteren in details

\def\strc_floats_analyze_variables_one
  {\doifelse{\floatparameter\c!local}\v!yes\settrue\setfalse\c_page_floats_center_box_global % fout keyword
   \ifconditional\c_page_floats_center_box_global
     \settrue\c_page_floats_center_box_local
   \else
     \doifinsetelse\v!local\floatlocation\settrue\setfalse\c_page_floats_center_box_local
   \fi
   \doifnotcommon{\v!always,\v!here,\v!force}\floatlocation % ! ! ! ! ! !
     {\setfalse\c_page_floats_center_box_global
      \setfalse\c_page_floats_center_box_local}}

\let\naturalfloatheight\!!zeropoint
\let\naturalfloatwidth \!!zeropoint
\let\naturalfloatdepth \!!zeropoint

\def\strc_floats_set_natural_dimensions#box%
  {\xdef\naturalfloatheight{\the\ht#box}%
   \xdef\naturalfloatwidth {\the\wd#box}%
   \xdef\naturalfloatdepth {\the\dp#box}}

\def\doifelsemainfloatbody
  {\ifinsidesplitfloat
     \ifconditional\splitfloatfirstdone
       \doubleexpandafter\secondoftwoarguments
     \else
       \doubleexpandafter\firstoftwoarguments
     \fi
   \else
     \expandafter\firstoftwoarguments
   \fi}

% todo: optional user pars

\let\currentfloatattribute\empty % to be checked

\def\floatcaptionattribute
  {\iflocation
    %\ifnofloatnumber
    %\else
       \ifnofloatcaption
       \else
         \ifinsidesplitfloat
            \ifconditional\splitfloatfirstdone
            \else
              attr \destinationattribute \currentfloatattribute
            \fi
         \else
           attr \destinationattribute \currentfloatattribute
         \fi
       \fi
    %\fi
   \fi}

\newconditional\usesamefloatnumber

% \startplacefigure[location=here,reference=first, title=first, group=alpha,groupsuffix=.a]
%     \externalfigure[dummy][height=2cm]
% \stopplacefigure
% \startplacefigure[location=here,reference=second,title=second,group=alpha,groupsuffix=.b]
%     \externalfigure[dummy][height=2cm]
% \stopplacefigure
%
% uses:

\def\strc_floats_group_index
  {\numexpr\ctxcommand{listgroupindex("\currentfloat","\currentfloatgroup")}\relax}

\def\strc_floats_place_packaged_boxes
  {\expandafter\strc_floats_place_packaged_boxes_indeed\expandafter{\m_strc_floats_saved_userdata}}

\def\strc_floats_place_packaged_boxes_indeed#userdata%
  {\bgroup
   \ifconditional\usesamefloatnumber
     \globallet\currentfloatnumber     \previousfloatnumber
     \globallet\currentfloatattribute  \empty
     \globallet\currentfloatsynchronize\relax
   \else
     \edef\currentfloatcounter{\namedcounterparameter\currentfloat\s!name}%
     \edef\currentfloatgroup  {\floatcaptionparameter\c!group}%
     \ifnofloatnumber \else \ifnofloatcaption \else
       \ifx\currentfloatgroup\empty
         % independent
         \strc_counters_increment\currentfloatcounter
       \else\ifcase\strc_floats_group_index
         % first in group
         \strc_counters_increment\currentfloatcounter
       \else
         % next in group
       \fi \fi
     \fi \fi
     % *1* as an alternative we could set counter parameters here if needed
     \strc_counters_register_component
       \s!float
       \setupcurrentfloatcaption
       \floatcaptionparameter
       \detokenizedfloatcaptionparameter
       \relax
       \relax
       \relax
       [\c!name=\currentfloat,%
        \s!counter=\currentfloatcounter,%
        \s!hascaption=\ifnofloatcaption \v!no\else\v!yes\fi,%
        \s!hasnumber=\ifnofloatnumber   \v!no\else\v!yes\fi,%
        \s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi]%
       [#userdata]%
     \globallet\previousfloatnumber    \m_strc_counters_last_registered_index
     \globallet\currentfloatnumber     \m_strc_counters_last_registered_index
     \globallet\currentfloatattribute  \m_strc_counters_last_registered_attribute
     \globallet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
   \fi
   %
   \global\setfalse\usesamefloatnumber % one shot
   % check float box
   \strc_floats_set_natural_dimensions\nextbox
   \global\setbox\floatbox\vbox{\floatparameter\c!command{\box\nextbox}}%
   \strc_floats_set_natural_dimensions\floatbox
   \ifdim\htdp\floatbox=\zeropoint
     \showmessage\m!floatblocks{11}\empty
     \global\setbox\floatbox\vbox
       {\dostarttagged\t!floatcontent\empty
        \strc_floats_place_empty_box
        \dostoptagged}%
   \fi
   % deal with lack of caption
   \global\setbox\floatbox\vbox \floatcaptionattribute
     {\doifelsemainfloatbody\currentfloatsynchronize\donothing
      \unvbox\floatbox
      \ifnofloatcaption
        \vss
      \fi}% gets rid of the depth (unless tabulate)
   \egroup
   % place the float
   \strc_floats_set_box
   \strc_floats_get_box
   \global\insidefloatfalse}

\newdimen\availablefloatwidth
\newdimen\availablefloatheight

\def\strc_floats_set_local_hsize
  {\ifconditional\c_page_floats_center_box_local
     % also available check here?
     \seteffectivehsize
     \hsize\localhsize
   \else
     \doifinset\v!margin\floatlocation % brr, really needed! see wm will be redone
       {\hsize\namedmarginblockparameter\empty\c!width}%
   \fi
   \edef\p_availablewidth {\floatparameter\c!availablewidth }%
   \edef\p_availableheight{\floatparameter\c!availableheight}%
   \availablefloatwidth \ifx\p_availablewidth \empty\hsize\else\p_availablewidth \relax\fi
   \availablefloatheight\ifx\p_availableheight\empty\vsize\else\p_availableheight\relax\fi}

\ifdefined\everyinsidefloat \else \newevery \everyinsidefloat \relax \fi

\appendtoks
    \everyinsidefloat\emptytoks % in case it's called earlier
    \strc_float_load_data
\to \everyinsidefloat

\def\doifrightpagefloatelse
  {\ifdoublesided
     \ifsinglesided
       \doubleexpandafter\firstoftwoarguments
     \else
       \doubleexpandafter\doifoddfloatpageelse
     \fi
   \else
     \expandafter\firstoftwoarguments
   \fi}

\def\doifoddfloatpageelse
  {\ifodd\purenumber\strc_float_realpage\space
     \expandafter\firstoftwoarguments
   \else
     \expandafter\secondoftwoarguments
   \fi}

\appendtoks
    \let\rightorleftpageaction\doifrightpagefloatelse
\to \everyinsidefloat

% \let\movesidefloat\gobbleoneargument

% new : \place...[leftmargin,-2*line]; we need to catch fxtb:2*3
% watch out: line alone aligns on the line ! ! !

\unexpanded\def\movesidefloat[#settings]% (-)n*line|x=,y=
  {\global\d_page_sides_downshift \zeropoint
   \global\d_page_sides_extrashift\zeropoint
   \doifassignmentelse{#settings}%
     {\begingroup
      \setupcurrentfloat[\c!x=\zeropoint,\c!y=\zeropoint,#settings]%
      \ifgridsnapping
        \getnoflines{\floatparameter\c!y}%
        \global\d_page_sides_downshift\noflines\lineheight
      \else
        \global\d_page_sides_downshift\floatparameter\c!y
      \fi
      \global\d_page_sides_extrashift\floatparameter\c!x
      \endgroup}
     {\movedownsidefloat[#settings]}}

\installcorenamespace{floatmovement}

\setvalue{\??floatmovement \v!line}{\strc_floats_move_down_line+}
\setvalue{\??floatmovement+\v!line}{\strc_floats_move_down_line+}
\setvalue{\??floatmovement-\v!line}{\strc_floats_move_down_line-}
\setvalue{\??floatmovement \v!hang}{\strc_floats_move_down_hang\plusone}
\setvalue{\??floatmovement+\v!hang}{\strc_floats_move_down_hang\plusone}
\setvalue{\??floatmovement-\v!hang}{\strc_floats_move_down_hang\minusone}

\def\strc_floats_move_down#setting%
  {\csname\??floatmovement
     \ifcsname\??floatmovement#setting\endcsname#setting\fi
   \endcsname}

\def\strc_floats_move_down_line#sign%
  {\if!!donea \else
     \global\d_page_sides_downshift\zeropoint
     \!!doneatrue
   \fi
   \global\advance\d_page_sides_downshift#sign\lineheight}

\def\strc_floats_move_down_hang#lines%
  {\if!!doneb \else
     \global\c_page_sides_n_of_lines\zerocount
     \!!donebtrue
   \fi
   \global\advance\c_page_sides_n_of_lines#lines\relax}

\unexpanded\def\movedownsidefloat[#settings]% already in core
  {\doifnotinstring{:}{#settings}
     {\begingroup
      \!!doneafalse
      \!!donebfalse
      \normalexpanded{\dorepeatwithcommand[#settings]}\strc_floats_move_down
      \endgroup}}

\unexpanded\def\hangsidefloat[#number]%
  {\global\c_page_sides_n_of_lines#number\relax}

\def\strc_floats_set_extra_action#rightpagelocation#leftpagelocation%
  {\rightorleftpageaction
     {\let\extrafloatlocation#rightpagelocation}%
     {\let\extrafloatlocation#leftpagelocation}}

\let\extrafloatlocation\empty

\installcorenamespace{extrafloataction}

\setvalue{\??extrafloataction      \v!inner}#1{\strc_floats_set_extra_action\v!left       \v!right}
\setvalue{\??extrafloataction      \v!outer}#1{\strc_floats_set_extra_action\v!right      \v!left}
\setvalue{\??extrafloataction\v!innermargin}#1{\strc_floats_set_extra_action\v!leftmargin \v!rightmargin}
\setvalue{\??extrafloataction\v!outermargin}#1{\strc_floats_set_extra_action\v!rightmargin\v!leftmargin}
\setvalue{\??extrafloataction  \v!inneredge}#1{\strc_floats_set_extra_action\v!leftedge   \v!rightedge}
\setvalue{\??extrafloataction  \v!outeredge}#1{\strc_floats_set_extra_action\v!rightedge  \v!leftedge}
\setvalue{\??extrafloataction  \v!backspace}#1{\strc_floats_set_extra_action\v!backspace  \v!cutspace}
\setvalue{\??extrafloataction   \v!cutspace}#1{\strc_floats_set_extra_action\v!cutspace   \v!backspace}
%setvalue{\??extrafloataction     \v!margin}#1{\strc_floats_set_extra_action\v!cutspace   \v!backspace}
\setvalue{\??extrafloataction       \v!left}#1{\strc_floats_set_extra_action\v!left       \v!left}
\setvalue{\??extrafloataction      \v!right}#1{\strc_floats_set_extra_action\v!right      \v!right}
\setvalue{\??extrafloataction       \v!line}#1{} % only -n*line is handled (see ***)
\setvalue{\??extrafloataction    \s!unknown}#1{\movedownsidefloat[#1]}

\def\strc_floats_check_extra_actions % less tracingthis way ....
  {\doifnotinset\v!text\floatlocation % fuzzy, text overloads left, since then it's a directive
     {\let\extrafloatlocation\empty
      % \d_page_sides_downshift will be reset afterwards, and can
      % already be set at this point
      \processcommacommand[\floatlocation]\strc_floats_check_extra_actions_step
      \ifx\extrafloatlocation\empty \else
        \edef\floatlocation{\extrafloatlocation,\floatlocation}%
        \setfloatmethodvariables\floatlocation
      \fi}}

\def\strc_floats_check_extra_actions_step#step%
  {\csname\??extrafloataction
     \ifcsname\??extrafloataction#step\endcsname#step\else\s!unknown\fi
   \endcsname{#step}}

% pas op, maxbreedte niet instellen als plaats=links/rechts

\def\strc_floats_set_local_dimensions
  {\global\d_page_sides_shift  \zeropoint       % duplicate
   \global\d_page_sides_maximum\zeropoint\relax % duplicate
   \ifdim\d_page_sides_downshift=\zeropoint\else
     \global\setbox\floatbox\vbox
       {\vskip\d_page_sides_downshift
        \nointerlineskip
        \box\floatbox}%
   \fi
   \edef\p_minwidth{\floatparameter\c!minwidth}%
   \ifx\p_minwidth\empty
     % nothing
   \else
     \scratchwidth\p_minwidth\relax
     \ifdim\wd\floatbox<\scratchwidth
       \strc_floats_realign_floatbox_horizontal_two
     \fi
   \fi
   % we can also support edges .. in that case no common but a fast loop
   \doifinsetelse\v!hanging\floatlocation
     {\doifcommonelse{\v!inleft,\v!leftmargin}\floatlocation
        {\let\p_maxwidth\leftmarginwidth}%
        {\doifcommonelse{\v!inright,\v!rightmargin}\floatlocation
           {\let\p_maxwidth\rightmarginwidth}%
           {\edef\p_maxwidth{\floatparameter\c!maxwidth}}}}%
     {\edef\p_maxwidth{\floatparameter\c!maxwidth}}%
   \ifx\p_maxwidth\empty
     % nothing
   \else
     \scratchwidth\p_maxwidth\relax
     \ifdim\wd\floatbox>\scratchwidth
       \doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge,\v!inleft,\v!leftmargin,\v!leftedge}\floatlocation
         {\global\d_page_sides_maximum\scratchwidth}
         {\doifcommonelse{\v!right,\v!left}\floatlocation
            \strc_floats_realign_floatbox_horizontal_one
            \strc_floats_realign_floatbox_horizontal_two}%
     \fi
   \fi}

\def\strc_floats_realign_floatbox_horizontal_one
  {\global\setbox\floatbox\hbox to \scratchwidth
     {\doifnotinset\v!right\floatlocation\hss
      \box\floatbox
      \doifnotinset\v!left \floatlocation\hss}}

\def\strc_floats_realign_floatbox_horizontal_two
  {\global\setbox\floatbox\hbox to \scratchwidth
     {\doifnot{\floatparameter\c!location}\v!left \hss
      \box\floatbox
      \doifnot{\floatparameter\c!location}\v!right\hss}}

\unexpanded\def\placefloats
  {\page_otr_command_flush_floats}

\newdimen\d_strc_floats_margin
\newdimen\d_strc_floats_top
\newdimen\d_strc_floats_bottom

\def\strc_floats_calculate_skip#target#skip%
  {\edef\askedfloatskip{#skip}%
   \ifx\askedfloatskip\empty
     \global#target\zeropoint
   \else\ifx\askedfloatskip\v!none
     \global#target\zeropoint
   \else
     \setbox\scratchbox\vbox{\whitespace\blank[\askedfloatskip]}% todo: move whitespace inside blank
     \global#target\ht\scratchbox
   \fi\fi}

\def\strc_floats_calculate_skips
  {\begingroup
   \strc_floats_calculate_skip\d_strc_floats_top      {\rootfloatparameter\c!spacebefore    }%
   \strc_floats_calculate_skip\d_strc_floats_bottom   {\rootfloatparameter\c!spaceafter     }%
   \strc_floats_calculate_skip\d_page_sides_topskip   {\rootfloatparameter\c!sidespacebefore}%
   \strc_floats_calculate_skip\d_page_sides_bottomskip{\rootfloatparameter\c!sidespaceafter }%
   \global\d_strc_floats_margin   \rootfloatparameter\c!margin
   \global\d_page_sided_leftshift \floatparameter    \c!leftmargindistance
   \global\d_page_sided_rightshift\floatparameter    \c!rightmargindistance
   \global\c_page_floats_n_of_top                    \rootfloatparameter\c!ntop
   \global\c_page_floats_n_of_bottom                 \rootfloatparameter\c!nbottom
   \endgroup}

\unexpanded\def\betweenfloatblanko % assumes that spaceafter is present
  {\blank[\rootfloatparameter\c!spacebefore]} % or v!back,....

\unexpanded\def\doplacefloatbox % used elsewhere
  {%\forgetall % NO
   \whitespace
   \blank[\rootfloatparameter\c!spacebefore]
   \page_otr_command_flush_float_box
   \blank[\rootfloatparameter\c!spaceafter]}

% test case:
%
% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=0.9\textheight,color=green]}
% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.0\textheight,color=green]}
% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.1\textheight,color=green]}

% the [#1] will go away

\def\page_one_place_float_text % this macro should be defined elsewhere
  {%\checkwaitingfloats\floatlocationmethod
   % todo: check if #1 is indeed \floatlocation or maybe more
   \global\floatwidth    \wd\floatbox
   \global\floatheight   \ht\floatbox % forget about the depth
   \global\floattextwidth\dimexpr\hsize-\floatwidth-\rootfloatparameter\c!margin\relax
   \edef\floatlocation{\floatlocationmethod}% to be sure .. why
   \doifinsetelse\v!tall\floatlocationmethod
     {\floattextheight\dimexpr\pagegoal-\pagetotal-\bigskipamount\relax % ugly, this bigskip
      \ifdim\floattextheight>\textheight
        \floattextheight\textheight
      \fi
      \boxmaxdepth\zeropoint\relax            % toegevoegd
      \ifdim\floattextheight<\floatheight
        \floattextheight\floatheight
      \fi
      \setbox\floattext\vbox to \floattextheight}
     {\setbox\floattext\vbox}%
   \bgroup
   \forgetall
   \setupblank
   \setupwhitespace % new, also needed for footnotes
   \blank[\v!disable]
   \hsize\floattextwidth
   \ignorespaces}

\def\strc_floats_stop_text_indeed
  {\egroup
   \doifnotinset\v!tall\floatlocation
     {\floattextheight\ifdim\ht\floattext<\floatheight\floatheight\else\ht\floattext\fi}%
   \setbox\floatbox\vbox to \floattextheight
     {\hsize\floatwidth
      \doifinsetelse\v!both\floatlocation
        {\doifinsetelse\v!low\floatlocation
           {\vfill\box\floatbox}
           {\doifinsetelse\v!middle\floatlocation
              {\vfill\box\floatbox\vfill}
              {\box\floatbox\vfill}}}
        {\box\floatbox\vfill}}%
    \setbox\floattext\vbox to \floattextheight
     {\hsize\floattextwidth
      \doifinsetelse\v!low\floatlocation
        {\vfill
         \box\floattext
         \doifinset\c!offset\floatlocation{\whitespace\blank}}
        {\doifinsetelse\v!middle\floatlocation
           {\vfill
            \box\floattext
            \vfill}
           {\doifinset\v!offset\floatlocation{\whitespace\blank}%
            \box\floattext
            \vfill}}}%
   \doifinsetelse\v!right\floatlocation
     {\setbox\floatbox\hbox to \hsize
        {\box\floattext
         \hfill
         \box\floatbox}}
     {\setbox\floatbox\hbox to \hsize
        {\box\floatbox
         \hfill
         \box\floattext}}%
   \baselinecorrection
   \whitespace
   \blank[\rootfloatparameter\c!spacebefore]%
   \doifnotinset\v!tall\floatlocation
     {\dp\floatbox\openstrutdepth}% dp\strutbox}%      % toegevoegd
   \box\floatbox
   \dostoptagged
   \blank[\rootfloatparameter\c!spaceafter]%
   \strc_floats_end_text_group
   \page_floats_report_total}

\def\borderedfloatbox
  {\begingroup
   \setupcurrentfloat[\c!location=\v!normal,\c!width=\v!fit,\c!height=\v!fit]%
   \inheritedfloatframed{\box\floatbox}%
   \endgroup}

% minwidth=fit,width=max : no overshoot, as wide as graphic

\def\strc_floats_align_content_indeed
  {\alignstrutmode\zerocount
   \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
     {\shiftalignedline
        {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}%
        {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}}%
   \alignedline{\floatparameter\c!location}\v!middle}

\def\strc_floats_align_caption_indeed
  {\alignstrutmode\zerocount
   \shiftalignedline
     {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}%
     {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}%
   \alignedline{\floatparameter\c!location}\v!middle}

\newdimen\d_strc_floats_content
\newdimen\d_strc_float_temp_height
\newdimen\d_strc_float_temp_width

\def\captionminwidth {15\bodyfontsize}
\def\captionovershoot{2\emwidth}

\def\strc_floats_set_page_variant
  {\bgroup
   \strc_floats_set_local_hsize
   \ifcase\c_strc_floats_rotation\else
     \swapdimens\hsize\vsize
   \fi
   \forgetall
   \postponenotes
   \dontcomplain
   \setbox\b_strc_floats_content\vbox{\borderedfloatbox}%
   \let\strc_floats_align_content\strc_floats_align_content_indeed
   \let\strc_floats_align_caption\strc_floats_align_caption_indeed
   \strc_floats_check_caption_content
   \d_strc_floats_content\wd\b_strc_floats_content
   \ifcase\floatparameter\c!method
     % nothing
   \or
     % automatic
    \ifnofloatcaption
       \strc_floats_prepare_no_caption
      %\page_backgrounds_add_local_to_box\floatbox % was \doglobal but not needed
     \else
       % todo: installable maken, variant/method=auto vs macro
       \strc_floats_prepare_page_caption
      %\page_backgrounds_add_local_to_box\b_strc_floats_content
       \setbox\b_strc_floats_caption\hbox
         {\floatcaptionparameter\c!command{\box\b_strc_floats_caption}}%
       \moveboxontogrid\b_strc_floats_caption{\floatcaptionparameter\c!grid}\d_strc_floats_caption_height
      %\page_backgrounds_add_local_to_box\b_strc_floats_caption
       \strc_floats_build_box
     \fi
   \or
     % semi automatic
   \or
     % manual
   \fi
   \ifcase\c_strc_floats_rotation
     \doifnotinset\v!margin\floatlocation % brr, really needed! see wm
       {\postcenterfloatbox\d_strc_floats_content}%
   \else
     \global\setbox\floatbox\vbox
       {\rotate[\c!rotation=\number\c_strc_floats_rotation]{\box\floatbox}}%
   \fi
   \egroup}

\def\strc_floats_prepare_no_caption
  {\global\setbox\floatbox\vbox % pas op als wd groter dan hsize
     {\ifinsidecolumns\ifdim\wd\b_strc_floats_content>\hsize
        \let\strc_floats_align_content\relax
      \fi\fi
      \strc_floats_align_content{\copy\b_strc_floats_content}}}

\def\strc_floats_prepare_page_caption
  {\edef\p_strc_floats_caption_location{\floatcaptionparameter\c!location}%
   \edef\p_strc_floats_caption_width   {\floatcaptionparameter\c!width}%
   \edef\p_strc_floats_caption_minwidth{\floatcaptionparameter\c!minwidth}%
   \edef\p_strc_floats_caption_align   {\floatcaptionparameter\c!align}%
   \dostarttagged\t!floatcaption\empty
   \ifx\p_strc_floats_caption_location\v!top
     \strc_floats_prepare_page_caption_top_bottom
   \else\ifx\p_strc_floats_caption_location\v!bottom
     \strc_floats_prepare_page_caption_top_bottom
   \else\ifx\p_strc_floats_caption_width\v!fit
     \strc_floats_prepare_side_auto_caption
   \else\ifx\p_strc_floats_caption_width\v!max
     \strc_floats_prepare_side_auto_caption
   \else
     \strc_floats_prepare_side_width_caption
   \fi\fi\fi\fi
   \dostoptagged}

\def\strc_floats_prepare_page_caption_top_bottom
  {\ifx\p_strc_floats_caption_width\v!fit
     \strc_floats_prepare_page_caption_top_bottom_fit_max
   \else\ifx\p_strc_floats_caption_width\v!max
     \strc_floats_prepare_page_caption_top_bottom_fit_max
   \else
     \strc_floats_prepare_side_width_caption % new, special effects (see icare)
   \fi\fi}

\def\strc_floats_prepare_page_caption_top_bottom_fit_max
  {\ifx\p_strc_floats_caption_minwidth\v!fit
     \ifx\p_strc_floats_caption_width\v!max
       \strc_floats_prepare_stack_caption_max
     \else\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content % wider caption
       \ifx\p_strc_floats_caption_width\v!fit
         \strc_floats_prepare_stack_caption_auto
       \else
         \strc_floats_prepare_stack_caption_width
       \fi
     \else
       \strc_floats_prepare_stack_caption_min
     \fi\fi
  \else
    \strc_floats_prepare_stack_caption_fixed
  \fi}

\def\strc_floats_caption_set_align
  {\normalexpanded{\setupalign[\v!reset,\p_strc_floats_caption_align]}}

\def\strc_floats_prepare_side_auto_caption
  {\scratchdimen\dimexpr\hsize-\wd\b_strc_floats_content-\floatparameter\c!margin\relax
   \ifdim\wd\b_strc_floats_caption>\scratchdimen
     \ifdim\wd\b_strc_floats_caption<1.3\scratchdimen
       \scratchdimen0.8\scratchdimen
     \fi
   \fi
   \setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\scratchdimen
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_side_width_caption
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\floatcaptionparameter\c!width
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_stack_caption_fixed
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\floatcaptionparameter\c!minwidth % special effects
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_stack_caption_max
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\wd\b_strc_floats_content
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_stack_caption_width
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\floatcaptionparameter\c!width
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_stack_caption_min
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\wd\b_strc_floats_content
      \ifx\p_strc_floats_caption_align\empty
        \raggedcenter % on purpose overloads align !
      \fi
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_stack_caption_auto
  {\ifx\p_strc_floats_caption_align\empty \else
     \doifnotinset\v!middle\p_strc_floats_caption_align{\let\captionovershoot\!!zeropoint}%
   \fi
   \edef\captionhsize{\the\wd\b_strc_floats_content}%
   \ifdim\captionhsize>\hsize
     % float is wider than \hsize
     \setbox\b_strc_floats_caption\vbox
       {\settrialtypesetting
        \strc_floats_caption_set_align
        \hsize\captionhsize
        \notesenabledfalse
        \strc_floats_make_complete_caption}%
     \ifdim\ht\scratchbox>\lineheight % more lines
       \setbox\b_strc_floats_caption\vbox
         {\strc_floats_caption_set_align
          \hsize\dimexpr\captionhsize-\captionovershoot\relax
          \ifdim\hsize<\captionminwidth\relax
            \hsize\captionhsize
          \fi
          \strc_floats_make_complete_caption}%
     \else
       \setbox\b_strc_floats_caption\vbox
         {\strc_floats_caption_set_align
          \hsize\captionhsize
          \strc_floats_make_complete_caption}%
     \fi
   \else
     % float is smaller of equal to \hsize
     \ifdim\captionhsize<\captionminwidth\relax
       \scratchdimen\captionminwidth % float smaller than min width
       \edef\captionhsize{\the\scratchdimen}%
     \fi
     \setbox\scratchbox\vbox     % test with overshoot
       {\settrialtypesetting
        \scratchdimen\dimexpr\captionhsize+\captionovershoot+3\emwidth\relax % 3em is an average word length
        \ifdim\scratchdimen<\hsize
          \hsize\scratchdimen
        \fi
        \notesenabledfalse
        \strc_floats_make_complete_caption}%
     \ifdim\ht\scratchbox>\lineheight
       % at least an average word longer than a line
       \setbox\b_strc_floats_caption\vbox
         {\strc_floats_caption_set_align
          \scratchdimen\dimexpr\captionhsize+\captionovershoot\relax
          \ifdim\scratchdimen<\hsize
            \hsize\scratchdimen
          \fi
          \strc_floats_make_complete_caption}%
     \else\ifx\p_strc_floats_caption_align\empty
       \setbox\b_strc_floats_caption\vbox
         {\strc_floats_caption_set_align
          \hsize\captionhsize
          \raggedcenter % overloads
          \strc_floats_make_complete_caption}%
     \else
       \setbox\b_strc_floats_caption\vbox
         {\strc_floats_caption_set_align
          \hsize\captionhsize
          \strc_floats_make_complete_caption}%
     \fi\fi
   \fi}

\def\strc_floats_between_stack
  {\endgraf
   \nointerlineskip
   \floatcaptionparameter\c!inbetween
   \endgraf}

\def\strc_floats_build_box_default % done
  {\strc_floats_align_content{\box\b_strc_floats_content}}

\def\strc_floats_build_box_next_right#1%
  {\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi
     {\d_strc_float_temp_height\ht\b_strc_floats_content
      \box\b_strc_floats_content
      \doifnotinset\v!hang{\floatcaptionparameter\c!location}
        {\dotfskip{\floatcaptionparameter\c!distance}}%
      \vbox to\d_strc_float_temp_height{#1}}}

\def\strc_floats_build_box_next_left#1%
  {\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi
     {\d_strc_float_temp_height\ht\b_strc_floats_content
      \vbox to\d_strc_float_temp_height{#1}%
      \doifnotinset\v!hang{\floatcaptionparameter\c!location}
        {\dotfskip{\floatcaptionparameter\c!distance}}%
      \box\b_strc_floats_content}}

\def\strc_floats_build_box_next_outer
  {\doifrightpagefloatelse\strc_floats_build_box_next_right\strc_floats_build_box_next_left}

\def\strc_floats_build_box_next_inner
  {\doifrightpagefloatelse\strc_floats_build_box_next_left\strc_floats_build_box_next_right}

\def\strc_floats_build_box_next_right_hang#1%
  {\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi
     {\d_strc_float_temp_height\ht\b_strc_floats_content
      \box\b_strc_floats_content
      \vbox to\d_strc_float_temp_height{#1}}}

\def\strc_floats_build_box_next_left_hang#1%
  {\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi
     {\d_strc_float_temp_height\ht\b_strc_floats_content
      \vbox to\d_strc_float_temp_height{#1}%
      \box\b_strc_floats_content}}

\def\strc_floats_build_box_next_right_margin_indeed#1#2%
  {\ifconditional\c_strc_floats_par_float
     \hbox\bgroup
     \d_strc_float_temp_height\ht\b_strc_floats_content
     \box\b_strc_floats_content
     \hsmash{\hskip#1\vbox to\d_strc_float_temp_height{#2}}%
     \egroup
   \else
     \begingroup
     \d_strc_float_temp_height\ht\b_strc_floats_content
     \everyrightofalignedline{\hsmash{\hskip#1\vbox to\d_strc_float_temp_height{#2}}}%
     \strc_floats_align_content{\box\b_strc_floats_content}%
     \endgroup
    \fi}

\def\strc_floats_build_box_next_left_margin_indeed#1#2%
  {\ifconditional\c_strc_floats_par_float
     \hbox\bgroup
     \d_strc_float_temp_height\ht\b_strc_floats_content
     \hsmash{\hskip-\dimexpr#1+\wd\b_strc_floats_caption\relax\vbox to\d_strc_float_temp_height{#2}}%
     \box\b_strc_floats_content
     \egroup
   \else
     \begingroup
     \d_strc_float_temp_height\ht\b_strc_floats_content
     \everyleftofalignedline{\hsmash{\hskip-\dimexpr#1+\wd\b_strc_floats_caption\relax\vbox to\d_strc_float_temp_height{#2}}}%
     \strc_floats_align_content{\box\b_strc_floats_content}%
     \endgroup
   \fi}

\def\strc_floats_build_box_next_right_margin
  {\strc_floats_build_box_next_right_margin_indeed\rightmargindistance}

\def\strc_floats_build_box_next_left_margin
  {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance }

\def\strc_floats_build_box_next_outer_margin
  {\doifrightpagefloatelse
     {\strc_floats_build_box_next_right_margin_indeed\rightmargindistance}
     {\strc_floats_build_box_next_left_margin_indeed \rightmargindistance}}

\def\strc_floats_build_box_next_inner_margin
  {\doifrightpagefloatelse
     {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance}
     {\strc_floats_build_box_next_right_margin_indeed\leftmargindistance}}

\def\strc_floats_build_box_next % beware, we first check on left/rightmargin because there can be left/right also
  {\let\next\strc_floats_build_box_next_left
   \processallactionsinset[\floatcaptionparameter\c!location]
     [ \v!outermargin=>\let\next\strc_floats_build_box_next_outer_margin,
       \v!innermargin=>\let\next\strc_floats_build_box_next_inner_margin,
        \v!leftmargin=>\let\next\strc_floats_build_box_next_left_margin,
       \v!rightmargin=>\let\next\strc_floats_build_box_next_right_margin,
       \v!lefthanging=>\let\next\strc_floats_build_box_next_left_hang,
      \v!righthanging=>\let\next\strc_floats_build_box_next_right_hang,
             \v!outer=>\let\next\strc_floats_build_box_next_outer,
             \v!inner=>\let\next\strc_floats_build_box_next_inner,
              \v!left=>\let\next\strc_floats_build_box_next_left,
             \v!right=>\let\next\strc_floats_build_box_next_right]%
   \next}

\def\strc_floats_build_box_side
  {\ifconditional\c_strc_floats_par_float
     \let\next\strc_floats_build_box_high
   \else
     \let\next\strc_floats_build_box_middle
     \processallactionsinset[\floatcaptionparameter\c!location]
       [   \v!low=>\let\next\strc_floats_build_box_low,
        \v!middle=>\let\next\strc_floats_build_box_middle,
          \v!high=>\let\next\strc_floats_build_box_high]%
   \fi
   \next}

\def\strc_floats_flush_right_caption_hang
  {\hsmash{\rlap{\dotfskip{\floatcaptionparameter\c!distance}\box\b_strc_floats_caption}}}

\def\strc_floats_flush_left_caption_hang
  {\hsmash{\llap{\box\b_strc_floats_caption\dotfskip{\floatcaptionparameter\c!distance}}}}

% \def\strc_floats_flush_caption_hang % expanded can go
%   {\expanded{\doifinsetelse{\v!righthanging}{\floatcaptionparameter\c!location}}
%      {\strc_floats_flush_right_caption_hang}
%      {\expanded{\doifinsetelse{\v!lefthanging}{\floatcaptionparameter\c!location}}
%         {\strc_floats_flush_left_caption_hang}
%         {\expanded{\doifinsetelse{\v!hang}{\floatcaptionparameter\c!location}}
%            {\expanded{\doifinsetelse{\v!outer}{\floatcaptionparameter\c!location}}
%               {\doifrightpagefloatelse{\strc_floats_flush_right_caption_hang}{\strc_floats_flush_left_caption_hang}}
%               {\expanded{\doifinsetelse{\v!right}{\floatcaptiondirectives}}
%                  {\strc_floats_flush_right_caption_hang}
%                  {\strc_floats_flush_left_caption_hang}}}
%         {\box\b_strc_floats_caption}}}}

\def\strc_floats_flush_caption_hang % expanded can go
  {\edef\p_strc_floats_caption_location{\floatcaptionparameter\c!location}%
   \doifinsetelse\v!righthanging\p_strc_floats_caption_location
     {\strc_floats_flush_right_caption_hang}
     {\doifinsetelse\v!lefthanging\p_strc_floats_caption_location
        {\strc_floats_flush_left_caption_hang}
        {\doifinsetelse\v!hang\p_strc_floats_caption_location
           {\doifinsetelse\v!outer\p_strc_floats_caption_location
              {\doifrightpagefloatelse{\strc_floats_flush_right_caption_hang}{\strc_floats_flush_left_caption_hang}}
              {\doifinsetelse\v!right\floatcaptiondirectives
                 {\strc_floats_flush_right_caption_hang}
                 {\strc_floats_flush_left_caption_hang}}}
        {\box\b_strc_floats_caption}}}}

\def\strc_floats_build_box_high
  {\strc_floats_build_box_next{\strc_floats_between_stack\strc_floats_flush_caption_hang\vfill}}

\def\strc_floats_build_box_low
  {\strc_floats_build_box_next{\vfill\strc_floats_flush_caption_hang\strc_floats_between_stack}}

\def\strc_floats_build_box_middle
  {\strc_floats_build_box_next{\vfill\box\b_strc_floats_caption\vfill}}

% \definefloat
%   [lefty][lefties][figure]
% \setupfloat
%   [lefty]
%   [default=left,
%    rightmargindistance=-2cm,
%    leftmargindistance=-2cm]
% \setupcaption
%   [lefty]
%   [location={bottom,overlay}]
%
% \starttext
%     \placelefty{}{} \input tufte \input tufte
%     \placelefty{}{} \input tufte \input tufte
% \stoptext

\def\strc_floats_build_box_top_stack_normal_overlay
  {\vbox to \ht\b_strc_floats_content{\vss\strc_floats_build_box_top_stack_normal_content}}

\def\strc_floats_build_box_top_stack_normal_content
  {\d_strc_float_temp_width\wd\b_strc_floats_content
   \ifconditional\c_strc_floats_par_float
     \hbox{\strc_floats_locate_side_float{\box\b_strc_floats_caption}}%
     \strc_floats_between_stack
     \hbox{\hbox{\box\b_strc_floats_content}}%
   \else
     \page_otr_command_set_float_hsize
     \hbox{\strc_floats_locate_text_float{\box\b_strc_floats_caption}}
     \strc_floats_between_stack
     \hbox{\strc_floats_align_content{\box\b_strc_floats_content}}%
   \fi}

\def\strc_floats_build_box_bottom_stack_normal_overlay
  {\vbox to \ht\b_strc_floats_content{\strc_floats_build_box_bottom_stack_normal_content\vss}}

\def\strc_floats_build_box_bottom_stack_normal_content
  {\d_strc_float_temp_width\wd\b_strc_floats_content
   \ifconditional\c_strc_floats_par_float
     \hbox{\hbox{\box\b_strc_floats_content}}%
     \strc_floats_between_stack
     \hbox{\strc_floats_locate_side_float{\box\b_strc_floats_caption}}%
   \else
     \page_otr_command_set_float_hsize
     \hbox{\strc_floats_align_content{\box\b_strc_floats_content}}%
     \strc_floats_between_stack
     \hbox{\strc_floats_locate_text_float{\box\b_strc_floats_caption}}%
   \fi}

\def\strc_floats_build_box_top_stack_normal
  {\doifinsetelse\v!overlay{\floatcaptionparameter\c!location}
      \strc_floats_build_box_top_stack_normal_overlay
      \strc_floats_build_box_top_stack_normal_content}

\def\strc_floats_build_box_bottom_stack_normal
  {\doifinset\v!overlay{\floatcaptionparameter\c!location}
    \strc_floats_build_box_bottom_stack_normal_overlay
    \strc_floats_build_box_bottom_stack_normal_content}

\def\strc_floats_build_box_top_stack_grid
  {\dp\b_strc_floats_caption\strutdepth
   \setbox\scratchbox\vbox
     {\d_strc_float_temp_width\wd\b_strc_floats_content
      \ifconditional\c_strc_floats_par_float
        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
        \vss\strc_floats_between_stack
        \hbox{\box\b_strc_floats_content}%
      \else
        \page_otr_command_set_float_hsize
        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
        \vss\strc_floats_between_stack
        \strc_floats_align_content{\box\b_strc_floats_content}%
      \fi}%
   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
   \vbox to \noflines\lineheight{\unvbox\scratchbox}}

\def\strc_floats_build_box_bottom_stack_grid
  {\dp\b_strc_floats_caption\strutdepth
   \setbox\scratchbox\vbox
     {\d_strc_float_temp_width\wd\b_strc_floats_content
      \ifconditional\c_strc_floats_par_float
        \hbox{\box\b_strc_floats_content}%
        \vss\strc_floats_between_stack
        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
      \else
        \page_otr_command_set_float_hsize
        \strc_floats_align_content{\box\b_strc_floats_content}%
        \vss\strc_floats_between_stack
        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
      \fi}%
   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
   \vbox to \noflines\lineheight{\unvbox\scratchbox}}

\def\strc_floats_build_box_top_stack_stretch
  {\dp\b_strc_floats_caption\strutdepth
   \setbox\scratchbox\vbox
     {\strc_floats_align_caption{\copy\b_strc_floats_caption}%
      \strc_floats_align_content  {\copy\b_strc_floats_content  }}%
   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
   \vbox to \noflines\lineheight
     {\d_strc_float_temp_width\wd\b_strc_floats_content
      \ifconditional\c_strc_floats_par_float
        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
        \vss\strc_floats_between_stack\vss
        \hbox{\box\b_strc_floats_content}%
      \else
        \page_otr_command_set_float_hsize
        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
        \vss\strc_floats_between_stack\vss
        \strc_floats_align_content{\box\b_strc_floats_content}%
      \fi}}

\def\strc_floats_build_box_bottom_stack_stretch
  {\dp\b_strc_floats_caption\strutdepth
   \setbox\scratchbox\vbox
     {\strc_floats_align_content{\copy\b_strc_floats_content  }%
      \strc_floats_align_caption{\copy\b_strc_floats_caption}}%
   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
   \vbox to \noflines\lineheight
     {\d_strc_float_temp_width\wd\b_strc_floats_content
      \ifconditional\c_strc_floats_par_float
        \hbox{\box\b_strc_floats_content}%
        \vss\strc_floats_between_stack\vss
        \strc_floats_locate_side_float{\box\b_strc_floats_caption}
      \else
        \page_otr_command_set_float_hsize
        \strc_floats_align_content{\box\b_strc_floats_content}%
        \vss\strc_floats_between_stack\vss
        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
      \fi}}

\def\strc_floats_build_box_top
  {\let\next\strc_floats_build_box_top_stack_normal
   \processfirstactioninset[\floatcaptionparameter\c!location]
     [   \v!grid=>\let\next\strc_floats_build_box_top_stack_grid,
      \v!stretch=>\let\next\strc_floats_build_box_top_stack_stretch]%
   \next}

\def\strc_floats_build_box_bottom
  {\let\next\strc_floats_build_box_bottom_stack_normal
   \processfirstactioninset[\floatcaptionparameter\c!location]
     [   \v!grid=>\let\next\strc_floats_build_box_bottom_stack_grid,
      \v!stretch=>\let\next\strc_floats_build_box_bottom_stack_stretch]%
   \next}

\def\strc_floats_relocate_caption_right#1{\strc_floats_align_caption{\hbox to \d_strc_float_temp_width{\hss#1}}}
\def\strc_floats_relocate_caption_left #1{\strc_floats_align_caption{\hbox to \d_strc_float_temp_width{#1\hss}}}

\unexpanded\def\installfloatboxbuilder#1#2{\setvalue{\??floatbuilder#1}{#2}}

\def\strc_floats_build_box
  {\global\setbox\floatbox\vbox
     {\strc_floats_set_local_hsize
      \forgetall
      \let\floatcaptionarrangement\s!default
      \processcommacommand[\floatcaptionparameter\c!location]\strc_floats_build_box_step
      \executeifdefined{\??floatbuilder\floatcaptionarrangement}{\getvalue{\??floatbuilder\s!default}}}}

\def\strc_floats_build_box_step#1%
  {\doifdefined{\??floatbuilder#1}{\def\floatcaptionarrangement{#1}\quitcommalist}}

\def\strc_floats_locate_text_float
  {\let\next\strc_floats_align_caption
   \processallactionsinset[\floatcaptionparameter\c!location]
     [ \v!left=>\let\next\strc_floats_relocate_caption_left,
      \v!right=>\let\next\strc_floats_relocate_caption_right,
      \v!inner=>\doifrightpagefloatelse{\let\next\strc_floats_relocate_caption_left }{\let\next\strc_floats_relocate_caption_right},
      \v!outer=>\doifrightpagefloatelse{\let\next\strc_floats_relocate_caption_right}{\let\next\strc_floats_relocate_caption_left }]%
   \next}

\installfloatboxbuilder \v!none    \strc_floats_build_box_default
\installfloatboxbuilder \s!default \strc_floats_build_box_default
\installfloatboxbuilder \v!high    \strc_floats_build_box_high
\installfloatboxbuilder \v!low     \strc_floats_build_box_low
\installfloatboxbuilder \v!middle  \strc_floats_build_box_middle

\installfloatboxbuilder \v!left    \strc_floats_build_box_side
\installfloatboxbuilder \v!right   \strc_floats_build_box_side

\installfloatboxbuilder \v!top     \strc_floats_build_box_top
\installfloatboxbuilder \v!bottom  \strc_floats_build_box_bottom

% \setuplayout[grid=yes] \showgrid \setupcaptions[style=smallbodyfont,location=grid,inbetween=]
%
% \starttext
%     test \placefigure{}                 {\externalfigure[cow.pdf][frame=on,grid=yes]}   test \page
%     test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=yes]}   test \page
%     test \placefigure{}                 {\externalfigure[cow.pdf][frame=on,grid=depth]} test \page
%     test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=depth]} test \page
% \stoptext

% This might move to page-flt:

\newif\ifpostponecolumnfloats \postponecolumnfloatsfalse % don't change

\setnewconstant\postcenterfloatmethod\plusone

\def\postcenterfloatbox#1%
  {\scratchdimen
     \ifcase\postcenterfloatmethod
       #1% \wd\floatbox
     \or\ifinsidecolumns
       \ifpostponecolumnfloats\makeupwidth\else#1\fi
     \else\ifdim#1>\hsize
       \hsize
     \else
       \wd\floatbox
     \fi\fi\fi
   \global\setbox\floatbox\hbox to \scratchdimen
   % {\hfill\box\floatbox\hfill}} % geen \hss, gaat mis in kolommen !
   % {\hss  \box\floatbox\hss  }} % wel \hss, anders mis in colset
     {\ifconditional\c_page_floats_center_box_global
        \donetrue
      \else\ifconditional\c_page_floats_center_box_local
        \donetrue
      \else
        \donefalse
      \fi\fi
      \ifdim\scratchdimen>\effectivehsize
        \donefalse
      \fi
      \hss\ifdone\hskip\effectiveleftskip\fi
      \box\floatbox
      \ifdone\hskip\effectiverightskip\fi\hss}}

\def\strc_floats_set_paragraph_variant
  {\bgroup
   \forgetall
   \postponenotes
   \dontcomplain
   \setbox\b_strc_floats_content\vbox{\borderedfloatbox}%
  %\page_backgrounds_add_local_to_box\b_strc_floats_content
   \ifnofloatcaption
     \global\setbox\floatbox\vbox{\box\b_strc_floats_content}%
   \else
     \strc_floats_check_caption_content
     \strc_floats_prepare_side_caption
     \setbox\b_strc_floats_caption\hbox{\floatcaptionparameter\c!command{\box\b_strc_floats_caption}}%
     \moveboxontogrid\b_strc_floats_caption{\floatcaptionparameter\c!grid}\d_strc_floats_caption_height
    %\page_backgrounds_add_local_to_box\b_strc_floats_caption
     \strc_floats_build_side_box
   \fi
   \egroup}

% \def\strc_floats_prepare_side_caption
%   {\dostarttagged\t!floatcaption\empty
%    \edef\p_strc_floats_caption_align{\floatcaptionparameter\c!align}%
%    \doifelse{\floatcaptionparameter\c!width}\v!max
%      {\setbox\b_strc_floats_caption\vbox
%         {\strc_floats_caption_set_align
%          \hsize\wd\b_strc_floats_content
%          \strc_floats_make_complete_caption}}%
%      {\doifelse{\floatcaptionparameter\c!width}\v!fit
%         {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax
%            \setbox\b_strc_floats_caption\vbox
%              {\forgetall % needed?
%               \hsize\wd\b_strc_floats_content
%               \strc_floats_make_complete_caption}%
%          \else
%            \setbox\b_strc_floats_caption\hbox to \wd\b_strc_floats_content
%              {\hss\hbox{\strc_floats_make_complete_caption}\hss}%
%          \fi}
%         {\setbox\b_strc_floats_caption\vbox
%            {\strc_floats_caption_set_align
%             \hsize\floatcaptionparameter\c!width % \wd\b_strc_floats_content
%             \strc_floats_make_complete_caption}}}%
%    \dostoptagged}

\def\strc_floats_prepare_side_caption
  {\dostarttagged\t!floatcaption\empty
   \edef\p_strc_floats_caption_width{\floatcaptionparameter\c!width}%
   \edef\p_strc_floats_caption_align{\floatcaptionparameter\c!align}%
   \ifx\p_strc_floats_caption_width\v!max
     \strc_floats_prepare_side_caption_max
   \else\ifx\p_strc_floats_caption_width\v!fit
     \strc_floats_prepare_side_caption_fit
   \else
     \strc_floats_prepare_side_caption_width
   \fi\fi
   \dostoptagged}

% these could be \??floatpreparesidecaption

\def\strc_floats_prepare_side_caption_max
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\wd\b_strc_floats_content
      \strc_floats_make_complete_caption}}

\def\strc_floats_prepare_side_caption_fit
  {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax
     \setbox\b_strc_floats_caption\vbox
       {\forgetall % needed?
        \hsize\wd\b_strc_floats_content
        \strc_floats_make_complete_caption}%
   \else
     \setbox\b_strc_floats_caption\hbox to \wd\b_strc_floats_content
       {\hss\hbox{\strc_floats_make_complete_caption}\hss}%
   \fi}

\def\strc_floats_prepare_side_caption_width
  {\setbox\b_strc_floats_caption\vbox
     {\strc_floats_caption_set_align
      \hsize\p_strc_floats_caption_width % \wd\b_strc_floats_content
      \strc_floats_make_complete_caption}}

% % maybe (but then also prepare_page that way):
%
% \installcorenamespace{floatpreparesidecaption}
%
% \def\strc_floats_prepare_side_caption
%   {\dostarttagged\t!floatcaption\empty
%    \edef\p_strc_floats_caption_width{\floatcaptionparameter\c!width}%
%    \edef\p_strc_floats_caption_align{\floatcaptionparameter\c!align}%
%    \expandnamespacemacro\??floatpreparesidecaption\p_strc_floats_caption_width\s!unknown
%    \dostoptagged}
%
% \setvalue{\??floatpreparesidecaption\v!max}%
%   {\setbox\b_strc_floats_caption\vbox
%      {\strc_floats_caption_set_align
%       \hsize\wd\b_strc_floats_content
%       \strc_floats_make_complete_caption}}
%
% \setvalue{\??floatpreparesidecaption\v!fit}%
%   {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax
%      \setbox\b_strc_floats_caption\vbox
%        {\forgetall % needed?
%         \hsize\wd\b_strc_floats_content
%         \strc_floats_make_complete_caption}%
%    \else
%      \setbox\b_strc_floats_caption\hbox to \wd\b_strc_floats_content
%        {\hss\hbox{\strc_floats_make_complete_caption}\hss}%
%    \fi}
%
% \setvalue{\??floatpreparesidecaption\s!unknown}%
%   {\setbox\b_strc_floats_caption\vbox
%      {\strc_floats_caption_set_align
%       \hsize\p_strc_floats_caption_width % \wd\b_strc_floats_content
%       \strc_floats_make_complete_caption}}

\def\strc_floats_locate_side_float#1%
  {\begingroup
   \alignstrutmode\zerocount
   \hsize\d_strc_float_temp_width \forgetall
   \alignedline{\floatparameter\c!location}\v!middle{#1}%
   \endgroup}

\def\strc_floats_build_side_box
  {\let\strc_floats_align_content\relax
   \let\strc_floats_align_caption\relax
   \strc_floats_build_box}

\def\strc_floats_set_box % todo : \global\setbox, currently messy
  {\ifvisible
     \par
     \edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}%
     \ifconditional\c_strc_floats_par_float
       \strc_floats_set_paragraph_variant
     \else
       \strc_floats_set_page_variant
     \fi
     \strc_floats_set_local_dimensions
     \global\advance\totalnoffloats\plusone
     \setbox\floatbox\hbox{\strc_float_save_data\box\floatbox}% still needed? we will do renumbering differently
     \global\floatheight\htdp\floatbox
     \global\floatwidth\wd\floatbox
     \doifnotinset\v!margin\floatlocation % gaat namelijk nog fout
       {\setbox\floatbox\vbox
          {\parindent\zeropoint
           \box\floatbox}}%
     \wd\floatbox\floatwidth
     \ifdim\dimexpr\floatheight+\lineheight\relax<\textheight \else
       \global\floatheight\dimexpr\textheight-\lineheight\relax
       \ht\floatbox\floatheight
       \dp\floatbox\zeropoint
       \showmessage\m!floatblocks{10}{\the\totalnoffloats}%
     \fi
   \fi}

% \def\dooutput{\sidefloatoutput} % redefinition of \dooutput

\definefloat
  [\v!figure]
  [\v!figures]

\definefloat
  [\v!table]
  [\v!tables]

\setupfloat
  [\v!table]
  [\c!frame=\v!off]

\definefloat
  [\v!intermezzo]
  [\v!intermezzi]

\definefloat
  [\v!graphic]
  [\v!graphics]

% float strategy, replaces some of the above macros

\installcorenamespace{floatmethods}

\let\floatmethod      \empty % set by lua
\let\floatlabel       \empty % set by lua
\let\floatcolumn      \empty % set by lua
\let\floatrow         \empty % set by lua
\let\forcedfloatmethod\empty % set by lua

\def\setfloatmethodvariables#1% \floatmethod \floatlabel \floatrow \floatcolumn
  {\ctxcommand{analysefloatmethod("#1")}}

\def\somesomewherefloat[#1]%
  {\page_floats_save_somewhere_float\s!somewhere{#1}}

\def\strc_floats_get_box
  {\ifvisible
%      \let\floatlabel \empty
%      \let\floatcolumn\empty
%      \let\floatrow   \empty
%      \setfloatmethodvariables\floatlocation
     % todo: nog algemeen otr
     \ifdefined\OTRSETsetpreferedcolumnslot
       \OTRSETsetpreferedcolumnslot\floatcolumn\floatrow
     \fi
     \ifcsname\??floatmethods\currentoutputroutine:\floatmethod\endcsname \else
        \let\floatmethod\v!here
     \fi
     \ifx\forcedfloatmethod\empty \else
       \let\floatmethod\forcedfloatmethod
     \fi
     % [] will go
     \edef\floatlocationmethod{\floatmethod,\floatlocation}%
     \csname\??floatmethods\currentoutputroutine:\floatmethod\endcsname
   \fi}

\installcorenamespace{floatsettings}

\unexpanded\def\installfloatmethod#1#2#3% routine keyword handler
  {\setvalue{\??floatmethods#1:#2}{#3}}

\unexpanded\def\handlefloatmethod#1%
  {\csname\??floatmethods\currentoutputroutine:#1\endcsname}

% \unexpanded\def\installfloatmethod#1#2#3% routine keyword handler
%   {\ifcsname\??floatsettings#1:#2\endcsname \else
%      \expandafter\newtoks\csname\??floatsettings#1:#2\endcsname
%    \fi
%    \setvalue{\??floatmethods#1:#2}{#3}}
%
% \unexpanded\def\startfloatmethodsettings#1#2 #3\stopfloatmethodsettings
%   {\csname\??floatsettings#1:#2\endcsname\expandafter{\the\csname\??floatsettings#1:#2\endcsname#3}}
%
% \let\stopfloatmethodsettings\relax
%
% \unexpanded\def\applyfloatmethodsettings#1#2{\the\??floatsettings#1:#2\endcsname}

\definesystemconstant{tblr}
\definesystemconstant{lrtb}
\definesystemconstant{tbrl}
\definesystemconstant{rltb}
\definesystemconstant{btlr}
\definesystemconstant{lrbt}
\definesystemconstant{btrl}
\definesystemconstant{rlbt}
\definesystemconstant{fxtb}
\definesystemconstant{fxbt}
\definesystemconstant{fixd}

\installfloatmethod \s!singlecolumn \v!here        \page_one_place_float_here
\installfloatmethod \s!singlecolumn \v!force       \page_one_place_float_force
\installfloatmethod \s!singlecolumn \v!left        \page_one_place_float_left
\installfloatmethod \s!singlecolumn \v!right       \page_one_place_float_right
\installfloatmethod \s!singlecolumn \v!text        \page_one_place_float_text
\installfloatmethod \s!singlecolumn \v!top         \page_one_place_float_top
\installfloatmethod \s!singlecolumn \v!bottom      \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \v!auto        \page_one_place_float_auto
\installfloatmethod \s!singlecolumn \v!margin      \page_one_place_float_margin
\installfloatmethod \s!singlecolumn \v!opposite    \page_one_place_float_face
\installfloatmethod \s!singlecolumn \v!page        \page_one_place_float_page
\installfloatmethod \s!singlecolumn \v!leftpage    \page_one_place_float_leftpage
\installfloatmethod \s!singlecolumn \v!rightpage   \page_one_place_float_rightpage
\installfloatmethod \s!singlecolumn \v!inmargin    \page_one_place_float_inmargin
\installfloatmethod \s!singlecolumn \v!inleft      \page_one_place_float_leftmargin
\installfloatmethod \s!singlecolumn \v!inright     \page_one_place_float_rightmargin
\installfloatmethod \s!singlecolumn \v!leftmargin  \page_one_place_float_leftmargin
\installfloatmethod \s!singlecolumn \v!rightmargin \page_one_place_float_rightmargin
\installfloatmethod \s!singlecolumn \v!leftedge    \page_one_place_float_leftedge
\installfloatmethod \s!singlecolumn \v!rightedge   \page_one_place_float_rightedge
\installfloatmethod \s!singlecolumn \v!somewhere   \page_one_place_float_somewhere
\installfloatmethod \s!singlecolumn \v!backspace   \page_one_place_float_backspace
\installfloatmethod \s!singlecolumn \v!cutspace    \page_one_place_float_cutspace
\installfloatmethod \s!singlecolumn \s!tblr        \page_one_place_float_top
\installfloatmethod \s!singlecolumn \s!lrtb        \page_one_place_float_top
\installfloatmethod \s!singlecolumn \s!tbrl        \page_one_place_float_top
\installfloatmethod \s!singlecolumn \s!fxtb        \page_one_place_float_top
\installfloatmethod \s!singlecolumn \s!rltb        \page_one_place_float_top
\installfloatmethod \s!singlecolumn \s!btlr        \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \s!lrbt        \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \s!btrl        \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \s!rlbt        \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \s!fxbt        \page_one_place_float_bottom
\installfloatmethod \s!singlecolumn \s!fixd        \page_one_place_float_force

\installfloatmethod \s!multicolumn  \v!here        \page_mul_place_float_here
\installfloatmethod \s!multicolumn  \v!force       \page_mul_place_float_force
%installfloatmethod \s!multicolumn  \v!left
%installfloatmethod \s!multicolumn  \v!right
%installfloatmethod \s!multicolumn  \v!text
\installfloatmethod \s!multicolumn  \v!top         \page_mul_place_float_top
\installfloatmethod \s!multicolumn  \v!bottom      \page_mul_place_float_bottom
%installfloatmethod \s!multicolumn  \v!auto
%installfloatmethod \s!multicolumn  \v!margin
%installfloatmethod \s!multicolumn  \v!opposite
%installfloatmethod \s!multicolumn  \v!page
%installfloatmethod \s!multicolumn  \v!leftpage
%installfloatmethod \s!multicolumn  \v!rightpage
%installfloatmethod \s!multicolumn  \v!inmargin
%installfloatmethod \s!multicolumn  \v!inleft
%installfloatmethod \s!multicolumn  \v!inright
%installfloatmethod \s!multicolumn  \v!leftmargin
%installfloatmethod \s!multicolumn  \v!rightmargin
%installfloatmethod \s!multicolumn  \v!leftedge
%installfloatmethod \s!multicolumn  \v!rightedge
%installfloatmethod \s!multicolumn  \v!somewhere
%installfloatmethod \s!multicolumn  \v!backspace
%installfloatmethod \s!multicolumn  \v!cutspace
%installfloatmethod \s!multicolumn  \s!tblr
%installfloatmethod \s!multicolumn  \s!lrtb
%installfloatmethod \s!multicolumn  \s!tbrl
%installfloatmethod \s!multicolumn  \s!rltb
%installfloatmethod \s!multicolumn  \s!fxtb
%installfloatmethod \s!multicolumn  \s!btlr
%installfloatmethod \s!multicolumn  \s!lrbt
%installfloatmethod \s!multicolumn  \s!btrl
%installfloatmethod \s!multicolumn  \s!rlbt
%installfloatmethod \s!multicolumn  \s!fxbt
%installfloatmethod \s!multicolumn  \s!fixd

\installfloatmethod \s!columnset    \v!here        \page_set_place_float_here
\installfloatmethod \s!columnset    \v!force       \page_set_place_float_force
%installfloatmethod \s!columnset    \v!left
%installfloatmethod \s!columnset    \v!right
%installfloatmethod \s!columnset    \v!text
\installfloatmethod \s!columnset    \v!top         \page_set_place_float_top
\installfloatmethod \s!columnset    \v!bottom      \page_set_place_float_bottom
%installfloatmethod \s!columnset    \v!auto
%installfloatmethod \s!columnset    \v!margin
%installfloatmethod \s!columnset    \v!opposite
\installfloatmethod \s!columnset    \v!page        \page_set_place_float_page
%installfloatmethod \s!columnset    \v!leftpage
%installfloatmethod \s!columnset    \v!rightpage
%installfloatmethod \s!columnset    \v!inmargin
%installfloatmethod \s!columnset    \v!inleft
%installfloatmethod \s!columnset    \v!inright
%installfloatmethod \s!columnset    \v!leftmargin
%installfloatmethod \s!columnset    \v!rightmargin
%installfloatmethod \s!columnset    \v!leftedge
%installfloatmethod \s!columnset    \v!rightedge
%installfloatmethod \s!columnset    \v!somewhere
%installfloatmethod \s!columnset    \v!backspace
%installfloatmethod \s!columnset    \v!cutspace
\installfloatmethod \s!columnset    \s!tblr        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!lrtb        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!tbrl        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!rltb        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!fxtb        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!btlr        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!lrbt        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!btrl        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!rlbt        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!fxbt        \page_set_place_float_slot
\installfloatmethod \s!columnset    \s!fixd        \page_set_place_float_force

%D Local floats:

\installcorenamespace{localfloats}
\installcorenamespace{localfloatstack}

\installsetuponlycommandhandler \??localfloats {localfloats}

\setuplocalfloats
  [%\c!before=\blank,
   %\c!after=\blank,
   \c!inbetween=\blank]

\initializeboxstack\??localfloatstack

\newcount\c_strc_localfloats_n  \let\noflocalfloats\c_strc_localfloats_n

\unexpanded\def\resetlocalfloats
  {\global\c_strc_localfloats_n\zerocount
   \initializeboxstack\??localfloatstack}

\unexpanded\def\somelocalfloat
  {\global\advance\c_strc_localfloats_n\plusone
   \savebox\??localfloatstack{\number\c_strc_localfloats_n}{\box\floatbox}}

\unexpanded\def\getlocalfloats
  {\dorecurse\c_strc_localfloats_n
     {\ifnum\recurselevel=\plusone % 1\relax
        \directlocalfloatsparameter\c!before
      \else
        \directlocalfloatsparameter\c!inbetween
      \fi
      \dontleavehmode\hbox{\foundbox\??localfloatstack\recurselevel}% \restorebox...
      \ifnum\recurselevel=\c_strc_localfloats_n\relax
        \directlocalfloatsparameter\c!after
      \fi}}

\unexpanded\def\flushlocalfloats
  {\getlocalfloats
   \resetlocalfloats}

% \unexpanded\def\getlocalfloat#1%
%   {\normalexpanded{\foundbox{\??localfloatstack}{\number#1}}}% \vbox{\restorebox...}

\unexpanded\def\getlocalfloat#1%
  {\foundbox\??localfloatstack{\number#1}} % \vbox{\restorebox...}

\unexpanded\def\forcelocalfloats
  {\let\forcedfloatmethod\v!local}

\installfloatmethod \s!singlecolumn \v!local \somelocalfloat
\installfloatmethod \s!multicolumn  \v!local \somelocalfloat
\installfloatmethod \s!columnset    \v!local \somelocalfloat

\protect \endinput