page-mbk.mklx /size: 9269 b    last modification: 2023-12-21 09:44
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
77\resetboxesincache \s!marginblock \s!marginblock
78
79\c_page_margin_blocks_enabled\conditionalfalse
80
81\let\page_margin_blocks_stop_block\relax
82
83\permanent\tolerant\protected\def\startmarginblock[#tag]%
84  {\begingroup
85   \cdef\currentmarginblock{#tag}%
86   \ifcstok{\marginblockparameter\c!state}\v!start
87     \expandafter\page_margin_blocks_start_block_yes
88   \else
89     \expandafter\page_margin_blocks_start_block_nop
90   \fi}
91
92\permanent\protected\def\stopmarginblock
93  {\page_margin_blocks_stop_block
94   \endgroup}
95
96\def\page_margin_blocks_start_block_yes
97  {%\showmessage\m!layouts4\empty
98   \global\c_page_margin_blocks_enabled\conditionaltrue
99   \dowithnextboxcs
100     \page_margin_blocks_start_block_save
101     \vbox\bgroup
102       \let\page_margin_blocks_stop_block\page_margin_blocks_stop_block_yes
103       \hsize\marginblockparameter\c!width
104       \usealignparameter\marginblockparameter
105       \usemarginblockstyleandcolor\c!style\c!color
106       \begstrut
107       \ignorespaces}
108
109\def\page_margin_blocks_stop_block_yes
110  {\removeunwantedspaces
111   \endstrut
112   \egroup}
113
114\def\page_margin_blocks_start_block_save
115  {\putboxincache\s!marginblock{+}\nextbox}
116
117\def\page_margin_blocks_start_block_nop
118  {%\showmessage\m!layouts5\empty
119   \marginblockparameter\c!before
120   \bgroup
121   \let\page_margin_blocks_stop_block\page_margin_blocks_stop_block_nop
122   \usemarginblockstyleandcolor\c!style\c!color}
123
124\def\page_margin_blocks_stop_block_nop
125  {\egroup
126   \marginblockparameter\c!after}
127
128\permanent\protected\def\checkmarginblocks
129  {\ifconditional\c_page_margin_blocks_enabled\ifcase\getboxcountfromcache\s!marginblock\else
130     \expandafter\page_margin_blocks_check_indeed
131   \fi\fi}
132
133\def\page_margin_blocks_check_indeed
134  {\ifcsname\??marginblocklocation\marginblockparameter\c!location\endcsname
135     \page_margin_blocks_prepare_box
136     \csname\??marginblocklocation\marginblockparameter\c!location\endcsname
137   \else
138     \global\setbox\b_page_margin_blocks\emptybox
139   \fi}
140
141\def\page_margin_blocks_prepare_box
142  {\begingroup
143   \scratchcounter\zerocount
144   \localcontrolledloop \plusone \getboxcountfromcache\s!marginblock \plusone
145     {\scratchcounter\currentloopiterator
146      \setbox\scratchbox\vbox\bgroup
147        \marginblockparameter\c!top
148        \localcontrolledloop \plusone \scratchcounter \plusone
149          {\ifcase\currentloopiterator\or
150             \marginblockparameter\c!before
151           \else
152             \marginblockparameter\c!inbetween
153           \fi
154           \setbox\scratchbox\emptyvbox
155           \ht\scratchbox\getboxhtfromcache\s!marginblock{\the\currentloopiterator}%
156           \dp\scratchbox\getboxdpfromcache\s!marginblock{\the\currentloopiterator}%
157           \box\scratchbox
158           \marginblockparameter\c!after}%
159       \marginblockparameter\c!bottom
160      \egroup
161      \ifdim\htdp\scratchbox>\textheight
162        \advanceby\scratchcounter\minusone
163       %\writestatus{quit}{\the\scratchcounter=>\the\htdp\scratchbox}
164        \quitloop
165      \else
166       %\writestatus{progress}{\the\htdp\scratchbox}
167      \fi}%
168   \ifcase\scratchcounter\else
169     \global\setbox\b_page_margin_blocks_prepared\vbox to \textheight\bgroup
170       \marginblockparameter\c!top
171       \localcontrolledloop \plusone \scratchcounter \plusone
172         {\ifcase\currentloopiterator\or
173            \marginblockparameter\c!before
174          \else
175            \marginblockparameter\c!inbetween
176          \fi
177          \getboxfromcache\s!marginblock{\the\currentloopiterator}\scratchbox
178          \box\scratchbox
179          \marginblockparameter\c!after}%
180       \marginblockparameter\c!bottom
181    \egroup
182    \pruneboxesincache\s!marginblock
183    \ifcase\getboxcountfromcache\s!marginblock\relax
184      \global\c_page_margin_blocks_enabled\conditionaltrue
185    \fi
186  \fi
187  \endgroup}
188
189% inner outer
190
191\permanent\protected\def\page_margin_blocks_place_r_yes
192  {\setbox\b_page_margin_blocks_prepared\hbox to \rightmarginwidth
193     {\marginblockparameter\c!left
194      \box\b_page_margin_blocks_prepared
195      \marginblockparameter\c!right}%
196   \vsmashbox\b_page_margin_blocks_prepared
197   \box\b_page_margin_blocks_prepared}
198
199\permanent\protected\def\page_margin_blocks_place_l_yes
200  {\setbox\b_page_margin_blocks_prepared\hbox to \leftmarginwidth
201     {\marginblockparameter\c!right
202      \box\b_page_margin_blocks_prepared
203      \marginblockparameter\c!left}%
204   \vsmashbox\b_page_margin_blocks_prepared
205   \box\b_page_margin_blocks_prepared}
206
207\permanent\protected\def\page_margin_blocks_place_r_nop{\hskip\rightmarginwidth}
208\permanent\protected\def\page_margin_blocks_place_l_nop{\hskip\leftmarginwidth}
209
210\aliased\let\placerightmarginblock\page_margin_blocks_place_r_nop
211\aliased\let\placeleftmarginblock \page_margin_blocks_place_l_nop
212
213\def\page_margin_blocks_set_r_box{\enforced\aliased\let\placerightmarginblock\page_margin_blocks_place_r_yes}
214\def\page_margin_blocks_set_l_box{\enforced\aliased\let\placeleftmarginblock \page_margin_blocks_place_l_yes}
215
216\letcsname\??marginblocklocation\v!left \endcsname\page_margin_blocks_set_l_box
217\letcsname\??marginblocklocation\v!right\endcsname\page_margin_blocks_set_r_box
218
219\defcsname\??marginblocklocation\v!inmargin\endcsname
220  {\doifbothsidesoverruled
221     \page_margin_blocks_set_r_box
222     \page_margin_blocks_set_r_box
223     \page_margin_blocks_set_l_box}
224
225\defcsname\??marginblocklocation\v!middle\endcsname
226  {\doifbothsidesoverruled
227     \page_margin_blocks_set_r_box
228     \page_margin_blocks_set_l_box
229     \page_margin_blocks_set_r_box}
230
231% margin floats (keyword 'margin' in option list)
232
233\protected\def\page_margin_blocks_process_float
234  {\ifcstok{\marginblockparameter\c!state}\v!start
235     \page_margin_blocks_process_float_yes
236   \else
237     \page_margin_blocks_process_float_nop
238   \fi}
239
240\def\page_margin_blocks_process_float_yes
241  {\global\c_page_margin_blocks_enabled\conditionaltrue
242   \putboxincache\s!marginblock{+}\floatbox}
243
244\def\page_margin_blocks_process_float_nop
245  {\handlefloatmethod\v!here}
246
247\appendtoks
248   \ifcase\getboxcountfromcache\s!marginblock\else
249     \writestatus\m!layouts{beware: there are left-over margin floats!}%
250   \fi
251\to \everystoptext
252
253\permanent\protected\def\flushmarginblocks
254 {\ifconditional\c_page_margin_blocks_enabled
255    \page_otr_command_flush_margin_blocks
256  \fi}
257
258\permanent\tolerant\protected\def\flushallmarginblocks[#1]%
259 {\ifconditional\c_page_margin_blocks_enabled
260    \begingroup
261    \scratchcounterone\getboxcountfromcache\s!marginblock\relax
262    \ifcase\scratchcounterone\else
263      \scratchcountertwo\ifparameter#1\or\numexpr\scratchcounterone-#1+\plusone\relax\else\plusone\fi
264      \localcontrolledloop \scratchcountertwo \scratchcounterone \plusone
265        {\ifcase\currentloopiterator\or
266           \marginblockparameter\c!before
267         \else
268           \marginblockparameter\c!inbetween
269         \fi
270         \getboxfromcache\s!marginblock{\the\currentloopiterator}\scratchbox
271         \box\scratchbox
272         \marginblockparameter\c!after}%
273      \pruneboxesincache\s!marginblock
274    \fi
275    \endgroup
276  \fi}
277
278\protect \endinput
279