strc-flt.mkvi /size: 97 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=strc-flt,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Float Numbering,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D This module will be redone with conditionals and everythings
15
16\writestatus{loading}{ConTeXt Structure Macros / Float Numbering}
17
18\registerctxluafile{strc-flt}{}
19
20\unprotect
21
22% todo: a keyword for this (and then a settings->hash for speed)
23%
24% \setuplayout[width=middle,backspace=3cm]
25%
26% \appendtoks
27%     \settrue\inhibitmargindata
28% \to \everyinsidefloat
29%
30% \starttext
31%     \dorecurse{20}{
32%         \par \inleft{\red\infofont<#1>} \par
33%         \placefigure[leftmargin]{}{\framed[height=1cm,width=2cm]{}}
34%       % \placefigure{#1}{\framed[height=1cm,width=2cm]{}}
35%         \par line #1.1 \par line #1.2 \par
36%     }
37% \stoptext
38
39% todo: delay caption creation and make setups for each method instead
40%       so that we can have a list of methods and redo them as we can
41%       keep the list or even better: recreate it
42%
43% todo: strc_floats_analyze_variables_two could trigger a setup
44%       and we could have nofmethods of them
45%
46% todo: move variables from page-flt to strc-flt
47%
48% todo: p_name etc
49%
50% todo: less globals!
51%
52% todo: do all options in lua
53
54%D This module is being converted into a mkvi one.
55%D
56%D - rename macros
57%D - get rid of dead code
58%D - less gobal mess
59%D - more mkiv-ish
60
61\installcorenamespace{float}
62\installcorenamespace{floatbuilder}
63\installcorenamespace{floatcaption}
64\installcorenamespace{floatframed}
65
66\installframedcommandhandler \??float        {float}        \??float
67\installframedcommandhandler \??floatcaption {floatcaption} \??floatcaption
68\installframedcommandhandler \??floatframed  {floatframed}  \??floatframed
69
70\let\setupfloats  \setupfloat
71\let\setupcaption \setupfloatcaption
72\let\setupcaptions\setupfloatcaption
73
74\unexpanded\def\dohandlenextfloatindent
75  {\useindentnextparameter\floatparameter
76   \dorechecknextindentation}
77
78\setupcaptions
79  [\c!location=\v!bottom,
80   \c!grid=,
81   \c!before=, % not used (yet)
82   \c!inbetween={\blank[\v!medium]},
83   \c!after=, % not used (yet)
84   \c!spacebefore=,
85   \c!spaceinbetween=, % replaces fuzzy inbetween dual usage
86   \c!spaceafter=,
87   \c!width=\v!fit,
88   \c!minwidth=\v!fit, % id est: the width of the floatbox in some cases
89   \c!headstyle=\v!bold,
90   \c!headcolor=,
91   \c!leftmargin=\zeropoint,
92   \c!rightmargin=\zeropoint,
93   \c!outermargin=\zeropoint,
94   \c!innermargin=\zeropoint,
95   \c!setups=,
96   \c!style=\v!normal,
97   \c!color=,
98   \c!textstyle=,
99   \c!textcolor=,
100   \c!align=,
101   \c!number=\v!yes,
102   \c!offset=\v!overlay,
103   \c!frame=\v!off,
104 % \c!expansion=,
105 % \c!prefix=,
106 % \c!prefixconnector=,
107 % \c!way=,
108 % \c!prefixsegments=,
109 % \c!way=,
110 % \c!blockway=,
111 % \c!sectionnumber=,
112 % \c!separator=,
113 % \c!starter=,
114 % \c!stopper=,
115   \c!suffixseparator=, % currently rather hard coded
116   \c!suffix=\floatcaptionsuffix,
117   \c!distance=\emwidth, % plus .5\emwidth minus .25\emwidth
118   \c!conversion=\v!numbers,
119   \c!maxwidth=\hsize,
120   \c!command=]
121
122% we can comment some of these
123
124\setupfloats
125  [\c!location=\v!middle,
126   \c!width=8\lineheight,
127   \c!height=6\lineheight,
128   \c!offset=\v!overlay,
129   \c!frame=\v!off,
130   \c!strut=\v!no,
131   \c!radius=.5\bodyfontsize,
132   \c!corner=\v!rectangular,
133   \c!grid=,
134  %\c!background=,
135  %\c!backgroundcolor=,
136   \c!backgroundoffset=\!!zeropoint,
137  %\c!topframe=,
138  %\c!bottomframe=,
139  %\c!leftframe=,
140  %\c!rightframe=,
141   \c!frameoffset=\!!zeropoint,
142  %\c!before=,
143  %\c!after=,
144   \c!spacebefore=\v!big,
145   \c!spaceafter=\v!big,
146   \c!sidespacebefore=\rootfloatparameter\c!spacebefore,
147   \c!sidespaceafter=\rootfloatparameter\c!spaceafter,
148   \c!sidespaceinbetween=\rootfloatparameter\c!spacebefore,
149   \c!spacebeforeside=, % extra, not part of, can be used to add whitespace before text
150   \c!spaceafterside=,  % idem
151   \c!sidealign=\v!normal,
152   \c!textmethod=\ifgridsnapping2\else0\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) % THIS WILL CHANGE
153   \c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) % THIS WILL CHANGE
154   \c!indentnext=\v!no,
155   \c!margin=\emwidth,
156   \c!method=1,
157   \c!cache=\v!yes, % when no, then intermediate flush
158   \c!leftmargin=\zeropoint,  % displacement in 'normal floats'
159   \c!rightmargin=\zeropoint, % idem
160   \c!innermargin=\zeropoint, % idem
161   \c!outermargin=\zeropoint, % idem
162   \c!leftmargindistance=\zeropoint,
163   \c!rightmargindistance=\floatparameter\c!leftmargindistance,
164   \c!step=\v!small, % the flush side float step (big, medium, small : always depth)
165   \c!ntop=2,
166   \c!nbottom=0,
167   \c!nlines=4, % used?
168   \c!topoffset=\zeropoint,
169   \c!bottomoffset=\zeropoint,
170   \c!freeregion=\v!yes,
171  %\c!local=,
172  %\c!bottombefore=, % e.g. \vfill
173  %\c!bottomafter=,
174  %\c!default=, % default location
175   \c!sidethreshold=.5\strutdp, % set to "old" to check with old method
176   \c!numbering=\v!yes,
177   \c!compress=\v!yes, % when possible pack floats when flushing
178   \c!compressdistance=\emwidth]
179
180\setupfloatframed
181  [\c!frame=\v!off,
182   \c!offset=\v!overlay,
183   \c!strut=\v!no]
184
185\appendtoks
186    \doifelse{\floatparameter\c!compress}\v!yes\settrue\setfalse\c_page_floats_pack_flushed
187    \d_page_floats_compress_distance\floatparameter\c!compressdistance\relax
188\to \everysetupfloat
189
190%D We need to do it again here:
191
192\setupfloat
193  [\c!compress=\v!yes, % when possible pack floats when flushing
194   \c!compressdistance=\emwidth]
195
196%D Individial settings:
197
198\installcounterassociation{floatcaption}
199
200\appendtoks
201    \let\currentfloat\currentfloatcaption % ?
202    \synchronizefloatcaptioncounters
203\to \everysetupfloatcaption
204
205\appendtoks
206    \let\currentfloat\currentfloatcaption % ?
207    \synchronizefloatcaptioncounters
208\to \everydefinefloatcaption
209
210%D Definitions:
211
212\let\strc_floats_define_saved\definefloat
213
214\unexpanded\overloaded\def\definefloat
215  {\dotripleempty\strc_floats_define}
216
217\def\strc_floats_define[#1][#2][#3]% name+plural+parent | name+parent+settings
218  {\ifthirdargument
219     \doifassignmentelse{#3}
220       {\strc_floats_define_b[#1][#2][#3]}%
221       {\strc_floats_define_a[#1][#2][#3]}%
222   \else\ifsecondargument
223     \doifelsecommandhandler\??float{#2}%
224       {\strc_floats_define_a[#1][#1][#2]}%
225       {\strc_floats_define_c[#1][#2]}%
226   \else
227     \strc_floats_define_c[#1][#1]%
228   \fi\fi}
229
230\def\strc_floats_define_a[#1][#2][#3]% name names parent
231  {\definefloatcaption[#1][#3]%
232   \definefloatframed[#1][#3]%
233   \definecounter[#1][#3]%
234   \definelist[#1][#3]%
235   \copylabeltext[#1=#3]%
236   \strc_floats_define_saved[#1][#3]%
237   \strc_floats_define_commands{#1}{#2}}
238
239\def\strc_floats_define_b[#1][#2][#3]% name parent settings
240  {\definefloatcaption[#1][#2]%
241   \definefloatframed[#1][#2]%
242   \definecounter[#1][#2]%
243   \definelist[#1][#2]%
244   \copylabeltext[#1=#2]%
245   \strc_floats_define_saved[#1][#2][#3]%
246   \strc_floats_define_commands{#1}{#1}}
247
248\def\strc_floats_define_c[#1][#2]% name names
249  {\registerfloatcaptioncounter{#1}%
250   \definefloatcaption[#1]%
251   \definefloatframed[#1]%
252   \definecounter[#1]%
253   \definelist[#1]%
254   \presetlabeltext[#1=\Word{#1}~]%
255   \presetheadtext[#2=\Word{#2}]%
256   \strc_floats_define_saved[#1]%
257   \strc_floats_define_commands{#1}{#2}}
258
259\def\strc_floats_define_commands#1#2%
260  {\setuvalue         {\e!place\e!listof#2}{\dodoubleempty\strc_lists_place[#1]}% call will change
261   \setuvalue      {\e!complete\e!listof#2}{\dotripleempty\strc_lists_complete_indeed[#1][#2]}% call will change
262   \setuevalue                 {\e!place#1}{\strc_floats_place{#1}}%
263   \setuevalue         {\e!start\e!place#1}{\strc_floats_start_place{#1}}%
264   \setuevalue          {\e!stop\e!place#1}{\strc_floats_stop_place}%
265   \setuevalue          {\e!start#1\e!text}{\strc_floats_start_text{#1}}%
266   \setuevalue           {\e!stop#1\e!text}{\strc_floats_stop_text}%
267   % these will become obsolete:
268   \setuevalue               {\e!reserve#1}{\strc_floats_reserve{#1}}%
269   \setuevalue{\e!start\e!reserve#1\e!text}{\strc_floats_start_reserve_text{#1}}%
270   \setuevalue {\e!stop\e!reserve#1\e!text}{\strc_floats_stop_reserve_text}}
271
272%D Fallback float body:
273
274\unexpanded\def\strc_floats_place_empty_box % \inheritedfloatframed
275  {\framed
276     [\c!frame=\v!on,
277      \c!width=\rootfloatparameter\c!width,
278      \c!height=\rootfloatparameter\c!height,
279      \c!location=\v!normal,
280      \c!offset=\rootfloatparameter\c!offset]%
281     {\getmessage\m!floatblocks{12}\empty}}
282
283%D Data. We can generalize this to lists.
284
285\newif\ifnofloatcaption
286\newif\ifnofloatnumber
287\newif\ifemptyfloatcaption
288
289\installstructurelistprocessor\s!float{\usestructurelistprocessor{number+title}}
290
291\unexpanded\def\thecurrentfloatnumbersuffix
292  {\doifsomething{\floatcaptionparameter\c!suffix}
293     {\floatcaptionparameter\c!suffixseparator
294      \floatcaptionparameter\c!suffix
295      \floatcaptionparameter\c!suffixstopper}}
296
297\unexpanded\def\thecurrentfloatnumber
298  {\ifnofloatcaption \else \ifnofloatnumber \else
299     \ifx\currentfloatnumber\relax\else
300       \namedtaggedlabeltexts
301         \t!floatlabel \currentfloat
302         \t!floatnumber\currentfloat
303         {\begstrut
304          \floatcaptionparameter\c!numbercommand
305            {\clf_savedlistprefixednumber{\currentfloat}\currentfloatnumber\relax
306             \thecurrentfloatnumbersuffix}%
307          \endstrut}%
308     \fi
309   \fi \fi}
310
311\unexpanded\def\thecurrentfloatcaption
312  {\ifnofloatcaption \else \ifemptyfloatcaption \else
313     \ifx\currentfloatnumber\relax\else
314       \dostarttagged\t!floattext\empty
315       \begstrut
316       \floatcaptionparameter\c!textcommand
317         {\clf_savedlisttitle{\currentfloat}\numexpr\currentfloatnumber\relax}%
318       \endstrut
319       \dostoptagged
320     \fi
321   \fi \fi}
322
323%D Captions.
324
325\let\floatcaptionsuffix\empty % an optional suffix
326\let\floatcaptionnumber\empty % a logical counter
327
328% For a while these were placeholders:
329%
330%D \starttyping
331%D \unexpanded\def\placefloatcaption{\dodoubleempty\strc_floats_place_caption}
332%D \unexpanded\def\setfloatcaption  {\dodoubleempty\strc_floats_set_caption}
333%D
334%D \def\strc_floats_place_caption[#tag][#reference]#caption{[not supported]}
335%D \def\strc_floats_set_caption  [#tag][#reference]#caption{[not supported]}
336%D
337%D \unexpanded\def\placefloatcaptiontext     [#tag]{[not suported yet]}
338%D \unexpanded\def\placefloatcaptionnumber   [#tag]{[not suported yet]}
339%D \unexpanded\def\placefloatcaptionreference[#tag]{[not suported yet]}
340%D \stoptyping
341%D
342%D because in \MKII\ we had:
343%D
344%D \starttyping
345%D \let\placefloatlabel         \placefloatcaption
346%D \let\placefloatlabeltext     \placefloatcaptiontext
347%D \let\placefloatlabelreference\placefloatcaptionreference
348%D \stoptyping
349%D
350%D But as it was never advertised we don't provide it in \MKIV. However, at some
351%D point HvdM wanted this:
352%D
353%D \starttyping
354%D \placefigure                     {labeltext-1}  {\externalfigure[figure-1]}
355%D \placefloatcaption[figure][title={labeltext-2}]  \externalfigure[figure-2]
356%D \placefigure                     {labeltext-3}  {\externalfigure[figure-3]}
357%D \stoptyping
358%D
359%D So there you have it:
360
361\unexpanded\def\placefloatcaption
362  {\dotripleempty\strc_floats_place_caption}
363
364\def\strc_floats_place_caption[#category][#settings][#userdata]%
365  {\ifsecondargument
366     % we need at least a category and title
367     \dontleavehmode
368     \bgroup
369     \edef\currentfloat{#category}%
370     \let\currentfloatcaption\currentfloat
371     \resetfloatcaptionparameter\c!reference
372     \resetfloatcaptionparameter\c!title
373     \resetfloatcaptionparameter\c!marking
374     \resetfloatcaptionparameter\c!list
375     \resetfloatcaptionparameter\c!bookmark
376     \setupcurrentfloatcaption[#settings]%
377     \edef\currentfloatcounter{\namedcounterparameter\currentfloat\s!name}%
378     \iftrialtypesetting\strc_counters_save\currentfloatcounter\fi
379     \strc_counters_increment\currentfloatcounter
380     \strc_counters_register_component
381       \s!float
382       \setupcurrentfloatcaption
383       \floatcaptionparameter
384       \detokenizedfloatcaptionparameter
385       \relax
386       \relax
387       \relax
388       [\s!name=\currentfloat,
389        \s!counter=\currentfloatcounter,%
390        \s!hascaption=\v!yes,%
391        \s!hasnumber=\v!yes,%
392        \s!hastitle=\v!yes]%
393       [#userdata]%
394     \glet\previousfloatnumber    \m_strc_counters_last_registered_index
395     \glet\currentfloatnumber     \m_strc_counters_last_registered_index
396     \glet\currentfloatattribute  \m_strc_counters_last_registered_attribute
397     \glet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
398     %
399   % \iflocation
400   %    \c_attr_destination\currentfloatattribute\relax
401   % \fi
402     \currentfloatsynchronize
403     \strc_floats_make_complete_caption
404     %
405     \iftrialtypesetting\strc_counters_restore\currentfloatcounter\fi
406     \egroup
407   \fi}
408
409\newbox  \b_strc_floats_caption
410\newbox  \b_strc_floats_content
411\newdimen\d_strc_floats_caption_height
412\newdimen\d_strc_floats_caption_depth
413
414\def\strc_floats_make_complete_caption
415  {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}%
416   \strc_floats_make_complete_caption_before
417   \synchronizedisplaydirection % temp hack, till we have a proper model
418   \noindent
419   \gdef\lastcaptiontag{\strut\thecurrentfloatnumber}% was xdef ... needs checking
420   \begingroup
421     \ifnofloatcaption
422       \global\d_strc_floats_caption_height\zeropoint
423       \global\d_strc_floats_caption_depth \zeropoint
424     \else
425       \usefloatcaptionstyleandcolor\c!style\c!color
426       \clf_doifelselisthastitle{\currentfloat}\numexpr\currentfloatnumber\relax
427         \donothing
428         \emptyfloatcaptiontrue
429       \ifnofloatnumber \else \ifnofloatcaption \else
430         \ifemptyfloatcaption
431           \hbox{\usefloatcaptionstyleandcolor\c!headstyle\c!headcolor\thecurrentfloatnumber}%
432         \else
433           \doifelsenothing{\floatcaptionparameter\c!spaceinbetween}
434             {\scratchskip\floatcaptionparameter\c!distance\relax
435              \setbox\scratchbox\hbox
436                {\usefloatcaptionstyleandcolor\c!headstyle\c!headcolor
437                 \thecurrentfloatnumber
438                 \floatcaptionparameter\c!headseparator
439                 \dotfskip\scratchskip}%
440              \doifelse{\floatcaptionparameter\c!hang}\v!yes
441                 {\leftskip\wd\scratchbox
442                  \llap{\box\scratchbox}}
443                 {\unhbox\scratchbox}%
444               \emergencystretch.5\scratchskip}
445             {\hbox{\usefloatcaptionstyleandcolor\c!headstyle\c!headcolor\thecurrentfloatnumber}%
446              \blank[\floatcaptionparameter\c!spaceinbetween]}%
447         \fi
448       \fi \fi
449       \usefloatcaptionstyleandcolor\c!textstyle\c!textcolor
450       \global\d_strc_floats_caption_height\strutheight
451       \global\d_strc_floats_caption_depth \strutdepth
452       \thecurrentfloatcaption\endgraf
453     \fi
454   \endgroup
455   \strc_floats_make_complete_caption_after
456   \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}}
457
458%let\strc_floats_make_complete_caption_before\relax
459\let\strc_floats_make_complete_caption_after \relax
460
461\def\strc_floats_make_complete_caption_before
462  {\doifelseframed\floatcaptionparameter\strc_floats_make_complete_caption_before_indeed\relax}
463
464\def\strc_floats_make_complete_caption_before_indeed
465  {\edef\m_strc_align{\floatcaptionparameter\c!align}%
466   \edef\m_strc_strut{\floatcaptionparameter\c!strut}%
467   \letfloatcaptionparameter\c!align\v!normal
468   \letfloatcaptionparameter\c!strut\v!no
469   \inheritedfloatcaptionframed
470   \bgroup
471   \letfloatcaptionparameter\c!align\m_strc_align
472   \letfloatcaptionparameter\c!strut\m_strc_strut
473   \let\strc_floats_make_complete_caption_after\egroup}
474
475% \definefloat  [figure-1] [figure]
476% \definefloat  [figure-2] [figure]
477% \setupfloat   [figure-1] [location=left,leftmargin=10mm]
478% \setupfloat   [figure-2] [location=left,leftmargin=-5mm]
479% \setupcaption [figure-1] [align=flushleft]
480% \setupcaption [figure-2] [align=flushleft,leftmargin=15mm]
481%
482% \startsetups somefigure
483%     \ifdim\wd\nextbox>\textwidth
484%         \placefloat[figure-2][][]{}{\box\nextbox}
485%     \else
486%         \placefloat[figure-1][][]{}{\box\nextbox}
487%     \fi
488% \stopsetups
489%
490% \unexpanded\def\setupswithbox[#1]{\dowithnextbox{\setups[#1]}\vbox}
491%
492% test \setupswithbox[somefigure]{\framed[width=3cm]                         {}} test
493% test \setupswithbox[somefigure]{\framed[width=\dimexpr\textwidth+3cm\relax]{}} test
494
495% temporary removed ... was not applied systematically
496%
497% \def\dosetcaptionthings
498%   {\usesetupsparameter\floatcaptionparameter}
499
500\def\strc_floats_check_caption_content
501  {\ifnofloatcaption
502   \else
503     \setbox\b_strc_floats_caption\hbox
504       {\settrialtypesetting
505        \notesenabledfalse
506        \strc_floats_make_complete_caption}%
507     % new, \placefigure{\xmlfirst{#1}{somecaption}}{} passes earlier empty check
508     % so here we misuse the scratch box; actually this means that the previous
509     % test can go away (some day, when i redo this module)
510     \ifzeropt\wd\b_strc_floats_caption
511       \global\emptyfloatcaptiontrue
512       \ifnofloatnumber
513         \global\nofloatcaptiontrue
514       \fi
515     \else
516       \global\emptyfloatcaptionfalse
517       \setbox\b_strc_floats_caption\hpack{\hskip\leftskip\box\b_strc_floats_caption}%
518     \fi
519   \fi}
520
521%D We can do this ...
522%D
523%D \starttyping
524%D \newcount\c_strc_floats_n
525%D
526%D \definedataset[\s!float][\c!delay=\v!yes]
527%D
528%D \let\strc_float_realpage\realpageno
529%D
530%D \def\strc_float_save_data
531%D   {\setdataset[\s!float][\number\c_strc_floats_n][]}
532%D
533%D \def\strc_float_load_data % precedes save !
534%D   {\global\advance\c_strc_floats_n\plusone
535%D    \xdef\strc_float_realpage{\datasetvariable\s!float{\number\c_strc_floats_n}\s!page}%
536%D    \ifx\strc_float_realpage\empty
537%D      \glet\strc_float_realpage\realpageno % \realfolio
538%D    \fi}
539%D \stoptyping
540%D
541%D ... but this is more efficient:
542
543\definepagestate[\s!float][\c!delay=\v!yes]
544
545\newcount\c_strc_floats_n
546
547\let\strc_float_realpage\realpageno
548
549\def\strc_float_save_data
550  {\setpagestate[\s!float][\number\c_strc_floats_n]}
551
552\def\strc_float_load_data % precedes save !
553  {\global\advance\c_strc_floats_n\plusone
554   \xdef\strc_float_realpage{\pagestaterealpage\s!float{\number\c_strc_floats_n}}%
555   \ifx\strc_float_realpage\empty
556    \glet\strc_float_realpage\realpageno % \realfolio
557   \fi}
558
559%D test case:
560%D
561%D \starttyping
562%D \setupfloat[figure][criterium=\marginwidth,fallback=bottom]
563%D \dorecurse{3}{
564%D     \chapter{test}
565%D     \placefigure[bottom]{1}{\framed{bottom}}
566%D     test
567%D     \placetable[bottom]{1}{\framed{table}}
568%D     test
569%D     \placetable{2}{\framed{table}}
570%D     test
571%D     \placefigure[left]{2}{\framed{left but way too wide}}
572%D     \input tufte
573%D     \placefigure[left]{3}{\framed{left but ok}}
574%D     \input tufte }
575%D \stoptyping
576
577% A complication is that we may have to handle a pagebreak
578% first, which in turn may issue a (postponed) float.
579% Therefore we may not trust on variable assignments before
580% we're really dealing with the float. Some day I'll root out
581% the global settings.
582
583\let\lastplacedfloat\empty
584
585\def\strc_floats_set_current_tag#tag%
586  {\edef\currentfloat{#tag}%
587   \ifx\currentfloat\empty
588     \let\currentfloat\v!figure % a bit of a hack
589   \fi
590   \doifelsecommandhandler\??float\currentfloat
591     \donothing
592     {\writestatus\m!floatblocks{unknown float type '\currentfloat'}%
593      \let\currentfloat\v!figure}% also a hack
594   \glet\lastplacedfloat\currentfloat
595   \let\m_strc_floats_saved_userdata\empty
596   \let\currentfloatcaption\currentfloat}
597
598\let\askedfloatmethod \empty
599\let\askedfloatoptions\empty
600
601\def\strc_floats_reset_variables
602  {\global\emptyfloatcaptionfalse
603   \global\nofloatcaptionfalse
604   \global\nofloatnumberfalse
605   \glet\askedfloatmethod \empty
606   \glet\askedfloatoptions\empty}
607
608% place
609
610\let\floatlabel         \empty
611\let\floatcolumn        \empty
612\let\floatrow           \empty
613\let\floatlocation      \empty
614\let\floatlocationmethod\empty
615
616\def\strc_floats_analyze_location
617  {% more will be moved here
618   \let\floatlabel \empty
619   \let\floatcolumn\empty
620   \let\floatrow   \empty
621   %
622   \edef\floatcaptionlocation{\floatcaptionparameter\c!location}%
623   %
624   \setfloatmethodvariables\floatlocation}
625
626\unexpanded\def\strc_floats_place#tag%
627  {\flushnotes
628   \page_otr_command_flush_side_floats % here !
629   \strc_floats_begin_group
630   \strc_floats_set_current_tag{#tag}%
631   \dodoubleempty\strc_floats_place_indeed}
632
633\newtoks\c_floats_every_table_float
634
635\appendtoks
636    \edef\floatlocation{\v!force,\v!always,\floatlocation}%
637    \setupfloat[\c!spacebefore=\v!none,\c!spaceafter=\v!none]%
638\to \c_floats_every_table_float
639
640\ifdefined\dotagregisterfloat \else \let\dotagregisterfloat\gobbletwoarguments \fi
641
642\def\strc_floats_place_indeed[#location][#reference]#caption%
643  {\strc_floats_reset_variables
644   \xdef\askedfloatoptions{#location}%
645   \edef\floatlocation{#location}%
646   \ifx\floatlocation\empty
647     \edef\floatlocation{\floatparameter\c!default}% beware of a clash between alignment locations
648   \fi
649   \ifintable
650     \the\c_floats_every_table_float
651   \fi
652   \strc_floats_analyze_location
653   % todo: use \lets
654   \setupcurrentfloatcaption[\c!reference={#reference},\c!title={#caption},\c!marking=,\c!list=,\c!bookmark=]%
655   \doifelseinset\v!split\floatlocation\strc_floats_place_next_box_split\strc_floats_place_next_box_normal}
656
657\unexpanded\def\placefloat
658  {\flushnotes
659   \page_otr_command_flush_side_floats % here !
660   \strc_floats_begin_group
661   \dotripleempty\strc_floats_place_float}
662
663\def\strc_floats_place_float[#tag]%
664  {\strc_floats_set_current_tag{#tag}%
665   \strc_floats_place_indeed}
666
667% start-stop
668
669% \startplacefigure[title=oeps][subtitle=whatever]
670%     \framed[width=10cm,height=5cm]{\floatuserdataparameter{subtitle}}
671% \stopplacefigure
672
673\installcorenamespace{floatuserdata}
674
675\installsetuponlycommandhandler \??floatuserdata {floatuserdata}
676
677\let\m_strc_floats_saved_userdata\empty % todo: reset this in non start|stop cases
678
679\unexpanded\def\strc_floats_start_place#tag%
680  {\flushnotes
681   \page_otr_command_flush_side_floats % here !
682   \strc_floats_begin_group
683   \strc_floats_set_current_tag{#tag}%
684   \dodoubleempty\strc_floats_start_place_indeed}
685
686%D We abuse the settings to pick up some float parameters too which makes it
687%D messy.
688
689\def\strc_floats_start_place_indeed[#settings][#userdata]%
690  {\strc_floats_reset_variables
691   % save
692   \edef\m_location    {\floatcaptionparameter\c!location}%
693   \edef\m_topoffset   {\floatcaptionparameter\c!topoffset}%
694   \edef\m_bottomoffset{\floatcaptionparameter\c!bottomoffset}%
695   \edef\m_freeregion  {\floatcaptionparameter\c!freeregion}%
696   % preset
697   \letfloatcaptionparameter        \c!location     \empty
698   \setexpandedfloatcaptionparameter\c!topoffset   {\floatparameter\c!topoffset}%
699   \setexpandedfloatcaptionparameter\c!bottomoffset{\floatparameter\c!bottomoffset}%
700   \setexpandedfloatcaptionparameter\c!freeregion  {\floatparameter\c!freeregion}%
701   \letfloatcaptionparameter        \c!reference    \empty
702   \letfloatcaptionparameter        \c!title        \empty
703   \letfloatcaptionparameter        \c!marking      \empty
704   \letfloatcaptionparameter        \c!list         \empty
705   \letfloatcaptionparameter        \c!bookmark     \empty
706   % pickup
707   \setupcurrentfloatcaption[#settings]%
708   \ifsecondargument
709     \setupcurrentfloatuserdata[#userdata]%
710     \def\m_strc_floats_saved_userdata{#userdata}%
711   \else
712     \let\m_strc_floats_saved_userdata\empty
713   \fi
714   % check
715   \edef\floatlocation{\floatcaptionparameter\c!location}%
716   \ifx\floatlocation\empty
717      \edef\floatlocation{\floatparameter\c!default}%
718   \fi
719   % inherit
720   \setexpandedfloatparameter\c!topoffset   {\floatcaptionparameter\c!topoffset}%
721   \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}%
722   \setexpandedfloatparameter\c!freeregion  {\floatcaptionparameter\c!freeregion}%
723   % restore
724   \letfloatcaptionparameter\c!location    \m_location
725   \letfloatcaptionparameter\c!topoffset   \m_topoffset
726   \letfloatcaptionparameter\c!bottomoffset\m_bottomoffset
727   \letfloatcaptionparameter\c!freeregion  \m_freeregion
728   %
729   \strc_floats_analyze_location
730   \doifelseinset\v!split\floatlocation\strc_floats_place_next_box_split\strc_floats_place_next_box_normal
731   \bgroup
732   \ignorespaces}
733
734\unexpanded\def\strc_floats_stop_place
735  {\removeunwantedspaces
736   \egroup}
737
738\unexpanded\def\startplacefloat
739  {\flushnotes
740   \page_otr_command_flush_side_floats % here !
741   \strc_floats_begin_group
742   \dotripleempty\strc_floats_start_place_float}
743
744\def\strc_floats_start_place_float[#tag]%
745  {\strc_floats_set_current_tag{#tag}%
746   \strc_floats_start_place_indeed}
747
748\let\stopplacefloat\strc_floats_stop_place
749
750% reserve
751
752\unexpanded\def\strc_floats_reserve#tag%
753  {\flushnotes
754   \page_otr_command_flush_side_floats % here !
755   \strc_floats_begin_group
756   \strc_floats_set_current_tag{#tag}%
757   \dotripleempty\strc_floats_reserve_indeed}
758
759\def\strc_floats_reserve_indeed[#settings][#location][#reference]#caption% maybe check for #settings
760  {\strc_floats_place_indeed[#location][#reference]{#caption}{\strc_floats_reserve_box{#settings}}}
761
762\def\strc_floats_reserve_box#settings%
763  {\begingroup
764   \setupcurrentfloat[\c!frame=\v!on,#settings]%
765   \inheritedfloatframed{}%
766   \endgroup}
767
768% text
769
770\unexpanded\def\strc_floats_start_text#tag%
771  {\flushnotes      % Here indeed?
772   \page_otr_command_flush_side_floats % Here indeed?
773   \strc_floats_begin_text_group
774   \strc_floats_set_current_tag{#tag}%
775   \dodoubleempty\strc_floats_start_text_indeed}
776
777\def\strc_floats_start_text_indeed[#location][#reference]%
778  {\strc_floats_place_indeed[\v!text,#location,\v!left][#reference]}
779
780\unexpanded\def\strc_floats_stop_text
781  {\strc_floats_stop_text_indeed}
782
783% reserved text
784
785\unexpanded\def\strc_floats_start_reserve_text#tag%
786  {\flushnotes
787   \page_otr_command_flush_side_floats
788   \strc_floats_begin_text_group
789   \strc_floats_set_current_tag{#tag}%
790   \dotripleempty\strc_floats_start_reserve_text_indeed}
791
792\def\strc_floats_start_reserve_text_indeed[#settings][#location][#reference]#caption%
793  {\strc_floats_place_indeed[\v!text,#location,\v!left][#reference]{#caption}{\strc_floats_reserve_box{#settings}}}
794
795\unexpanded\def\strc_floats_stop_reserve_text
796  {\strc_floats_stop_text_indeed}
797
798% special hack
799
800\def\strc_floats_begin_group     {\begingroup}
801\def\strc_floats_end_group       {\carryoverpar\endgroup}
802\def\strc_floats_end_split_group {\endgroup}
803\def\strc_floats_begin_text_group{\begingroup\let\strc_floats_end_group\relax}
804\def\strc_floats_end_text_group  {\endgroup}
805
806% implementation
807
808%setnewconstant\c_page_one_float_method  \zerocount % 0=raw 1=safe (.99) 2=tight (-1pt) / belongs in page-one
809\setnewconstant\c_strc_floats_rotation   \zerocount % 0 90 180 270
810\newconditional\c_strc_floats_par_float
811
812\ifdefined\page_margin_strc_floats_before    \else \let\page_margin_strc_floats_before   \relax \fi
813\ifdefined\page_margin_strc_floats_set_hsize \else \let\page_margin_strc_floats_set_hsize\relax \fi
814
815\def\flushfloatslist
816  {\v!left,\v!right,\v!inner,\v!outer,%
817   \v!backspace,\v!cutspace,%
818   \v!inleft,\v!inright,\v!inmargin,%
819   \v!leftmargin,\v!rightmargin,\v!leftedge,\v!rightedge,%
820   \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,%
821   \v!text,\v!opposite}% \v!page
822
823\unexpanded\def\strc_floats_place_next_box_split
824  {\let\splitfloatfinalizer\strc_floats_end_split_group
825   \let\strc_floats_end_group\relax
826   \splitfloat{\strc_floats_place_next_box_normal}}
827
828\unexpanded\def\strc_floats_place_next_box_normal
829  {\ifconditional\c_page_floats_some_waiting
830     % this was \checkwaitingfloats spread all over
831     \doifelseinset\v!always\floatlocation
832       {\showmessage\m!floatblocks5\empty}
833       {\doifelsecommon\floatlocation\flushfloatslist\page_otr_command_flush_floats\donothing}%
834     % but which should be done before using box \floatbox
835   \fi
836   \page_margin_strc_floats_before % todo: each float handler gets a before
837   \global\insidefloattrue
838   \dostarttaggedchained\t!float\currentfloat\??float
839   \page_margin_strc_floats_set_hsize % todo: each float handler gets a set_hsize
840   \the\everyinsidefloat
841   \strc_floats_analyze_variables_one
842   \dostarttagged\t!floatcontent\empty
843   \dowithnextboxcontent
844     {\strc_floats_set_local_hsize
845      \floatparameter\c!inner
846      \postponenotes} % new
847     {\page_postprocessors_linenumbers_box\nextbox % for aditya
848      \dostoptagged
849      \strc_floats_finish_placement}
850     \vbox}
851
852%D \starttyping
853%D \definefloat
854%D   [one] [figure]
855%D   [default=right,
856%D    rightmargindistance=-20cm,
857%D    criterium=129pt,
858%D    fallback=rightmargin]
859%D
860%D \definefloat
861%D   [two] [figure]
862%D   [default=right,
863%D    rightmargindistance=-20cm,
864%D    criterium=129pt,
865%D    fallback=three]
866%D
867%D \definefloat
868%D   [three] [figure]
869%D   [default=rightmargin,
870%D    rightmargindistance=0cm]
871%D
872%D \placefloat[one]{}{\blackrule[width=30pt]}  \samplefile{tufte}
873%D \placefloat[one]{}{\blackrule[width=60pt]}  \samplefile{tufte}
874%D \placefloat[one]{}{\blackrule[width=90pt]}  \samplefile{tufte}
875%D \placefloat[one]{}{\blackrule[width=130pt]} \samplefile{tufte}
876%D \placefloat[two]{}{\blackrule[width=130pt]} \samplefile{tufte}
877%D \stoptyping
878
879\def\strc_floats_finish_placement
880  {\doifsomething{\floatparameter\c!criterium}
881     {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax
882        \edef\forcedfloatmethod{\floatparameter\c!fallback}%
883        \ifx\forcedfloatmethod\empty \else
884          \doifelsecommandhandler\??float\forcedfloatmethod
885            {\let\currentfloat\forcedfloatmethod
886             \edef\floatlocation{\floatparameter\c!default}%
887             \let\forcedfloatmethod\floatlocation}
888            \donothing
889        \fi
890        \ifx\forcedfloatmethod\empty
891          \let\forcedfloatmethod\v!here
892        \fi
893      \fi}%
894   \strc_floats_check_extra_actions
895   \strc_floats_analyze_variables_two
896   \strc_floats_place_packaged_boxes
897   \dotagregisterfloat\askedfloatoptions\askedfloatmethod
898   \dostoptagged % tricky .... needs checking
899   % we need to carry over the par because of side floats
900   \global\d_page_sides_downshift \zeropoint
901   \global\d_page_sides_extrashift\zeropoint
902   \ifconditional\c_strc_floats_par_float
903     \doifinset\v!reset\floatlocation\page_sides_forget_floats
904     \doinhibitblank
905   \fi
906   \strc_floats_end_group}
907
908% nicer is a bunch of states and one loop that sets those states
909
910\newdimen\d_strc_floats_top
911\newdimen\d_strc_floats_bottom
912\newdimen\d_strc_floats_overflow
913
914% \def\strc_floats_calculate_skip#target#skip%
915%   {\begingroup
916%    \edef\askedfloatskip{\rootfloatparameter#skip}%
917%    \ifx\askedfloatskip\empty
918%      \global#target\zeropoint
919%    \else\ifx\askedfloatskip\v!none
920%      \global#target\zeropoint
921%    \else
922%      \setbox\scratchbox\vbox{\whitespace\blank[\askedfloatskip]}% todo: move whitespace inside blank
923%      \global#target\ht\scratchbox
924%    \fi\fi
925%    \endgroup}
926
927\def\strc_floats_calculate_skip#target#skip%
928  {\begingroup
929   \edef\p_blank{\rootfloatparameter#skip}%
930   \ifx\p_blank\v!nowhite
931     \edef\p_blank{-\v!white}%
932   \fi
933   \prerollblank[\p_blank]%
934   \global#target\prerolledblank
935   \endgroup}
936
937\def\strc_floats_analyze_variables_two
938  {\ifinsidecolumns
939     \global\setfalse\c_strc_floats_par_float
940   \else
941     \doifelsecommon\floatlocation\flushfloatslist
942       {\global\settrue \c_strc_floats_par_float}%
943       {\global\setfalse\c_strc_floats_par_float}%
944   \fi
945   % variable initializations
946   \global\d_page_sides_shift       \zeropoint
947   \global\d_page_sides_maximum     \zeropoint
948   \global\c_page_sides_align       \zerocount
949   \global\c_page_sides_tolerance   \zerocount
950   \global\c_page_sides_skipmode    \zerocount
951   \global\c_strc_floats_rotation   \zerocount
952   \global\d_page_sides_margin      \floatparameter\c!margin
953   \global\d_page_sides_leftshift   \floatparameter\c!leftmargindistance
954   \global\d_page_sides_rightshift  \floatparameter\c!rightmargindistance
955   \global\d_page_sides_topoffset   \floatparameter\c!topoffset
956   \global\d_page_sides_bottomoffset\floatparameter\c!bottomoffset
957   \global\c_page_sides_method      \floatparameter\c!sidemethod
958   \global\c_page_one_float_method  \floatparameter\c!textmethod
959   \global\c_page_floats_n_of_top   \rootfloatparameter\c!ntop
960   \global\c_page_floats_n_of_bottom\rootfloatparameter\c!nbottom
961   \global\d_strc_floats_overflow   \zeropoint
962   \ifconditional\c_strc_floats_par_float
963     \global\d_strc_floats_top        \zeropoint
964     \global\d_strc_floats_bottom     \zeropoint
965     \strc_floats_calculate_skip\d_page_sides_topskip   \c!sidespacebefore
966     \strc_floats_calculate_skip\d_page_sides_bottomskip\c!sidespaceafter
967     \strc_floats_calculate_skip\d_page_sides_midskip   \c!sidespaceinbetween
968     \strc_floats_calculate_skip\d_strc_floats_top      \c!spacebeforeside
969     \strc_floats_calculate_skip\d_strc_floats_bottom   \c!spaceafterside
970   \else
971     \global\d_page_sides_topskip     \zeropoint
972     \global\d_page_sides_bottomskip  \zeropoint
973     \strc_floats_calculate_skip\d_strc_floats_top   \c!spacebefore
974     \strc_floats_calculate_skip\d_strc_floats_bottom\c!spaceafter
975   \fi
976   % keyword handling
977   \ifconditional\c_strc_floats_par_float
978     \processaction
979       [\floatparameter\c!sidealign]
980       [\v!height=>\global\c_page_sides_align\plusone  ,%
981          \v!line=>\global\c_page_sides_align\plustwo  ,% (***)
982         \v!depth=>\global\c_page_sides_align\plusthree,%
983          \v!grid=>\global\c_page_sides_align\plusfour ,%
984      \v!halfline=>\global\c_page_sides_align\plusfive ]%
985     \ifcase\c_page_sides_align\relax % todo: optie v!lokaal => \else
986       \doifinset\v!height  \floatlocation{\global\c_page_sides_align\plusone  }%
987       \doifinset\v!line    \floatlocation{\global\c_page_sides_align\plustwo  }%
988       \doifinset\v!depth   \floatlocation{\global\c_page_sides_align\plusthree}%
989       \doifinset\v!grid    \floatlocation{\global\c_page_sides_align\plusfour }%
990       \doifinset\v!halfline\floatlocation{\global\c_page_sides_align\plusfive }% meant for 'none'
991     \fi
992     \doifinset\v!high        \floatlocation{\global\c_page_sides_skipmode \plusone  }%
993     \doifinset\v!low         \floatlocation{\global\c_page_sides_skipmode \plustwo  }%
994     \doifinset\v!fit         \floatlocation{\global\c_page_sides_skipmode \plusthree}%
995     \doifinset\v!tolerant    \floatlocation{\global\c_page_sides_tolerance\plusone  }%
996     \doifinset\v!verytolerant\floatlocation{\global\c_page_sides_tolerance\plustwo  }%
997   \else
998     \processallactionsinset
999       [\floatlocation]%
1000       [ 90=>\global\c_strc_floats_rotation\commalistelement\relax,%
1001        180=>\global\c_strc_floats_rotation\commalistelement\relax,%
1002        270=>\global\c_strc_floats_rotation\commalistelement\relax]%
1003   \fi
1004   \doifelseinset\v!nonumber\floatlocation
1005     {\global\nofloatnumbertrue}%
1006     {\doifelse{\floatcaptionparameter\c!number}\v!yes
1007        {\global\nofloatnumberfalse}%
1008        {\global\nofloatnumbertrue}}%
1009   \doifelseinset\v!none\floatlocation
1010     {\global\nofloatcaptiontrue}%
1011     {\global\nofloatcaptionfalse}%
1012   \doif{\floatcaptionparameter\c!number}\v!none % new
1013     {\global\nofloatcaptiontrue}%
1014   \doifinset\v!effective\floatlocation
1015     {\letfloatparameter       \c!leftmargin \effectiveleftskip
1016      \letfloatparameter       \c!rightmargin\effectiverightskip
1017      \letfloatcaptionparameter\c!leftmargin \effectiveleftskip
1018      \letfloatcaptionparameter\c!rightmargin\effectiverightskip}%
1019   \ifemptyfloatcaption \ifnofloatnumber
1020     \global\nofloatcaptiontrue
1021   \fi \fi}
1022
1023% documenteren in details
1024
1025\def\strc_floats_analyze_variables_one
1026  {\doifelse{\floatparameter\c!local}\v!yes\settrue\setfalse\c_page_floats_center_box_global % fout keyword
1027   \ifconditional\c_page_floats_center_box_global
1028     \settrue\c_page_floats_center_box_local
1029   \else
1030     \doifelseinset\v!local\floatlocation\settrue\setfalse\c_page_floats_center_box_local
1031   \fi
1032   \doifelse{\floatparameter\c!freeregion}\v!yes
1033     \settrue\setfalse\c_strc_floats_mark_as_free
1034   \doifnotcommon{\v!always,\v!here,\v!force}\floatlocation % ! ! ! ! ! !
1035     {\setfalse\c_page_floats_center_box_global
1036      \setfalse\c_page_floats_center_box_local}}
1037
1038\def\naturalfloatheight{\the\naturalfloatwd}
1039\def\naturalfloatwidth {\the\naturalfloatht}
1040\def\naturalfloatdepth {\the\naturalfloatdp}
1041
1042\def\floatcaptionheight{\the\floatcaptionwd}
1043\def\floatcaptionwidth {\the\floatcaptionht}
1044\def\floatcaptiondepth {\the\floatcaptiondp}
1045
1046\newdimen\naturalfloatwd
1047\newdimen\naturalfloatht
1048\newdimen\naturalfloatdp
1049
1050\newdimen\floatcaptionwd
1051\newdimen\floatcaptionht
1052\newdimen\floatcaptiondp
1053
1054\def\strc_floats_set_natural_dimensions#box%
1055  {\global\naturalfloatwd\wd#box\relax
1056   \global\naturalfloatht\ht#box\relax
1057   \global\naturalfloatdp\dp#box\relax}
1058
1059\def\strc_floats_set_caption_dimensions#box%
1060  {\global\floatcaptionwd\wd#box\relax
1061   \global\floatcaptionht\ht#box\relax
1062   \global\floatcaptiondp\dp#box\relax}
1063
1064\def\doifelsemainfloatbody
1065  {\ifinsidesplitfloat
1066     \ifconditional\splitfloatfirstdone
1067       \doubleexpandafter\secondoftwoarguments
1068     \else
1069       \doubleexpandafter\firstoftwoarguments
1070     \fi
1071   \else
1072     \expandafter\firstoftwoarguments
1073   \fi}
1074
1075\let\doifmainfloatbodyelse\doifelsemainfloatbody
1076
1077% todo: optional user pars
1078
1079\let\currentfloatattribute\empty % to be checked
1080
1081\def\floatcaptionattribute
1082  {\iflocation
1083      \ifx\currentfloatattribute\empty
1084        % safeguard, can be samepage too
1085      \else
1086       \ifnofloatcaption
1087       \else
1088         \ifinsidesplitfloat
1089            \ifconditional\splitfloatfirstdone
1090            \else
1091              attr \destinationattribute \currentfloatattribute
1092            \fi
1093         \else
1094           attr \destinationattribute \currentfloatattribute
1095         \fi
1096       \fi
1097     \fi
1098   \fi}
1099
1100\newconditional\usesamefloatnumber
1101
1102% \startplacefigure[location=here,reference=first, title=first, group=alpha,groupsuffix=.a]
1103%     \externalfigure[dummy][height=2cm]
1104% \stopplacefigure
1105% \startplacefigure[location=here,reference=second,title=second,group=alpha,groupsuffix=.b]
1106%     \externalfigure[dummy][height=2cm]
1107% \stopplacefigure
1108%
1109% uses:
1110
1111\def\strc_floats_group_index
1112  {\numexpr\clf_listgroupindex{\currentfloat}{\currentfloatgroup}\relax}
1113
1114\def\strc_floats_place_packaged_boxes
1115  {\expandafter\strc_floats_place_packaged_boxes_indeed\expandafter{\m_strc_floats_saved_userdata}}
1116
1117\def\strc_floats_place_packaged_boxes_indeed#userdata%
1118  {\bgroup
1119   \ifconditional\usesamefloatnumber
1120     \glet\currentfloatnumber     \previousfloatnumber
1121     \glet\currentfloatattribute  \empty
1122     \glet\currentfloatsynchronize\relax
1123   \else
1124     \edef\currentfloatcounter{\namedcounterparameter\currentfloat\s!name}%
1125     \edef\currentfloatgroup  {\floatcaptionparameter\c!group}%
1126     \ifnofloatnumber \else \ifnofloatcaption \else
1127       \ifx\currentfloatgroup\empty
1128         % independent
1129         \iftrialtypesetting\strc_counters_save\currentfloatcounter\fi
1130         \strc_counters_increment\currentfloatcounter
1131       \else\ifcase\strc_floats_group_index
1132         % first in group
1133         \iftrialtypesetting\strc_counters_save\currentfloatcounter\fi
1134         \strc_counters_increment\currentfloatcounter
1135       \else
1136         % next in group
1137       \fi \fi
1138     \fi \fi
1139     % *1* as an alternative we could set counter parameters here if needed
1140     \strc_counters_register_component
1141       \s!float
1142       \setupcurrentfloatcaption
1143       \floatcaptionparameter
1144       \detokenizedfloatcaptionparameter
1145       \relax
1146       \relax
1147       \relax
1148       [\s!name=\currentfloat,% was c!name
1149        \s!counter=\currentfloatcounter,%
1150        \s!hascaption=\ifnofloatcaption \v!no\else\v!yes\fi,%
1151        \s!hasnumber=\ifnofloatnumber   \v!no\else\v!yes\fi,%
1152        \s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi]%
1153       [#userdata]%
1154     \glet\previousfloatnumber    \m_strc_counters_last_registered_index
1155     \glet\currentfloatnumber     \m_strc_counters_last_registered_index
1156     \glet\currentfloatattribute  \m_strc_counters_last_registered_attribute
1157     \glet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize
1158   \fi
1159   %
1160   \iftrialtypesetting\else\global\setfalse\usesamefloatnumber\fi % one shot
1161   % check float box
1162   \strc_floats_set_natural_dimensions\nextbox
1163   \global\setbox\floatbox\vbox{\floatparameter\c!command{\box\nextbox}}% can be anything so no pack
1164   \strc_floats_set_natural_dimensions\floatbox
1165   \ifzeropt\htdp\floatbox
1166     \showmessage\m!floatblocks{11}\empty
1167     \global\setbox\floatbox\vpack
1168       {\dostarttagged\t!floatcontent\empty
1169        \strc_floats_place_empty_box
1170        \dostoptagged}%
1171   \fi
1172   % deal with lack of caption
1173   \global\setbox\floatbox\vpack \floatcaptionattribute
1174     {\doifelsemainfloatbody\currentfloatsynchronize\donothing
1175      \unvbox\floatbox
1176      \ifnofloatcaption
1177        \vss
1178      \fi}% gets rid of the depth (unless tabulate)
1179   \iftrialtypesetting\strc_counters_restore\currentfloatcounter\fi
1180   \egroup
1181   % place the float
1182   \strc_floats_set_box
1183   \strc_floats_get_box
1184   \global\insidefloatfalse}
1185
1186
1187\newdimen\availablefloatwidth
1188\newdimen\availablefloatheight
1189
1190\def\strc_floats_set_local_hsize
1191  {\ifconditional\c_page_floats_center_box_local
1192     % also available check here?
1193     \seteffectivehsize
1194     \hsize\localhsize
1195   \else
1196     \doifinset\v!margin\floatlocation % brr, really needed! see wm will be redone
1197       {\hsize\namedmarginblockparameter\empty\c!width}%
1198   \fi
1199   \edef\p_availablewidth {\floatparameter\c!availablewidth }%
1200   \edef\p_availableheight{\floatparameter\c!availableheight}%
1201   \availablefloatwidth \ifx\p_availablewidth \empty\hsize\else\p_availablewidth \relax\fi
1202   \availablefloatheight\ifx\p_availableheight\empty\vsize\else\p_availableheight\relax\fi}
1203
1204\ifdefined\everyinsidefloat \else \newevery \everyinsidefloat \relax \fi
1205
1206\appendtoks
1207    \everyinsidefloat\emptytoks % in case it's called earlier
1208    \strc_float_load_data
1209\to \everyinsidefloat
1210
1211\def\doifelserightpagefloat
1212  {\ifdoublesided
1213     \ifsinglesided
1214       \doubleexpandafter\firstoftwoarguments
1215     \else
1216       \doubleexpandafter\doifelseoddpagefloat
1217     \fi
1218   \else
1219     \expandafter\firstoftwoarguments
1220   \fi}
1221
1222\def\doifelseoddpagefloat
1223  {\ifodd\purenumber\strc_float_realpage\space
1224     \expandafter\firstoftwoarguments
1225   \else
1226     \expandafter\secondoftwoarguments
1227   \fi}
1228
1229\let\doifrightpagefloatelse\doifelserightpagefloat
1230\let\doifoddpagefloatelse  \doifelseoddpagefloat
1231
1232\appendtoks
1233    \overloaded\frozen\let\rightorleftpageaction\doifelserightpagefloat
1234\to \everyinsidefloat
1235
1236% \let\movesidefloat\gobbleoneargument
1237
1238% new : \place...[leftmargin,-2*line]; we need to catch fxtb:2*3
1239% watch out: line alone aligns on the line ! ! !
1240
1241\unexpanded\def\movesidefloat[#settings]% (-)n*line|x=,y=
1242  {\global\d_page_sides_downshift \zeropoint
1243   \global\d_page_sides_extrashift\zeropoint
1244   \doifelseassignment{#settings}%
1245     {\begingroup
1246      \setupcurrentfloat[\c!x=\zeropoint,\c!y=\zeropoint,#settings]%
1247      \ifgridsnapping
1248        \getnoflines{\floatparameter\c!y}%
1249        \global\d_page_sides_downshift\noflines\lineheight
1250      \else
1251        \global\d_page_sides_downshift\floatparameter\c!y
1252      \fi
1253      \global\d_page_sides_extrashift\floatparameter\c!x
1254      \endgroup}
1255     {\movedownsidefloat[#settings]}}
1256
1257\installcorenamespace{floatmovement}
1258
1259\setvalue{\??floatmovement \v!line}{\strc_floats_move_down_line+}
1260\setvalue{\??floatmovement+\v!line}{\strc_floats_move_down_line+}
1261\setvalue{\??floatmovement-\v!line}{\strc_floats_move_down_line-}
1262\setvalue{\??floatmovement \v!hang}{\strc_floats_move_down_hang\plusone}
1263\setvalue{\??floatmovement+\v!hang}{\strc_floats_move_down_hang\plusone}
1264\setvalue{\??floatmovement-\v!hang}{\strc_floats_move_down_hang\minusone}
1265
1266\setvalue{\??floatmovement-2*\v!line}{\strc_floats_move_down_line{-2}}
1267\setvalue{\??floatmovement+2*\v!line}{\strc_floats_move_down_line{2}}
1268\setvalue{\??floatmovement 2*\v!line}{\strc_floats_move_down_line{2}}
1269
1270\unexpanded\def\installfloatmovement#1#2{\setvalue{\??floatmovement#1}{#2}}
1271
1272\def\strc_floats_move_down#setting%
1273  {\begincsname\??floatmovement#setting\endcsname}
1274
1275\def\strc_floats_move_down_line#sign%
1276  {\if!!donea \else
1277     \global\d_page_sides_downshift\zeropoint
1278     \!!doneatrue
1279   \fi
1280   \global\advance\d_page_sides_downshift#sign\lineheight}
1281
1282\def\strc_floats_move_down_hang#lines%
1283  {\if!!doneb \else
1284     \global\c_page_sides_n_of_lines\zerocount
1285     \!!donebtrue
1286   \fi
1287   \global\advance\c_page_sides_n_of_lines#lines\relax}
1288
1289\unexpanded\def\movedownsidefloat[#settings]% already in core
1290  {\doifnotinstring{:}{#settings}
1291     {\begingroup
1292      \!!doneafalse
1293      \!!donebfalse
1294      \normalexpanded{\dorepeatwithcommand[#settings]}\strc_floats_move_down
1295      \endgroup}}
1296
1297\unexpanded\def\hangsidefloat[#number]%
1298  {\global\c_page_sides_n_of_lines#number\relax}
1299
1300\def\strc_floats_set_extra_action#rightpagelocation#leftpagelocation%
1301  {\rightorleftpageaction
1302     {\let\extrafloatlocation#rightpagelocation}%
1303     {\let\extrafloatlocation#leftpagelocation}}
1304
1305\let\extrafloatlocation\empty
1306
1307\installcorenamespace{extrafloataction}
1308
1309\setvalue{\??extrafloataction      \v!inner}#1{\strc_floats_set_extra_action\v!left       \v!right}
1310\setvalue{\??extrafloataction      \v!outer}#1{\strc_floats_set_extra_action\v!right      \v!left}
1311\setvalue{\??extrafloataction\v!innermargin}#1{\strc_floats_set_extra_action\v!leftmargin \v!rightmargin}
1312\setvalue{\??extrafloataction\v!outermargin}#1{\strc_floats_set_extra_action\v!rightmargin\v!leftmargin}
1313\setvalue{\??extrafloataction  \v!inneredge}#1{\strc_floats_set_extra_action\v!leftedge   \v!rightedge}
1314\setvalue{\??extrafloataction  \v!outeredge}#1{\strc_floats_set_extra_action\v!rightedge  \v!leftedge}
1315\setvalue{\??extrafloataction  \v!backspace}#1{\strc_floats_set_extra_action\v!backspace  \v!cutspace}
1316\setvalue{\??extrafloataction   \v!cutspace}#1{\strc_floats_set_extra_action\v!cutspace   \v!backspace}
1317%setvalue{\??extrafloataction     \v!margin}#1{\strc_floats_set_extra_action\v!cutspace   \v!backspace}
1318\setvalue{\??extrafloataction       \v!left}#1{\strc_floats_set_extra_action\v!left       \v!left}
1319\setvalue{\??extrafloataction      \v!right}#1{\strc_floats_set_extra_action\v!right      \v!right}
1320\setvalue{\??extrafloataction       \v!line}#1{} % only -n*line is handled (see ***)
1321\setvalue{\??extrafloataction    \s!unknown}#1{\movedownsidefloat[#1]}
1322
1323\def\strc_floats_check_extra_actions % less tracingthis way ....
1324  {\doifnotinset\v!text\floatlocation % fuzzy, text overloads left, since then it's a directive
1325     {\let\extrafloatlocation\empty
1326      % \d_page_sides_downshift will be reset afterwards, and can
1327      % already be set at this point
1328      \processcommacommand[\floatlocation]\strc_floats_check_extra_actions_step
1329      \ifx\extrafloatlocation\empty \else
1330        \edef\floatlocation{\extrafloatlocation,\floatlocation}%
1331        \setfloatmethodvariables\floatlocation
1332      \fi}}
1333
1334\def\strc_floats_check_extra_actions_step#step%
1335  {\csname\??extrafloataction
1336     \ifcsname\??extrafloataction#step\endcsname#step\else\s!unknown\fi
1337   \endcsname{#step}}
1338
1339% pas op, maxbreedte niet instellen als plaats=links/rechts
1340
1341\def\strc_floats_set_local_dimensions
1342  {\global\d_page_sides_shift  \zeropoint       % duplicate
1343   \global\d_page_sides_maximum\zeropoint\relax % duplicate
1344   \ifzeropt\d_page_sides_downshift\else
1345     \global\setbox\floatbox\vpack
1346       {\vskip\d_page_sides_downshift
1347        \nointerlineskip
1348        \box\floatbox}%
1349   \fi
1350   \edef\p_minwidth{\floatparameter\c!minwidth}%
1351   \ifx\p_minwidth\empty
1352     % nothing
1353   \else
1354     \scratchwidth\p_minwidth\relax
1355     \ifdim\wd\floatbox<\scratchwidth
1356       \strc_floats_realign_floatbox_horizontal_two
1357     \fi
1358   \fi
1359   % we can also support edges .. in that case no common but a fast loop
1360   \doifelseinset\v!hanging\floatlocation
1361     {\doifelsecommon{\v!inleft,\v!leftmargin}\floatlocation
1362        {\let\p_maxwidth\leftmarginwidth}%
1363        {\doifelsecommon{\v!inright,\v!rightmargin}\floatlocation
1364           {\let\p_maxwidth\rightmarginwidth}%
1365           {\edef\p_maxwidth{\floatparameter\c!maxwidth}}}}%
1366     {\edef\p_maxwidth{\floatparameter\c!maxwidth}}%
1367   \ifx\p_maxwidth\empty
1368     % nothing
1369   \else
1370     \scratchwidth\p_maxwidth\relax
1371     \ifdim\wd\floatbox>\scratchwidth
1372       \doifelsecommon{\v!inright,\v!rightmargin,\v!rightedge,\v!inleft,\v!leftmargin,\v!leftedge}\floatlocation
1373         {\global\d_page_sides_maximum\scratchwidth}
1374         {\doifelsecommon{\v!right,\v!left}\floatlocation
1375            \strc_floats_realign_floatbox_horizontal_one
1376            \strc_floats_realign_floatbox_horizontal_two}%
1377     \fi
1378   \fi}
1379
1380\def\strc_floats_realign_floatbox_horizontal_one
1381  {\global\setbox\floatbox\hpack to \scratchwidth
1382     {\doifnotinset\v!right\floatlocation\hss
1383      \box\floatbox
1384      \doifnotinset\v!left\floatlocation\hss}}
1385
1386\def\strc_floats_realign_floatbox_horizontal_two % why is this
1387  {\global\setbox\floatbox\hpack to \scratchwidth
1388     {\doifnot{\floatparameter\c!location}\v!left\hss
1389      \box\floatbox
1390      \doifnot{\floatparameter\c!location}\v!right\hss}}
1391
1392\unexpanded\def\placefloats
1393  {\page_otr_command_flush_floats}
1394
1395\unexpanded\def\betweenfloatblanko % assumes that spaceafter is present
1396  {\blank[\rootfloatparameter\c!spacebefore]} % or v!back,....
1397
1398% keep as old 1
1399%
1400% \unexpanded\def\doplacefloatbox % used elsewhere
1401%   {%\forgetall % NO
1402%    \whitespace
1403%    \blank[\rootfloatparameter\c!spacebefore]
1404%    \page_otr_command_flush_float_box
1405%    \blank[\rootfloatparameter\c!spaceafter]}
1406%
1407% keep as old 2
1408%
1409% \unexpanded\def\doplacefloatbox % used elsewhere
1410%   {%\forgetall % NO
1411%    \whitespace
1412%    \blank[\rootfloatparameter\c!spacebefore]
1413%    \nointerlineskip
1414%    \flushnotes % new per 2014-05-29 : todo: move them up in the mvl
1415%    \nointerlineskip
1416%    \page_otr_command_flush_float_box
1417%    \nointerlineskip
1418%    \blank[\rootfloatparameter\c!spaceafter]}
1419
1420\def\strc_floats_apply_skip#1%
1421  {\edef\m_space{\rootfloatparameter#1}%
1422   \ifx\m_space\empty \else\ifx\m_space\v!none \else
1423      \directvspacing\m_space
1424   \fi\fi}
1425
1426\unexpanded\def\doplacefloatbox % used elsewhere
1427  {%\forgetall % NO
1428   \whitespace
1429   \strc_floats_apply_skip\c!spacebefore
1430   \nointerlineskip
1431   \flushnotes % new per 2014-05-29 : todo: move them up in the mvl
1432   \nointerlineskip
1433   \page_otr_command_flush_float_box
1434 % \nointerlineskip % interferes with depth of caption
1435   \strc_floats_apply_skip\c!spaceafter}
1436
1437% test case:
1438%
1439% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=0.9\textheight,color=green]}
1440% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.0\textheight,color=green]}
1441% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.1\textheight,color=green]}
1442
1443% the [#1] will go away
1444
1445\def\page_one_place_float_text % this macro should be defined elsewhere
1446  {%\checkwaitingfloats\floatlocationmethod
1447   % todo: check if #1 is indeed \floatlocation or maybe more
1448   \global\floatwidth    \wd\floatbox
1449   \global\floatheight   \ht\floatbox % forget about the depth
1450   \global\floattextwidth\dimexpr\hsize-\floatwidth-\rootfloatparameter\c!margin\relax
1451   \edef\floatlocation{\floatlocationmethod}% to be sure .. why
1452   \doifelseinset\v!tall\floatlocationmethod
1453     {\floattextheight\dimexpr\pagegoal-\pagetotal-\bigskipamount\relax % ugly, this bigskip
1454      \ifdim\floattextheight>\textheight
1455        \floattextheight\textheight
1456      \fi
1457      \boxmaxdepth\zeropoint\relax            % toegevoegd
1458      \ifdim\floattextheight<\floatheight
1459        \floattextheight\floatheight
1460      \fi
1461      \setbox\floattext\vbox to \floattextheight}
1462     {\setbox\floattext\vbox}%
1463   \bgroup
1464   \forgetall
1465   \setupblank
1466   \setupwhitespace % new, also needed for footnotes
1467   \blank[\v!disable]
1468   \hsize\floattextwidth
1469   \ignorespaces}
1470
1471\def\strc_floats_stop_text_indeed % todo
1472  {\egroup
1473   \doifnotinset\v!tall\floatlocation
1474     {\floattextheight\ifdim\ht\floattext<\floatheight\floatheight\else\ht\floattext\fi}%
1475   \setbox\floatbox\vpack to \floattextheight
1476     {\hsize\floatwidth
1477      \doifelseinset\v!both\floatlocation
1478        {\doifelseinset\v!low\floatlocation
1479           {\vfill\box\floatbox}
1480           {\doifelseinset\v!middle\floatlocation
1481              {\vfill\box\floatbox\vfill}
1482              {\box\floatbox\vfill}}}
1483        {\box\floatbox\vfill}}%
1484    \setbox\floattext\vpack to \floattextheight
1485     {\hsize\floattextwidth
1486      \doifelseinset\v!low\floatlocation
1487        {\vfill
1488         \box\floattext
1489         \doifinset\c!offset\floatlocation{\whitespace\blank}}
1490        {\doifelseinset\v!middle\floatlocation
1491           {\vfill
1492            \box\floattext
1493            \vfill}
1494           {\doifinset\v!offset\floatlocation{\whitespace\blank}%
1495            \box\floattext
1496            \vfill}}}%
1497   \doifelseinset\v!right\floatlocation
1498     {\setbox\floatbox\hpack to \hsize
1499        {\box\floattext
1500         \hfill
1501         \box\floatbox}}
1502     {\setbox\floatbox\hpack to \hsize
1503        {\box\floatbox
1504         \hfill
1505         \box\floattext}}%
1506   \baselinecorrection
1507   \whitespace
1508   \blank[\rootfloatparameter\c!spacebefore]%
1509   \doifnotinset\v!tall\floatlocation
1510     {\dp\floatbox\openstrutdepth}% dp\strutbox}%      % toegevoegd
1511   \box\floatbox
1512   \dostoptagged
1513   \blank[\rootfloatparameter\c!spaceafter]%
1514   \strc_floats_end_text_group
1515   \page_floats_report_total}
1516
1517\def\borderedfloatbox
1518  {\begingroup
1519   \setupcurrentfloat[\c!location=\v!normal,\c!width=\v!fit,\c!height=\v!fit]%
1520   \inheritedfloatframed{\box\floatbox}%
1521   \endgroup}
1522
1523% minwidth=fit,width=max : no overshoot, as wide as graphic
1524
1525% keep these as reference:
1526%
1527% \def\strc_floats_align_content_indeed
1528%   {\alignstrutmode\zerocount
1529%    \doifnotcommon\floatcaptionlocation{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
1530%      {\shiftalignedline
1531%         {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}%
1532%         {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}}%
1533%    \alignedline{\floatparameter\c!location}\v!middle}
1534%
1535% \def\strc_floats_align_caption_indeed
1536%   {\alignstrutmode\zerocount
1537%    \shiftalignedline
1538%      {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}%
1539%      {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}%
1540%    \alignedline{\floatparameter\c!location}\v!middle}
1541%
1542% Test case:
1543%
1544% \setupfloats[location=left]
1545% \setupfloatcaption[width=max]
1546%
1547% \startfloatcombination
1548%     \placefigure{}{}
1549%     \placefigure{}{}
1550% \stopfloatcombination
1551
1552%D In a floatcombination we ignore the margins .. if that is ever needed we need another
1553%D state (instead of local).
1554
1555\def\strc_floats_align_indeed
1556  {\alignedline{\floatparameter\c!location}\v!middle}
1557
1558\def\strc_floats_shift_indeed#1%
1559  {\shiftalignedline{#1\c!leftmargin}{#1\c!rightmargin}{#1\c!innermargin}{#1\c!outermargin}}
1560
1561\def\strc_floats_align_content_indeed
1562  {\alignstrutmode\zerocount
1563   \ifx\forcedfloatmethod\v!local \else
1564     \doifnotcommon\floatcaptionlocation{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin}
1565       {\strc_floats_shift_indeed\floatparameter}%
1566     \expandafter\strc_floats_align_indeed
1567   \fi}
1568
1569\def\strc_floats_align_caption_indeed
1570  {\alignstrutmode\zerocount
1571   \ifx\forcedfloatmethod\v!local
1572     \expandafter\strc_floats_align_indeed_local
1573   \else
1574     \strc_floats_shift_indeed\floatcaptionparameter
1575     \expandafter\strc_floats_align_indeed
1576   \fi}
1577
1578% \def\strc_floats_align_indeed_local#1%
1579%   {\begingroup
1580%    \hsize\wd\floatbox
1581%    \strc_floats_align_indeed{#1}%
1582%    \endgroup}
1583
1584\let\strc_floats_align_indeed_local\firstofoneargument
1585
1586\newdimen\d_strc_floats_content
1587\newdimen\d_strc_float_temp_height
1588\newdimen\d_strc_float_temp_width
1589
1590\newconditional\c_floats_adapt_to_caption_width
1591\newconditional\c_floats_store_minimal_package
1592
1593\def\captionminwidth {15\bodyfontsize} % can become parameter (but what name)
1594\def\captionovershoot{2\emwidth}       % can become parameter (but what name)
1595
1596\let\strc_floats_mark_pag_as_free\relax
1597
1598\def\strc_floats_set_page_variant
1599  {\bgroup
1600   \strc_floats_set_local_hsize
1601   \ifcase\c_strc_floats_rotation\else
1602     \swapdimens\hsize\vsize
1603   \fi
1604   \forgetall
1605   \postponenotes
1606   \dontcomplain
1607   \setbox\b_strc_floats_content\vpack{\borderedfloatbox}%
1608   \let\strc_floats_align_content\strc_floats_align_content_indeed
1609   \let\strc_floats_align_caption\strc_floats_align_caption_indeed
1610   \strc_floats_check_caption_content
1611   \d_strc_floats_content\wd\b_strc_floats_content
1612   \ifcase\floatparameter\c!method
1613     % nothing
1614   \or
1615     % automatic
1616     \ifnofloatcaption
1617       \strc_floats_prepare_no_caption
1618       \strc_floats_set_caption_dimensions\voidbox
1619      %\page_backgrounds_add_local_to_box\floatbox % was \doglobal but not needed
1620     \else
1621       % todo: installable maken, variant/method=auto vs macro
1622       \strc_floats_prepare_page_caption
1623      %\page_backgrounds_add_local_to_box\b_strc_floats_content
1624       \setbox\b_strc_floats_caption\hbox % text
1625         {\floatcaptionparameter\c!command{\box\b_strc_floats_caption}}%
1626       \strc_floats_set_caption_dimensions\b_strc_floats_caption
1627      %\moveboxontogrid\b_strc_floats_caption{\floatcaptionparameter\c!grid}\d_strc_floats_caption_height
1628      %\page_backgrounds_add_local_to_box\b_strc_floats_caption
1629       \strc_floats_build_box
1630     \fi
1631   \or
1632     % semi automatic
1633   \or
1634     % manual
1635   \fi
1636   \ifconditional\c_floats_store_minimal_package
1637      % nothing
1638   \else\ifcase\c_strc_floats_rotation
1639     \doifnotinset\v!margin\floatlocation % brr, really needed! see wm
1640       {\postcenterfloatbox\d_strc_floats_content
1641        \strc_floats_mark_pag_as_free}%
1642       % mark as free not done here
1643   \else
1644     \global\setbox\floatbox\vpack
1645       {\rotate[\c!rotation=\number\c_strc_floats_rotation]{\box\floatbox}}%
1646     \strc_floats_mark_pag_as_free
1647   \fi\fi
1648   \egroup}
1649
1650\def\strc_floats_prepare_no_caption
1651  {\global\setbox\floatbox\vpack % pas op als wd groter dan hsize
1652     {\ifinsidecolumns\ifdim\wd\b_strc_floats_content>\hsize
1653        \let\strc_floats_align_content\relax
1654      \fi\fi
1655      \strc_floats_align_content{\copy\b_strc_floats_content}}}
1656
1657\def\strc_floats_prepare_page_caption
1658  {\edef\p_strc_floats_caption_width   {\floatcaptionparameter\c!width}%
1659   \edef\p_strc_floats_caption_minwidth{\floatcaptionparameter\c!minwidth}%
1660   \edef\p_strc_floats_caption_align   {\floatcaptionparameter\c!align}%
1661   \dostarttagged\t!floatcaption\empty
1662   \doifcommonelse\floatcaptionlocation{\v!top,\v!bottom}
1663      {\strc_floats_prepare_page_caption_top_bottom}
1664      {\ifx\p_strc_floats_caption_width\v!fit
1665         \strc_floats_prepare_side_auto_caption
1666       \else\ifx\p_strc_floats_caption_width\v!max
1667         \strc_floats_prepare_side_auto_caption
1668       \else
1669         \strc_floats_prepare_side_width_caption
1670      \fi\fi}%
1671   \dostoptagged}
1672
1673\def\strc_floats_prepare_page_caption_top_bottom
1674  {\ifx\p_strc_floats_caption_width\v!fit
1675     \strc_floats_prepare_page_caption_top_bottom_fit_max
1676   \else\ifx\p_strc_floats_caption_width\v!max
1677     \strc_floats_prepare_page_caption_top_bottom_fit_max
1678   \else
1679     \strc_floats_prepare_side_width_caption % new, special effects (see icare)
1680   \fi\fi}
1681
1682\def\strc_floats_prepare_page_caption_top_bottom_fit_max
1683  {\ifx\p_strc_floats_caption_minwidth\v!fit
1684     \ifx\p_strc_floats_caption_width\v!max
1685       \strc_floats_prepare_stack_caption_max
1686     \else\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content % wider caption
1687       \ifx\p_strc_floats_caption_width\v!fit
1688         \strc_floats_prepare_stack_caption_auto
1689       \else
1690         \strc_floats_prepare_stack_caption_width
1691       \fi
1692     \else
1693       \strc_floats_prepare_stack_caption_min
1694     \fi\fi
1695  \else
1696    \strc_floats_prepare_stack_caption_fixed
1697  \fi}
1698
1699\def\strc_floats_caption_set_align
1700  {\edef\m_align{\v!reset\ifx\p_strc_floats_caption_align\empty\else,\fi\p_strc_floats_caption_align}%
1701   \doifinset\v!tolerant    \floatcaptionlocation{\edef\m_align{\m_align,\v!tolerant}}%
1702   \doifinset\v!verytolerant\floatcaptionlocation{\edef\m_align{\m_align,\v!verytolerant}}%
1703   \doifinset\v!stretch     \floatcaptionlocation{\edef\m_align{\m_align,\v!stretch}}%
1704   \setupalign[\m_align]}
1705
1706\def\strc_floats_prepare_side_auto_caption
1707  {\scratchdimen\dimexpr\hsize-\wd\b_strc_floats_content-\floatparameter\c!margin\relax
1708   \ifdim\wd\b_strc_floats_caption>\scratchdimen
1709     \ifdim\wd\b_strc_floats_caption<1.3\scratchdimen
1710       \scratchdimen0.8\scratchdimen
1711     \fi
1712   \fi
1713   \setbox\b_strc_floats_caption\vbox
1714     {\strc_floats_caption_set_align
1715      \hsize\scratchdimen
1716      \strc_floats_make_complete_caption}}
1717
1718\def\strc_floats_prepare_side_width_caption
1719  {\setbox\b_strc_floats_caption\vbox
1720     {\strc_floats_caption_set_align
1721      \hsize\floatcaptionparameter\c!width
1722      \strc_floats_make_complete_caption}}
1723
1724\def\strc_floats_prepare_stack_caption_fixed
1725  {\setbox\b_strc_floats_caption\vbox
1726     {\strc_floats_caption_set_align
1727      \hsize\floatcaptionparameter\c!minwidth % special effects
1728      \strc_floats_make_complete_caption}}
1729
1730\def\strc_floats_prepare_stack_caption_max
1731  {\setbox\b_strc_floats_caption\vbox
1732     {\strc_floats_caption_set_align
1733      \hsize\wd\b_strc_floats_content
1734      \strc_floats_make_complete_caption}}
1735
1736\def\strc_floats_prepare_stack_caption_width
1737  {\setbox\b_strc_floats_caption\vbox
1738     {\strc_floats_caption_set_align
1739      \hsize\floatcaptionparameter\c!width
1740      \strc_floats_make_complete_caption}}
1741
1742\def\strc_floats_prepare_stack_caption_min
1743  {\setbox\b_strc_floats_caption\vbox
1744     {\strc_floats_caption_set_align
1745      \hsize\wd\b_strc_floats_content
1746      \ifx\p_strc_floats_caption_align\empty
1747        \raggedcenter % on purpose overloads align !
1748      \fi
1749      \strc_floats_make_complete_caption}}
1750
1751\def\strc_floats_prepare_stack_caption_auto
1752  {\ifx\p_strc_floats_caption_align\empty \else
1753     \doifnotinset\v!middle\p_strc_floats_caption_align{\let\captionovershoot\!!zeropoint}%
1754   \fi
1755   \edef\captionhsize{\the\wd\b_strc_floats_content}%
1756   \scratchwidth\floatcaptionparameter\c!maxwidth\relax
1757   \ifconditional\c_floats_adapt_to_caption_width
1758     \let\captionminwidth \!!zeropoint
1759     \let\captionovershoot\!!zeropoint
1760   \fi
1761   \ifdim\captionhsize>\scratchwidth
1762     % float is wider than \hsize
1763     \setbox\b_strc_floats_caption\vbox
1764       {\settrialtypesetting
1765        \strc_floats_caption_set_align
1766        \hsize\scratchwidth
1767        \notesenabledfalse
1768        \strc_floats_make_complete_caption}%
1769     \ifdim\ht\scratchbox>\lineheight % more lines
1770       \setbox\b_strc_floats_caption\vbox
1771         {\strc_floats_caption_set_align
1772          \hsize\dimexpr\captionhsize-\captionovershoot\relax
1773          \ifdim\hsize<\captionminwidth\relax
1774            \hsize\scratchwidth
1775          \fi
1776          \strc_floats_make_complete_caption}%
1777     \else
1778       \setbox\b_strc_floats_caption\vbox
1779         {\strc_floats_caption_set_align
1780          \hsize\scratchwidth
1781          \strc_floats_make_complete_caption}%
1782     \fi
1783   \else
1784     % float is smaller of equal to \hsize
1785     \ifdim\captionhsize<\captionminwidth\relax
1786       \scratchdimen\captionminwidth % float smaller than min width
1787       \edef\captionhsize{\the\scratchdimen}%
1788% \ifconditional\c_floats_adapt_to_caption_width
1789%   \setbox\b_strc_floats_content\hpack to \captionhsize{\hss\box\b_strc_floats_content\hss}%
1790% \fi
1791     \fi
1792     \setbox\scratchbox\vbox     % test with overshoot
1793       {\settrialtypesetting
1794        \scratchdimen\dimexpr\captionhsize+\captionovershoot+3\emwidth\relax % 3em is an average word length
1795        \ifdim\scratchdimen<\hsize
1796          \hsize\scratchdimen
1797        \fi
1798        \notesenabledfalse
1799        \strc_floats_make_complete_caption}%
1800     \ifdim\ht\scratchbox>\lineheight
1801       % at least an average word longer than a line
1802       \setbox\b_strc_floats_caption\vbox
1803         {\strc_floats_caption_set_align
1804          \scratchdimen\dimexpr\captionhsize+\captionovershoot\relax
1805          \ifdim\scratchdimen<\hsize
1806            \hsize\scratchdimen
1807          \fi
1808          \strc_floats_make_complete_caption}%
1809     \else\ifx\p_strc_floats_caption_align\empty
1810       \setbox\b_strc_floats_caption\vbox
1811         {\strc_floats_caption_set_align
1812          \hsize\captionhsize
1813          \raggedcenter % overloads
1814          \strc_floats_make_complete_caption}%
1815     \else
1816       \setbox\b_strc_floats_caption\vbox
1817         {\strc_floats_caption_set_align
1818          \hsize\captionhsize
1819          \strc_floats_make_complete_caption}%
1820     \fi\fi
1821   \fi}
1822
1823\def\strc_floats_between_stack
1824  {\endgraf
1825   \nointerlineskip
1826   \floatcaptionparameter\c!inbetween
1827   \endgraf}
1828
1829\def\strc_floats_build_box_default % done
1830  {\strc_floats_align_content{\box\b_strc_floats_content}}
1831
1832\def\strc_floats_build_box_next_right#1%
1833  {\ifconditional\c_strc_floats_par_float \hpack \else \expandafter \strc_floats_align_content \fi % skip, no pack
1834     {\d_strc_float_temp_height\ht\b_strc_floats_content
1835      \box\b_strc_floats_content
1836      \doifnotinset\v!hang\floatcaptionlocation
1837        {\dotfskip{\floatcaptionparameter\c!distance}}%
1838      \vbox to\d_strc_float_temp_height{#1}}}
1839
1840\def\strc_floats_build_box_next_left#1%
1841  {\ifconditional\c_strc_floats_par_float \hpack \else \expandafter \strc_floats_align_content \fi % skip, no pack
1842     {\d_strc_float_temp_height\ht\b_strc_floats_content
1843      \vbox to\d_strc_float_temp_height{#1}%
1844      \doifnotinset\v!hang\floatcaptionlocation
1845        {\dotfskip{\floatcaptionparameter\c!distance}}%
1846      \box\b_strc_floats_content}}
1847
1848\def\strc_floats_build_box_next_outer
1849  {\doifelserightpagefloat\strc_floats_build_box_next_right\strc_floats_build_box_next_left}
1850
1851\def\strc_floats_build_box_next_inner
1852  {\doifelserightpagefloat\strc_floats_build_box_next_left\strc_floats_build_box_next_right}
1853
1854\def\strc_floats_build_box_next_right_hang#1%
1855  {\ifconditional\c_strc_floats_par_float \hpack \else \expandafter \strc_floats_align_content \fi
1856     {\d_strc_float_temp_height\ht\b_strc_floats_content
1857      \box\b_strc_floats_content
1858      \vbox to\d_strc_float_temp_height{#1}}}
1859
1860\def\strc_floats_build_box_next_left_hang#1%
1861  {\ifconditional\c_strc_floats_par_float \hpack \else \expandafter \strc_floats_align_content \fi
1862     {\d_strc_float_temp_height\ht\b_strc_floats_content
1863      \vbox to\d_strc_float_temp_height{#1}%
1864      \box\b_strc_floats_content}}
1865
1866% \def\strc_floats_build_box_next_right_margin_indeed#1#2%
1867%   {\ifconditional\c_strc_floats_par_float
1868%      \hpack\bgroup
1869%        \d_strc_float_temp_height\ht\b_strc_floats_content
1870%        \box\b_strc_floats_content
1871%        \hsmash{\hskip#1\vbox to\d_strc_float_temp_height{#2}}%
1872%      \egroup
1873%    \else
1874%      \begingroup
1875%      \d_strc_float_temp_height\ht\b_strc_floats_content
1876%      \everyrightofalignedline{\hsmash{\hskip#1\vbox to\d_strc_float_temp_height{#2}}}%
1877%      \strc_floats_align_content{\box\b_strc_floats_content}%
1878%      \endgroup
1879%     \fi}
1880%
1881% \def\strc_floats_build_box_next_left_margin_indeed#1#2%
1882%   {\ifconditional\c_strc_floats_par_float
1883%      \hpack\bgroup
1884%        \d_strc_float_temp_height\ht\b_strc_floats_content
1885%        \hsmash{\hskip-\dimexpr#1+\wd\b_strc_floats_caption\relax\vbox to\d_strc_float_temp_height{#2}}%
1886%        \box\b_strc_floats_content
1887%      \egroup
1888%    \else
1889%      \begingroup
1890%      \d_strc_float_temp_height\ht\b_strc_floats_content
1891%      \everyleftofalignedline{\hsmash{\hskip-\dimexpr#1+\wd\b_strc_floats_caption\relax\vbox to\d_strc_float_temp_height{#2}}}%
1892%      \strc_floats_align_content{\box\b_strc_floats_content}%
1893%      \endgroup
1894%    \fi}
1895
1896\def\strc_floats_build_box_next_right_margin_indeed#1#2%
1897  {\ifconditional\c_strc_floats_par_float
1898     \hpack\bgroup
1899       \d_strc_float_temp_height\ht\b_strc_floats_content
1900       \box\b_strc_floats_content
1901       \hsmash{\hskip#1\vbox to\d_strc_float_temp_height{#2}}%
1902     \egroup
1903   \else
1904     \begingroup
1905     \d_strc_float_temp_height\ht\b_strc_floats_content
1906     \setbox\scratchboxone\vbox{#2}%
1907     \ifdim\htdp\scratchboxone>\htdp\b_strc_floats_content
1908       \global\d_strc_floats_overflow\dimexpr\htdp\scratchboxone-\htdp\b_strc_floats_content\relax
1909     \fi
1910     \ht\scratchboxone\d_strc_float_temp_height
1911     \everyrightofalignedline{\hsmash{\hskip#1\box\scratchboxone}}%
1912     \strc_floats_align_content{\box\b_strc_floats_content}%
1913     \endgroup
1914    \fi}
1915
1916\def\strc_floats_build_box_next_left_margin_indeed#1#2%
1917  {\ifconditional\c_strc_floats_par_float
1918     \hpack\bgroup
1919       \d_strc_float_temp_height\ht\b_strc_floats_content
1920       \hsmash{\hskip-\dimexpr#1+\wd\b_strc_floats_caption\relax\vbox to\d_strc_float_temp_height{#2}}%
1921       \box\b_strc_floats_content
1922     \egroup
1923   \else
1924     \begingroup
1925     \d_strc_float_temp_height\ht\b_strc_floats_content
1926     \setbox\scratchboxone\vbox{#2}%
1927     \ifdim\htdp\scratchboxone>\htdp\b_strc_floats_content
1928       \global\d_strc_floats_overflow\dimexpr\htdp\scratchboxone-\htdp\b_strc_floats_content\relax
1929     \fi
1930     \ht\scratchboxone\d_strc_float_temp_height
1931     \everyleftofalignedline{\hsmash{\hskip-\dimexpr#1+\wd\scratchboxone\relax\box\scratchboxone}}%
1932     \strc_floats_align_content{\box\b_strc_floats_content}%
1933     \endgroup
1934   \fi}
1935
1936\def\strc_floats_build_box_next_right_margin
1937  {\strc_floats_build_box_next_right_margin_indeed\rightmargindistance}
1938
1939\def\strc_floats_build_box_next_left_margin
1940  {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance}
1941
1942\def\strc_floats_build_box_next_outer_margin
1943  {\doifelserightpagefloat
1944     {\strc_floats_build_box_next_right_margin_indeed\rightmargindistance}
1945     {\strc_floats_build_box_next_left_margin_indeed \rightmargindistance}}
1946
1947\def\strc_floats_build_box_next_inner_margin
1948  {\doifelserightpagefloat
1949     {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance}
1950     {\strc_floats_build_box_next_right_margin_indeed\leftmargindistance}}
1951
1952\def\strc_floats_build_box_next % beware, we first check on left/rightmargin because there can be left/right also
1953  {\let\next\strc_floats_build_box_next_left
1954   \processallactionsinset[\floatcaptionlocation]
1955     [ \v!outermargin=>\let\next\strc_floats_build_box_next_outer_margin,
1956       \v!innermargin=>\let\next\strc_floats_build_box_next_inner_margin,
1957        \v!leftmargin=>\let\next\strc_floats_build_box_next_left_margin,
1958       \v!rightmargin=>\let\next\strc_floats_build_box_next_right_margin,
1959       \v!lefthanging=>\let\next\strc_floats_build_box_next_left_hang,
1960      \v!righthanging=>\let\next\strc_floats_build_box_next_right_hang,
1961             \v!outer=>\let\next\strc_floats_build_box_next_outer,
1962             \v!inner=>\let\next\strc_floats_build_box_next_inner,
1963              \v!left=>\let\next\strc_floats_build_box_next_left,
1964             \v!right=>\let\next\strc_floats_build_box_next_right]%
1965   \next}
1966
1967\def\strc_floats_build_box_side
1968  {\ifconditional\c_strc_floats_par_float
1969     \let\next\strc_floats_build_box_high
1970   \else
1971     \let\next\strc_floats_build_box_middle
1972     \processallactionsinset[\floatcaptionlocation]
1973       [   \v!low=>\let\next\strc_floats_build_box_low,
1974        \v!middle=>\let\next\strc_floats_build_box_middle,
1975          \v!high=>\let\next\strc_floats_build_box_high]%
1976   \fi
1977   \next}
1978
1979\def\strc_floats_flush_right_caption_hang
1980  {\hsmash{\rlap{\dotfskip{\floatcaptionparameter\c!distance}\box\b_strc_floats_caption}}}
1981
1982\def\strc_floats_flush_left_caption_hang
1983  {\hsmash{\llap{\box\b_strc_floats_caption\dotfskip{\floatcaptionparameter\c!distance}}}}
1984
1985\def\strc_floats_flush_caption_hang
1986  {\doifelseinset\v!righthanging\floatcaptionlocation
1987     {\strc_floats_flush_right_caption_hang}
1988     {\doifelseinset\v!lefthanging\floatcaptionlocation
1989        {\strc_floats_flush_left_caption_hang}
1990        {\doifelseinset\v!hang\floatcaptionlocation
1991           {\doifelseinset\v!outer\floatcaptionlocation
1992              {\doifelserightpagefloat{\strc_floats_flush_right_caption_hang}{\strc_floats_flush_left_caption_hang}}
1993              {\doifelseinset\v!right\floatcaptiondirectives
1994                 {\strc_floats_flush_right_caption_hang}
1995                 {\strc_floats_flush_left_caption_hang}}}
1996        {\box\b_strc_floats_caption}}}}
1997
1998\def\strc_floats_build_box_high
1999  {\strc_floats_build_box_next{\strc_floats_between_stack\strc_floats_flush_caption_hang\vfill}}
2000
2001\def\strc_floats_build_box_low
2002  {\strc_floats_build_box_next{\vfill\strc_floats_flush_caption_hang\strc_floats_between_stack}}
2003
2004\def\strc_floats_build_box_middle
2005  {\strc_floats_build_box_next{\vfill\box\b_strc_floats_caption\vfill}}
2006
2007% \definefloat
2008%   [lefty][lefties][figure]
2009% \setupfloat
2010%   [lefty]
2011%   [default=left,
2012%    rightmargindistance=-2cm,
2013%    leftmargindistance=-2cm]
2014% \setupcaption
2015%   [lefty]
2016%   [location={bottom,overlay}]
2017%
2018% \starttext
2019%     \placelefty{}{} \input tufte \input tufte
2020%     \placelefty{}{} \input tufte \input tufte
2021% \stoptext
2022
2023\def\strc_floats_build_box_top_stack_normal_overlay
2024  {\vbox to \ht\b_strc_floats_content{\vss\strc_floats_build_box_top_stack_normal_content}}
2025
2026\def\strc_floats_build_box_top_stack_normal_content
2027  {\d_strc_float_temp_width\wd\b_strc_floats_content
2028   \ifconditional\c_strc_floats_par_float
2029     \hpack{\strc_floats_locate_side_float{\box\b_strc_floats_caption}}%
2030     \strc_floats_between_stack
2031     \hpack{\hbox{\box\b_strc_floats_content}}%
2032   \else
2033     \page_otr_command_set_float_hsize
2034     \hpack{\strc_floats_locate_text_float{\box\b_strc_floats_caption}}
2035     \strc_floats_between_stack
2036     \hpack{\strc_floats_align_content{\box\b_strc_floats_content}}%
2037   \fi}
2038
2039\def\strc_floats_build_box_bottom_stack_normal_overlay
2040  {\vbox to \ht\b_strc_floats_content{\strc_floats_build_box_bottom_stack_normal_content\vss}}
2041
2042\def\strc_floats_build_box_bottom_stack_normal_content
2043  {\d_strc_float_temp_width\wd\b_strc_floats_content
2044   \ifconditional\c_strc_floats_par_float
2045     \hpack{\hpack{\box\b_strc_floats_content}}%
2046     \strc_floats_between_stack
2047     \hpack{\strc_floats_locate_side_float{\box\b_strc_floats_caption}}%
2048   \else
2049     \page_otr_command_set_float_hsize
2050     \hpack{\strc_floats_align_content{\box\b_strc_floats_content}}%
2051     \strc_floats_between_stack
2052     \hpack{\strc_floats_locate_text_float{\box\b_strc_floats_caption}}%
2053   \fi}
2054
2055\def\strc_floats_build_box_top_stack_normal
2056  {\doifelseinset\v!overlay{\floatcaptionparameter\c!location}
2057      \strc_floats_build_box_top_stack_normal_overlay
2058      \strc_floats_build_box_top_stack_normal_content}
2059
2060\def\strc_floats_build_box_bottom_stack_normal
2061  {\doifinset\v!overlay{\floatcaptionparameter\c!location}
2062    \strc_floats_build_box_bottom_stack_normal_overlay
2063    \strc_floats_build_box_bottom_stack_normal_content}
2064
2065\def\strc_floats_build_box_top_stack_grid
2066  {\dp\b_strc_floats_caption\strutdepth
2067   \setbox\scratchbox\vbox
2068     {\d_strc_float_temp_width\wd\b_strc_floats_content
2069      \hsize\d_strc_float_temp_width
2070      \ifconditional\c_strc_floats_par_float
2071        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
2072        \vss\strc_floats_between_stack
2073        \hpack{\box\b_strc_floats_content}%
2074      \else
2075        \page_otr_command_set_float_hsize
2076        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
2077        \vss\strc_floats_between_stack
2078        \strc_floats_align_content{\box\b_strc_floats_content}%
2079      \fi}%
2080   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
2081   \vpack to \noflines\lineheight{\unvbox\scratchbox}}
2082
2083\def\strc_floats_build_box_bottom_stack_grid
2084  {\dp\b_strc_floats_caption\strutdepth
2085   \setbox\scratchbox\vbox
2086     {\d_strc_float_temp_width\wd\b_strc_floats_content
2087      \hsize\d_strc_float_temp_width
2088      \ifconditional\c_strc_floats_par_float
2089        \hpack{\box\b_strc_floats_content}%
2090        \vss\strc_floats_between_stack
2091        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
2092      \else
2093        \page_otr_command_set_float_hsize
2094        \strc_floats_align_content{\box\b_strc_floats_content}%
2095        \vss\strc_floats_between_stack
2096        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
2097      \fi}%
2098   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
2099   \vpack to \noflines\lineheight{\unvbox\scratchbox}}
2100
2101\def\strc_floats_build_box_top_stack_stretch
2102  {\dp\b_strc_floats_caption\strutdepth
2103   \setbox\scratchbox\vpack
2104     {\strc_floats_align_caption{\copy\b_strc_floats_caption}%
2105      \strc_floats_align_content{\copy\b_strc_floats_content}}%
2106   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
2107   \vbox to \noflines\lineheight % pack ?
2108     {\d_strc_float_temp_width\wd\b_strc_floats_content
2109      \hsize\d_strc_float_temp_width
2110      \ifconditional\c_strc_floats_par_float
2111        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
2112        \vss\strc_floats_between_stack\vss
2113        \hpack{\box\b_strc_floats_content}%
2114      \else
2115        \page_otr_command_set_float_hsize
2116        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
2117        \vss\strc_floats_between_stack\vss
2118        \strc_floats_align_content{\box\b_strc_floats_content}%
2119      \fi}}
2120
2121\def\strc_floats_build_box_bottom_stack_stretch
2122  {\dp\b_strc_floats_caption\strutdepth
2123   \setbox\scratchbox\vpack
2124     {\strc_floats_align_content{\copy\b_strc_floats_content}%
2125      \strc_floats_align_caption{\copy\b_strc_floats_caption}}%
2126   \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
2127   \vbox to \noflines\lineheight
2128     {\d_strc_float_temp_width\wd\b_strc_floats_content
2129      \hsize\d_strc_float_temp_width
2130      \ifconditional\c_strc_floats_par_float
2131        \hpack{\box\b_strc_floats_content}%
2132        \vss\strc_floats_between_stack\vss
2133        \strc_floats_locate_side_float{\box\b_strc_floats_caption}%
2134      \else
2135        \page_otr_command_set_float_hsize
2136        \strc_floats_align_content{\box\b_strc_floats_content}%
2137        \vss\strc_floats_between_stack\vss
2138        \strc_floats_locate_text_float{\box\b_strc_floats_caption}%
2139      \fi}}
2140
2141\def\strc_floats_build_box_top
2142  {\let\next\strc_floats_build_box_top_stack_normal
2143   \processfirstactioninset[\floatcaptionparameter\c!location]
2144     [   \v!grid=>\let\next\strc_floats_build_box_top_stack_grid,
2145        \v!lines=>\let\next\strc_floats_build_box_top_stack_stretch]% was \v!grid but interfered
2146   \next}
2147
2148\def\strc_floats_build_box_bottom
2149  {\let\next\strc_floats_build_box_bottom_stack_normal
2150   \processfirstactioninset[\floatcaptionparameter\c!location]
2151     [   \v!grid=>\let\next\strc_floats_build_box_bottom_stack_grid,
2152        \v!lines=>\let\next\strc_floats_build_box_bottom_stack_stretch]% was \v!grid but interfered
2153   \next}
2154
2155\def\strc_floats_relocate_caption_right#1{\strc_floats_align_caption{\hbox to \d_strc_float_temp_width{\hss#1}}}
2156\def\strc_floats_relocate_caption_left #1{\strc_floats_align_caption{\hbox to \d_strc_float_temp_width{#1\hss}}}
2157
2158\unexpanded\def\installfloatboxbuilder#1#2{\setvalue{\??floatbuilder#1}{#2}}
2159
2160\def\strc_floats_build_box
2161  {\strc_floats_build_box_before
2162   \global\setbox\floatbox\vbox % pack ? probably not
2163     {\strc_floats_set_local_hsize
2164      \forgetall
2165      \ifconditional\c_floats_store_minimal_package
2166        \strc_floats_build_box_separate_make
2167      \else
2168      % \let\floatcaptionarrangement\s!default
2169        \let\floatcaptionarrangement\v!bottom % for Alan
2170        \processcommacommand[\floatcaptionparameter\c!location]\strc_floats_build_box_step
2171        \ifcsname\??floatbuilder\floatcaptionarrangement\endcsname
2172          \lastnamedcs
2173        \else
2174          \strc_floats_build_box_default
2175        \fi
2176      \fi}%
2177   \strc_floats_build_box_after}
2178
2179% \let\strc_floats_build_box_before\relax
2180% \let\strc_floats_build_box_after \relax
2181
2182\def\strc_floats_build_box_before
2183  {\let\currentfloatframed\currentfloat
2184   \floatwidth\wd
2185     \ifdim\wd\b_strc_floats_content>\wd\b_strc_floats_caption
2186       \b_strc_floats_content\else\b_strc_floats_caption
2187     \fi}
2188
2189\def\strc_floats_build_box_after
2190  {\doifelseframed\floatframedparameter\strc_floats_build_box_after_indeed\relax}
2191
2192\def\strc_floats_build_box_after_indeed
2193  {\global\setbox\floatbox\hpack
2194     {\edef\m_width{\floatframedparameter\c!width}%
2195      \ifx\m_width\v!fit
2196        \let\m_width\floatwidth
2197      \else\ifx\m_width\v!broad
2198        \let\m_width\v!fit
2199      \fi\fi
2200      \letfloatframedparameter\c!strut\v!no
2201      \letfloatframedparameter\c!width\m_width
2202      \inheritedfloatframedframed
2203        {\box\floatbox}}}
2204
2205% special purpose: used in floatcombinations
2206%
2207% todo : keep float content and caption separated in local
2208
2209\newbox\b_strc_floats_separate_content
2210\newbox\b_strc_floats_separate_caption
2211
2212\def\strc_floats_build_box_separate_set
2213  {\settrue\c_floats_adapt_to_caption_width
2214   \settrue\c_floats_store_minimal_package}
2215
2216% \def\strc_floats_build_box_separate_make
2217%   {\offinterlineskip
2218%    \vpack to \onepoint{\box\b_strc_floats_content}\break
2219%    \vpack to \onepoint{\box\b_strc_floats_caption}}
2220
2221%D Remark for \LMTX: we don't want to migrate inserts here so we unpack
2222%D (could be a flag). When migrated, the inserts end up in the vertical
2223%D list and we no longer have just a box (but inserts and lines again).
2224
2225% \def\strc_floats_build_box_separate_split#1%
2226%   {\setbox\scratchbox\vpack{#1}%
2227%    \setbox\scratchbox\vbox\bgroup
2228%      \unvpack\scratchbox
2229%      \setbox\scratchbox\lastbox % can have (unmigrated) inserts
2230%      \unvpack\scratchbox
2231%      \setbox\scratchbox\lastbox % can have (unmigrated) inserts
2232%      \unvpack\scratchbox
2233%      \setbox\scratchbox\lastbox % can have (unmigrated) inserts
2234%      \splittopskip\zeropoint
2235%      \global\setbox\b_strc_floats_separate_content\vsplit\scratchbox to \onepoint
2236%      \global\setbox\b_strc_floats_separate_caption\vsplit\scratchbox to \onepoint
2237%    \egroup
2238%    \global\setbox\b_strc_floats_separate_content\vpack
2239%      {\unvbox\b_strc_floats_separate_content
2240%       \setbox\scratchbox\lastbox
2241%       \unvbox\scratchbox}%
2242%    \global\setbox\b_strc_floats_separate_caption\tpack
2243%      {\unvbox\b_strc_floats_separate_caption
2244%       \setbox\scratchbox\lastbox
2245%       \unvbox\scratchbox}}
2246
2247\def\strc_floats_build_box_separate_make
2248  {\savebox\??localfloatstack{\number\numexpr\c_strc_localfloats_n+1\relax:a}{\box\b_strc_floats_content}%
2249   \savebox\??localfloatstack{\number\numexpr\c_strc_localfloats_n+1\relax:b}{\box\b_strc_floats_caption}}
2250
2251\unexpanded\def\strc_floats_build_box_separate_split#1%
2252  {\global\setbox\b_strc_floats_separate_content\vpack{\foundbox\??localfloatstack{\number#1:a}}%
2253   \global\setbox\b_strc_floats_separate_caption\tpack{\foundbox\??localfloatstack{\number#1:b}}}
2254
2255% \def\strc_floats_build_box_step#1%
2256%   {\doifdefined{\??floatbuilder#1}{\def\floatcaptionarrangement{#1}\quitcommalist}}
2257
2258\def\strc_floats_build_box_step#1%
2259  {\ifcsname\??floatbuilder#1\endcsname
2260     \def\floatcaptionarrangement{#1}% \let\floatcaptionarrangement\commalistelement
2261     \quitcommalist
2262   \fi}
2263
2264\def\strc_floats_locate_text_float
2265  {\let\next\strc_floats_align_caption
2266   \processallactionsinset[\floatcaptionparameter\c!location]
2267     [ \v!left=>\let\next\strc_floats_relocate_caption_left,
2268      \v!right=>\let\next\strc_floats_relocate_caption_right,
2269      \v!inner=>\doifelserightpagefloat{\let\next\strc_floats_relocate_caption_left }{\let\next\strc_floats_relocate_caption_right},
2270      \v!outer=>\doifelserightpagefloat{\let\next\strc_floats_relocate_caption_right}{\let\next\strc_floats_relocate_caption_left }]%
2271   \next}
2272
2273\installfloatboxbuilder \v!none         \strc_floats_build_box_default
2274\installfloatboxbuilder \s!default      \strc_floats_build_box_default
2275\installfloatboxbuilder \v!high         \strc_floats_build_box_high
2276\installfloatboxbuilder \v!low          \strc_floats_build_box_low
2277\installfloatboxbuilder \v!middle       \strc_floats_build_box_middle
2278
2279\installfloatboxbuilder \v!rightmargin  \strc_floats_build_box_side % added 2016-08-23
2280\installfloatboxbuilder \v!leftmargin   \strc_floats_build_box_side % added 2016-08-23
2281\installfloatboxbuilder \v!innermargin  \strc_floats_build_box_side % added 2016-08-23
2282\installfloatboxbuilder \v!outermargin  \strc_floats_build_box_side % added 2016-08-23
2283
2284\installfloatboxbuilder \v!left         \strc_floats_build_box_side
2285\installfloatboxbuilder \v!right        \strc_floats_build_box_side
2286\installfloatboxbuilder \v!inner        \strc_floats_build_box_side % added 2016-08-23
2287\installfloatboxbuilder \v!outer        \strc_floats_build_box_side % added 2016-08-23
2288
2289\installfloatboxbuilder \v!lefthanging  \strc_floats_build_box_side % added 2016-08-23
2290\installfloatboxbuilder \v!righthanging \strc_floats_build_box_side % added 2016-08-23
2291\installfloatboxbuilder \v!hang         \strc_floats_build_box_side % added 2016-08-23
2292
2293\installfloatboxbuilder \v!top          \strc_floats_build_box_top
2294\installfloatboxbuilder \v!bottom       \strc_floats_build_box_bottom
2295
2296% \setuplayout[grid=yes] \showgrid \setupcaptions[style=smallbodyfont,location=grid,inbetween=]
2297%
2298% \starttext
2299%     test \placefigure{}                 {\externalfigure[cow.pdf][frame=on,grid=yes]}   test \page
2300%     test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=yes]}   test \page
2301%     test \placefigure{}                 {\externalfigure[cow.pdf][frame=on,grid=depth]} test \page
2302%     test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=depth]} test \page
2303% \stoptext
2304
2305% This might move to page-flt:
2306
2307\newif\ifpostponecolumnfloats \postponecolumnfloatsfalse % don't change
2308
2309\setnewconstant\postcenterfloatmethod\plusone
2310
2311\def\postcenterfloatbox#1%
2312  {\scratchdimen
2313     \ifcase\postcenterfloatmethod
2314       #1% \wd\floatbox
2315     \or\ifinsidecolumns
2316       \ifpostponecolumnfloats\makeupwidth\else#1\fi
2317     \else\ifdim#1>\hsize
2318       \hsize
2319     \else
2320       \wd\floatbox
2321     \fi\fi\fi
2322   \global\setbox\floatbox\hbox to \scratchdimen
2323   % {\hfill\box\floatbox\hfill}} % geen \hss, gaat mis in kolommen !
2324   % {\hss  \box\floatbox\hss  }} % wel \hss, anders mis in colset
2325     {\ifconditional\c_page_floats_center_box_global
2326        \donetrue
2327      \else\ifconditional\c_page_floats_center_box_local
2328        \donetrue
2329      \else
2330        \donefalse
2331      \fi\fi
2332      \ifdim\scratchdimen>\effectivehsize
2333        \donefalse
2334      \fi
2335      \hss\ifdone\hskip\effectiveleftskip\fi
2336      \box\floatbox
2337      \ifdone\hskip\effectiverightskip\fi\hss}}
2338
2339\def\strc_floats_set_paragraph_variant
2340  {\bgroup
2341   \forgetall
2342   \postponenotes
2343   \dontcomplain
2344   \setbox\b_strc_floats_content\vbox{\borderedfloatbox}% \vpack >?
2345  %\page_backgrounds_add_local_to_box\b_strc_floats_content
2346   \ifnofloatcaption
2347     \global\setbox\floatbox\vpack{\box\b_strc_floats_content}%
2348   \else
2349     \strc_floats_check_caption_content
2350     \strc_floats_prepare_side_caption
2351     \setbox\b_strc_floats_caption\hbox{\floatcaptionparameter\c!command{\box\b_strc_floats_caption}}% \hpack ?
2352    %\moveboxontogrid\b_strc_floats_caption{\floatcaptionparameter\c!grid}\d_strc_floats_caption_height
2353    %\page_backgrounds_add_local_to_box\b_strc_floats_caption
2354     \strc_floats_build_side_box
2355   \fi
2356   \egroup}
2357
2358\def\strc_floats_prepare_side_caption
2359  {\dostarttagged\t!floatcaption\empty
2360   \edef\p_strc_floats_caption_width{\floatcaptionparameter\c!width}%
2361   \edef\p_strc_floats_caption_align{\floatcaptionparameter\c!align}%
2362   \ifx\p_strc_floats_caption_width\v!max
2363     \strc_floats_prepare_side_caption_max
2364   \else\ifx\p_strc_floats_caption_width\v!fit
2365     \strc_floats_prepare_side_caption_fit
2366   \else
2367     \strc_floats_prepare_side_caption_width
2368   \fi\fi
2369   \dostoptagged}
2370
2371% these could be \??floatpreparesidecaption
2372
2373% \setupfloat[figure][location=left]
2374% \setupcaption[figure][width=max]
2375%
2376% \placefigure{my figure caption my figure caption}{\framed[width=4cm,height=1cm]{}} \input tufte
2377% \placefigure{my figure caption}                  {\framed[width=4cm,height=1cm]{}} \input tufte
2378
2379\def\strc_floats_prepare_side_caption_max
2380  {\setbox\b_strc_floats_caption\vbox
2381     {\strc_floats_caption_set_align
2382      \hsize\wd\b_strc_floats_content
2383      \strc_floats_make_complete_caption}}
2384
2385\def\strc_floats_prepare_side_caption_fit % or center when smaller
2386  {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax
2387     \setbox\b_strc_floats_caption\vbox
2388       {\forgetall % needed?
2389        \strc_floats_caption_set_align
2390        \hsize\wd\b_strc_floats_content
2391        \strc_floats_make_complete_caption}%
2392   \else
2393     % maybe we should listen to the align option here (now side floats need the max option
2394     \setbox\b_strc_floats_caption\hpack to \wd\b_strc_floats_content
2395       {\hss\hbox{\strc_floats_make_complete_caption}\hss}%
2396   \fi}
2397
2398\def\strc_floats_prepare_side_caption_width
2399  {\setbox\b_strc_floats_caption\vbox
2400     {\strc_floats_caption_set_align
2401      \hsize\p_strc_floats_caption_width % \wd\b_strc_floats_content
2402      \strc_floats_make_complete_caption}}
2403
2404% % maybe (but then also prepare_page that way):
2405%
2406% \installcorenamespace{floatpreparesidecaption}
2407%
2408% \def\strc_floats_prepare_side_caption
2409%   {\dostarttagged\t!floatcaption\empty
2410%    \edef\p_strc_floats_caption_width{\floatcaptionparameter\c!width}%
2411%    \edef\p_strc_floats_caption_align{\floatcaptionparameter\c!align}%
2412%    \expandnamespacemacro\??floatpreparesidecaption\p_strc_floats_caption_width\s!unknown
2413%    \dostoptagged}
2414%
2415% \setvalue{\??floatpreparesidecaption\v!max}%
2416%   {\setbox\b_strc_floats_caption\vbox
2417%      {\strc_floats_caption_set_align
2418%       \hsize\wd\b_strc_floats_content
2419%       \strc_floats_make_complete_caption}}
2420%
2421% \setvalue{\??floatpreparesidecaption\v!fit}%
2422%   {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax
2423%      \setbox\b_strc_floats_caption\vbox
2424%        {\forgetall % needed?
2425%         \hsize\wd\b_strc_floats_content
2426%         \strc_floats_make_complete_caption}%
2427%    \else
2428%      \setbox\b_strc_floats_caption\hbox to \wd\b_strc_floats_content
2429%        {\hss\hbox{\strc_floats_make_complete_caption}\hss}%
2430%    \fi}
2431%
2432% \setvalue{\??floatpreparesidecaption\s!unknown}%
2433%   {\setbox\b_strc_floats_caption\vbox
2434%      {\strc_floats_caption_set_align
2435%       \hsize\p_strc_floats_caption_width % \wd\b_strc_floats_content
2436%       \strc_floats_make_complete_caption}}
2437
2438\def\strc_floats_locate_side_float#1%
2439  {\begingroup
2440   \alignstrutmode\zerocount
2441   \hsize\d_strc_float_temp_width \forgetall
2442   \alignedline{\floatparameter\c!location}\v!middle{#1}%
2443   \endgroup}
2444
2445\def\strc_floats_build_side_box
2446  {\let\strc_floats_align_content\relax
2447   \let\strc_floats_align_caption\relax
2448   \strc_floats_build_box}
2449
2450\def\strc_floats_set_box % todo : \global\setbox, currently messy
2451  {\ifvisible
2452     \par
2453     \edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}%
2454     \ifconditional\c_strc_floats_par_float
2455       \strc_floats_set_paragraph_variant
2456     \else
2457       \strc_floats_set_page_variant
2458     \fi
2459     \strc_floats_set_local_dimensions
2460     \global\advance\totalnoffloats\plusone
2461     \ifconditional\c_floats_store_minimal_package \else
2462       \setbox\floatbox\hpack{\strc_float_save_data\box\floatbox}% still needed? we will do renumbering differently
2463     \fi
2464     \global\floatheight\htdp\floatbox
2465     \global\floatwidth\wd\floatbox
2466     \ifconditional\c_floats_store_minimal_package \else
2467       \doifnotinset\v!margin\floatlocation % gaat namelijk nog fout
2468         {\setbox\floatbox\vpack
2469            {\parindent\zeropoint
2470             \box\floatbox}}%
2471     \fi
2472     \wd\floatbox\floatwidth
2473     \ifdim\dimexpr\floatheight+\lineheight\relax<\textheight \else
2474       \global\floatheight\dimexpr\textheight-\lineheight\relax
2475       \ht\floatbox\floatheight
2476       \dp\floatbox\zeropoint
2477       \showmessage\m!floatblocks{10}{\the\totalnoffloats}%
2478     \fi
2479   \fi}
2480
2481% \def\dooutput{\sidefloatoutput} % redefinition of \dooutput
2482
2483\definefloat
2484  [\v!figure]
2485  [\v!figures]
2486
2487\definefloat
2488  [\v!table]
2489  [\v!tables]
2490
2491\setupfloat
2492  [\v!table]
2493  [\c!frame=\v!off]
2494
2495\definefloat
2496  [\v!intermezzo]
2497  [\v!intermezzi]
2498
2499\definefloat
2500  [\v!graphic]
2501  [\v!graphics]
2502
2503% float strategy, replaces some of the above macros
2504
2505\installcorenamespace{floatmethods}
2506
2507\let\floatmethod      \empty % set by lua
2508\let\floatlabel       \empty % set by lua
2509\let\floatcolumn      \empty % set by lua
2510\let\floatrow         \empty % set by lua
2511\let\forcedfloatmethod\empty % set by lua and floatcombinations
2512
2513\def\setfloatmethodvariables#1% \floatmethod \floatlabel \floatrow \floatcolumn
2514  {\clf_analysefloatmethod{#1}}
2515
2516\def\somesomewherefloat[#1]%
2517  {\page_floats_save_somewhere_float\s!somewhere{#1}}
2518
2519\def\strc_floats_get_box
2520  {\ifvisible
2521%      \let\floatlabel \empty
2522%      \let\floatcolumn\empty
2523%      \let\floatrow   \empty
2524%      \setfloatmethodvariables\floatlocation
2525     % todo: nog algemeen otr
2526%      \ifdefined\OTRSETsetpreferedcolumnslot
2527%        \OTRSETsetpreferedcolumnslot\floatcolumn\floatrow
2528%      \fi
2529     \ifcsname\??floatmethods\currentoutputroutine:\floatmethod\endcsname \else
2530        \let\floatmethod\v!here
2531     \fi
2532     \ifx\forcedfloatmethod\empty \else
2533       \let\floatmethod\forcedfloatmethod
2534     \fi
2535\let\askedfloatmethod\floatmethod
2536\ifexporting \ifx\askedfloatmethod\v!here \else
2537  \showmessage\m!floatblocks{15}{\askedfloatmethod,\v!here}%
2538  \let\floatlocation\v!here
2539\fi \fi
2540     % [] will go
2541     \edef\floatlocationmethod{\floatmethod,\floatlocation}%
2542     \csname\??floatmethods\currentoutputroutine:\floatmethod\endcsname
2543   \fi}
2544
2545\installcorenamespace{floatsettings}
2546
2547\unexpanded\def\installfloatmethod#1#2#3% routine keyword handler
2548  {\setvalue{\??floatmethods#1:#2}{#3}}
2549
2550\unexpanded\def\handlefloatmethod#1%
2551  {\csname\??floatmethods\currentoutputroutine:#1\endcsname}
2552
2553% \unexpanded\def\installfloatmethod#1#2#3% routine keyword handler
2554%   {\ifcsname\??floatsettings#1:#2\endcsname \else
2555%      \expandafter\newtoks\csname\??floatsettings#1:#2\endcsname
2556%    \fi
2557%    \setvalue{\??floatmethods#1:#2}{#3}}
2558%
2559% \unexpanded\def\startfloatmethodsettings#1#2 #3\stopfloatmethodsettings
2560%   {\csname\??floatsettings#1:#2\endcsname\expandafter{\the\csname\??floatsettings#1:#2\endcsname#3}}
2561%
2562% \let\stopfloatmethodsettings\relax
2563%
2564% \unexpanded\def\applyfloatmethodsettings#1#2{\the\??floatsettings#1:#2\endcsname}
2565
2566\definesystemconstant{tblr}
2567\definesystemconstant{lrtb}
2568\definesystemconstant{tbrl}
2569\definesystemconstant{rltb}
2570\definesystemconstant{btlr}
2571\definesystemconstant{lrbt}
2572\definesystemconstant{btrl}
2573\definesystemconstant{rlbt}
2574\definesystemconstant{fxtb}
2575\definesystemconstant{fxbt}
2576\definesystemconstant{fixd}
2577
2578% can move to page-one:
2579
2580\installfloatmethod \s!singlecolumn \v!here        \page_one_place_float_here
2581\installfloatmethod \s!singlecolumn \v!force       \page_one_place_float_force
2582\installfloatmethod \s!singlecolumn \v!left        \page_one_place_float_left
2583\installfloatmethod \s!singlecolumn \v!right       \page_one_place_float_right
2584\installfloatmethod \s!singlecolumn \v!text        \page_one_place_float_text
2585\installfloatmethod \s!singlecolumn \v!top         \page_one_place_float_top
2586\installfloatmethod \s!singlecolumn \v!bottom      \page_one_place_float_bottom
2587\installfloatmethod \s!singlecolumn \v!auto        \page_one_place_float_auto
2588\installfloatmethod \s!singlecolumn \v!margin      \page_one_place_float_margin
2589\installfloatmethod \s!singlecolumn \v!opposite    \page_one_place_float_face
2590\installfloatmethod \s!singlecolumn \v!page        \page_one_place_float_page
2591\installfloatmethod \s!singlecolumn \v!leftpage    \page_one_place_float_leftpage
2592\installfloatmethod \s!singlecolumn \v!rightpage   \page_one_place_float_rightpage
2593\installfloatmethod \s!singlecolumn \v!inmargin    \page_one_place_float_inmargin
2594\installfloatmethod \s!singlecolumn \v!inleft      \page_one_place_float_leftmargin
2595\installfloatmethod \s!singlecolumn \v!inright     \page_one_place_float_rightmargin
2596\installfloatmethod \s!singlecolumn \v!leftmargin  \page_one_place_float_leftmargin
2597\installfloatmethod \s!singlecolumn \v!rightmargin \page_one_place_float_rightmargin
2598\installfloatmethod \s!singlecolumn \v!leftedge    \page_one_place_float_leftedge
2599\installfloatmethod \s!singlecolumn \v!rightedge   \page_one_place_float_rightedge
2600\installfloatmethod \s!singlecolumn \v!somewhere   \page_one_place_float_somewhere
2601\installfloatmethod \s!singlecolumn \v!backspace   \page_one_place_float_backspace
2602\installfloatmethod \s!singlecolumn \v!cutspace    \page_one_place_float_cutspace
2603\installfloatmethod \s!singlecolumn \s!tblr        \page_one_place_float_top
2604\installfloatmethod \s!singlecolumn \s!lrtb        \page_one_place_float_top
2605\installfloatmethod \s!singlecolumn \s!tbrl        \page_one_place_float_top
2606\installfloatmethod \s!singlecolumn \s!fxtb        \page_one_place_float_top
2607\installfloatmethod \s!singlecolumn \s!rltb        \page_one_place_float_top
2608\installfloatmethod \s!singlecolumn \s!btlr        \page_one_place_float_bottom
2609\installfloatmethod \s!singlecolumn \s!lrbt        \page_one_place_float_bottom
2610\installfloatmethod \s!singlecolumn \s!btrl        \page_one_place_float_bottom
2611\installfloatmethod \s!singlecolumn \s!rlbt        \page_one_place_float_bottom
2612\installfloatmethod \s!singlecolumn \s!fxbt        \page_one_place_float_bottom
2613\installfloatmethod \s!singlecolumn \s!fixd        \page_one_place_float_force
2614
2615%D Local floats:
2616
2617\installcorenamespace{localfloats}
2618\installcorenamespace{localfloatstack}
2619
2620\installsetuponlycommandhandler \??localfloats {localfloats}
2621
2622\setuplocalfloats
2623  [%\c!before=\blank,
2624   %\c!after=\blank,
2625   \c!inbetween=\blank]
2626
2627\initializeboxstack\??localfloatstack
2628
2629\newcount\c_strc_localfloats_n  \let\noflocalfloats\c_strc_localfloats_n
2630
2631\unexpanded\def\resetlocalfloats
2632  {\global\c_strc_localfloats_n\zerocount
2633   \initializeboxstack\??localfloatstack}
2634
2635\unexpanded\def\somelocalfloat
2636  {\global\advance\c_strc_localfloats_n\plusone
2637   \savebox\??localfloatstack{\number\c_strc_localfloats_n}{\box\floatbox}}
2638
2639\unexpanded\def\getlocalfloats
2640  {\dorecurse\c_strc_localfloats_n
2641     {\ifnum\recurselevel=\plusone % 1\relax
2642        \directlocalfloatsparameter\c!before
2643      \else
2644        \directlocalfloatsparameter\c!inbetween
2645      \fi
2646      \dontleavehmode\hpack{\foundbox\??localfloatstack\recurselevel}% \restorebox...
2647      \ifnum\recurselevel=\c_strc_localfloats_n\relax
2648        \directlocalfloatsparameter\c!after
2649      \fi}}
2650
2651\unexpanded\def\flushlocalfloats
2652  {\getlocalfloats
2653   \resetlocalfloats}
2654
2655% \unexpanded\def\getlocalfloat#1%
2656%   {\normalexpanded{\foundbox{\??localfloatstack}{\number#1}}}% \vbox{\restorebox...}
2657
2658\unexpanded\def\getlocalfloat#1%
2659  {\foundbox\??localfloatstack{\number#1}} % \vbox{\restorebox...}
2660
2661\unexpanded\def\forcelocalfloats
2662  {\let\forcedfloatmethod\v!local}
2663
2664\installfloatmethod \s!singlecolumn \v!local \somelocalfloat
2665\installfloatmethod \s!multicolumn  \v!local \somelocalfloat
2666\installfloatmethod \s!mixedcolumn  \v!local \somelocalfloat
2667\installfloatmethod \s!columnset    \v!local \somelocalfloat
2668
2669\protect \endinput
2670