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