page-mbk.mklx /size: 9479 b    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=page-mbk,   % was part of page-mis.mkiv / 2008.11.17
3%D        version=2011.11.23, % was part of page-flt.tex  / 2000.10.20
4%D          title=\CONTEXT\ Page Macros,
5%D       subtitle=Margin Floats,
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\writestatus{loading}{ConTeXt Page Macros / Margin Floats}
15
16\unprotect
17
18%D This is an old mechanism that is quite independent of other floats. There is for
19%D instance no save/restore used here. When there is need (and demand) we can use
20%D the float cache and then flush them in the text when they are left over. On the
21%D other hand, margin float are somewhat manual so it does not make too much sense
22%D to complicate the code. As an alternative users can fall back on margin texts:
23%D they do stack but don't float.
24%D
25%D \starttyping
26%D \dorecurse{9} {
27%D   \placefigure[margin]{#1}{}
28%D   \input ward
29%D }
30%D \page \null % will flush them
31%D \stoptyping
32
33% status=start: in margin
34% status=stop : in text
35%
36% todo: flush margin floats at end of text
37% todo: separate boxes for left and right
38
39\installcorenamespace{marginblock}
40\installcorenamespace{marginblocklocation}
41
42\installcommandhandler \??marginblock {marginblock} \??marginblock
43
44\aliased\let\setupmarginblocks\setupmarginblock
45
46\newconditional\c_page_margin_blocks_enabled % not really needed as we can check each time
47\newconditional\c_page_margin_blocks_present
48
49\newbox        \b_page_margin_blocks
50\newbox        \b_page_margin_blocks_prepared
51
52\appendtoks
53   \ifcstok{\rootmarginblockparameter\c!state}\v!start
54     \c_page_margin_blocks_enabled\conditionaltrue
55   \else
56     \c_page_margin_blocks_enabled\conditionalfalse
57   \fi
58\to \everysetupmarginblock
59
60\setupmarginblocks
61  [\c!state=\v!start,
62   \c!location=\v!inmargin,
63   \c!width=\rightmarginwidth,
64  %\c!style=,
65  %\c!color=,
66  %\c!align=,
67  %\c!left=,
68  %\c!right=,
69  %\c!top=,
70  %\c!before=,
71  %\c!after=,
72   \c!inbetween=\blank,
73   \c!bottom=\vfill]
74
75\definesystemconstant{marginblock}
76\definesystemconstant{leftmarginblock}
77\definesystemconstant{rightmarginblock}
78
79\resetboxesincache \s!marginblock      \s!marginblock
80\resetboxesincache \s!leftmarginblock  \s!leftmarginblock
81\resetboxesincache \s!rightmarginblock \s!rightmarginblock
82
83\c_page_margin_blocks_enabled\conditionalfalse
84
85\let\page_margin_blocks_stop_block\relax
86
87\permanent\tolerant\protected\def\startmarginblock[#tag]%
88  {\begingroup
89   \cdef\currentmarginblock{#tag}%
90   \ifcstok{\marginblockparameter\c!state}\v!start
91     \expandafter\page_margin_blocks_start_block_yes
92   \else
93     \expandafter\page_margin_blocks_start_block_nop
94   \fi}
95
96\permanent\protected\def\stopmarginblock
97  {\page_margin_blocks_stop_block
98   \endgroup}
99
100\def\page_margin_blocks_start_block_yes
101  {%\showmessage\m!layouts4\empty
102   \global\c_page_margin_blocks_enabled\conditionaltrue
103   \dowithnextboxcs
104     \page_margin_blocks_start_block_save
105     \vbox\bgroup
106       \let\page_margin_blocks_stop_block\page_margin_blocks_stop_block_yes
107       \hsize{\marginblockparameter\c!width}%
108       \usealignparameter\marginblockparameter
109       \usemarginblockstyleandcolor\c!style\c!color
110       \begstrut
111       \ignorespaces}
112
113\def\page_margin_blocks_stop_block_yes
114  {\removeunwantedspaces
115   \endstrut
116   \egroup}
117
118\def\page_margin_blocks_start_block_save
119  {\putboxincache\s!marginblock{+}\nextbox}
120
121\def\page_margin_blocks_start_block_nop
122  {%\showmessage\m!layouts5\empty
123   \marginblockparameter\c!before
124   \bgroup
125   \let\page_margin_blocks_stop_block\page_margin_blocks_stop_block_nop
126   \usemarginblockstyleandcolor\c!style\c!color}
127
128\def\page_margin_blocks_stop_block_nop
129  {\egroup
130   \marginblockparameter\c!after}
131
132\permanent\protected\def\checkmarginblocks
133  {\ifconditional\c_page_margin_blocks_enabled\ifcase\getboxcountfromcache\s!marginblock\else
134     \expandafter\page_margin_blocks_check_indeed
135   \fi\fi}
136
137\def\page_margin_blocks_check_indeed
138  {\ifcsname\??marginblocklocation\marginblockparameter\c!location\endcsname
139     \page_margin_blocks_prepare_box
140     \csname\??marginblocklocation\marginblockparameter\c!location\endcsname
141   \else
142     \global\setbox\b_page_margin_blocks\emptybox
143   \fi}
144
145\def\page_margin_blocks_prepare_box
146  {\begingroup
147   \scratchcounter\zerocount
148   \localcontrolledloop \plusone \getboxcountfromcache\s!marginblock \plusone
149     {\scratchcounter\currentloopiterator
150      \setbox\scratchbox\vbox\bgroup
151        \marginblockparameter\c!top
152        \localcontrolledloop \plusone \scratchcounter \plusone
153          {\ifcase\currentloopiterator\or
154             \marginblockparameter\c!before
155           \else
156             \marginblockparameter\c!inbetween
157           \fi
158           \setbox\scratchbox\emptyvbox
159           \ht\scratchbox\getboxhtfromcache\s!marginblock{\the\currentloopiterator}%
160           \dp\scratchbox\getboxdpfromcache\s!marginblock{\the\currentloopiterator}%
161           \box\scratchbox
162           \marginblockparameter\c!after}%
163       \marginblockparameter\c!bottom
164      \egroup
165      \ifdim\htdp\scratchbox>\textheight
166        \advanceby\scratchcounter\minusone
167       %\writestatus{quit}{\the\scratchcounter=>\the\htdp\scratchbox}
168        \quitloop
169      \else
170       %\writestatus{progress}{\the\htdp\scratchbox}
171      \fi}%
172   \ifcase\scratchcounter\else
173     \global\setbox\b_page_margin_blocks_prepared\vbox to \textheight\bgroup
174       \marginblockparameter\c!top
175       \localcontrolledloop \plusone \scratchcounter \plusone
176         {\ifcase\currentloopiterator\or
177            \marginblockparameter\c!before
178          \else
179            \marginblockparameter\c!inbetween
180          \fi
181          \getboxfromcache\s!marginblock{\the\currentloopiterator}\scratchbox
182          \box\scratchbox
183          \marginblockparameter\c!after}%
184       \marginblockparameter\c!bottom
185    \egroup
186    \pruneboxesincache\s!marginblock
187    \ifcase\getboxcountfromcache\s!marginblock\relax
188      \global\c_page_margin_blocks_enabled\conditionaltrue
189    \fi
190  \fi
191  \endgroup}
192
193% inner outer
194
195\permanent\protected\def\page_margin_blocks_place_r_yes
196  {\setbox\b_page_margin_blocks_prepared\hbox to \rightmarginwidth
197     {\marginblockparameter\c!left
198      \box\b_page_margin_blocks_prepared
199      \marginblockparameter\c!right}%
200   \vsmashbox\b_page_margin_blocks_prepared
201   \box\b_page_margin_blocks_prepared}
202
203\permanent\protected\def\page_margin_blocks_place_l_yes
204  {\setbox\b_page_margin_blocks_prepared\hbox to \leftmarginwidth
205     {\marginblockparameter\c!right
206      \box\b_page_margin_blocks_prepared
207      \marginblockparameter\c!left}%
208   \vsmashbox\b_page_margin_blocks_prepared
209   \box\b_page_margin_blocks_prepared}
210
211\permanent\protected\def\page_margin_blocks_place_r_nop{\hskip\rightmarginwidth}
212\permanent\protected\def\page_margin_blocks_place_l_nop{\hskip\leftmarginwidth}
213
214\aliased\let\placerightmarginblock\page_margin_blocks_place_r_nop
215\aliased\let\placeleftmarginblock \page_margin_blocks_place_l_nop
216
217\def\page_margin_blocks_set_r_box{\enforced\aliased\let\placerightmarginblock\page_margin_blocks_place_r_yes}
218\def\page_margin_blocks_set_l_box{\enforced\aliased\let\placeleftmarginblock \page_margin_blocks_place_l_yes}
219
220\letcsname\??marginblocklocation\v!left \endcsname\page_margin_blocks_set_l_box
221\letcsname\??marginblocklocation\v!right\endcsname\page_margin_blocks_set_r_box
222
223\defcsname\??marginblocklocation\v!inmargin\endcsname
224  {\doifbothsidesoverruled
225     \page_margin_blocks_set_r_box
226     \page_margin_blocks_set_r_box
227     \page_margin_blocks_set_l_box}
228
229\defcsname\??marginblocklocation\v!middle\endcsname
230  {\doifbothsidesoverruled
231     \page_margin_blocks_set_r_box
232     \page_margin_blocks_set_l_box
233     \page_margin_blocks_set_r_box}
234
235% margin floats (keyword 'margin' in option list)
236
237\protected\def\page_margin_blocks_process_float
238  {\ifcstok{\marginblockparameter\c!state}\v!start
239     \page_margin_blocks_process_float_yes
240   \else
241     \page_margin_blocks_process_float_nop
242   \fi}
243
244\def\page_margin_blocks_process_float_yes
245  {\global\c_page_margin_blocks_enabled\conditionaltrue
246   \putboxincache\s!marginblock{+}\floatbox}
247
248\def\page_margin_blocks_process_float_nop
249  {\handlefloatmethod\v!here}
250
251\appendtoks
252   \ifcase\getboxcountfromcache\s!marginblock\else
253     \writestatus\m!layouts{beware: there are left-over margin floats!}%
254   \fi
255\to \everystoptext
256
257\permanent\protected\def\flushmarginblocks
258 {\ifconditional\c_page_margin_blocks_enabled
259    \page_otr_command_flush_margin_blocks
260  \fi}
261
262\permanent\tolerant\protected\def\flushallmarginblocks[#1]%
263  {\ifconditional\c_page_margin_blocks_enabled
264     \begingroup
265     \scratchcounterone\getboxcountfromcache\s!marginblock\relax
266     \ifcase\scratchcounterone\else
267       \scratchcountertwo\ifparameter#1\or{\scratchcounterone-#1+\plusone}\else\plusone\fi
268       \localcontrolledloop \scratchcountertwo \scratchcounterone \plusone
269         {\ifcase\currentloopiterator\or
270            \marginblockparameter\c!before
271          \else
272            \marginblockparameter\c!inbetween
273          \fi
274          \getboxfromcache\s!marginblock{\the\currentloopiterator}\scratchbox
275          \box\scratchbox
276          \marginblockparameter\c!after}%
277       \pruneboxesincache\s!marginblock
278     \fi
279     \endgroup
280   \fi}
281
282\protect \endinput
283