page-otr.mkvi /size: 10 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=page-otr,
3
%D version=2012.01.25,
4
%D title=\CONTEXT\ Page Macros,
5
%D subtitle=Output Routines,
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
/
Output
Routines
}
15 16
%D This module will get some of the code from other modules. At the
17
%D same time we provide a bit more control.
18 19
% When issuing two \par\penalty-\plustenthousand's, only the first
20
% triggers the otr. Is this an obscure feature or an optimization?
21 22
\registerctxluafile
{
page
-
otr
}{}
23 24
\unprotect
25 26
\let
\triggerpagebuilder
\clf_triggerpagebuilder
27 28
\def
\m!otr
{
otr
}
% todo
29 30
\installcorenamespace
{
outputroutine
}
31 32
\installswitchcommandhandler
\??outputroutine
{
outputroutine
}
\??outputroutine
33 34
\newtoks
\t_page_otr_commands
35
\newtoks
\t_page_otr_tracers
36 37
\unexpanded
\def
\defineoutputroutinecommand
[#
name
]
% doing multiple on one go saves syncing
38
{
\processcommalist
[#
name
]
\page_otr_commands_define
}
39 40
\unexpanded
\def
\page_otr_commands_define
#
name
%
41
{
\ifcsname
#
name
\endcsname
\else
42
\expandafter\let\csname
#
name
\endcsname\relax
43
\normalexpanded
{
\t_page_otr_commands
{
\the
\t_page_otr_commands
\noexpand
\page_otr_commands_process
{
#
name
}}}
%
44
\fi
}
45 46
\let
\page_otr_commands_process
\gobbleoneargument
47 48
\appendtoks
49
\let
\page_otr_commands_process
\page_otr_specifics_preset
50
\the
\t_page_otr_commands
51
\let
\page_otr_commands_process
\gobbleoneargument
52
\to
\everyswitchoutputroutine
53 54
\unexpanded
\def
\page_otr_specifics_preset
#
name
%
55
{
\edef
\page_otr_specifics_command
{
\directoutputroutineparameter
{
#
name
}}
% no inheritance of commands
56
\ifx
\page_otr_specifics_command
\empty
57
\writestatus
{
\currentoutputroutine
}{
-
\expandafter
\strippedcsname
\csname
#
name
\endcsname
}
%
58
\expandafter\let\csname
#
name
\endcsname\relax
59
\else
60
\writestatus
{
\currentoutputroutine
}{
+
\expandafter
\strippedcsname
\csname
#
name
\endcsname
}
%
61
\expandafter\let\csname
#
name
\expandafter\endcsname
\page_otr_specifics_command
62
\fi
}
63 64
\unexpanded
\def
\page_otr_specifics_preset_normal
#
name
%
65
{
\edef
\page_otr_specifics_command
{
\directoutputroutineparameter
{
#
name
}}
% no inheritance of commands
66
\ifx
\page_otr_specifics_command
\empty
67
\expandafter\let\csname
#
name
\endcsname\relax
68
\else
69
\expandafter\let\csname
#
name
\expandafter\endcsname
\page_otr_specifics_command
70
\fi
}
71 72
\unexpanded
\def
\page_otr_specifics_preset_traced
#
name
%
73
{
\edef
\page_otr_specifics_command
{
\directoutputroutineparameter
{
#
name
}}
% no inheritance of commands
74
\ifx
\page_otr_specifics_command
\empty
75
\writestatus
{
\currentoutputroutine
}{
preset
:
-
\expandafter
\strippedcsname
\csname
#
name
\endcsname
}
%
76
\expandafter\let\csname
#
name
\endcsname\relax
77
\else
78
\writestatus
{
\currentoutputroutine
}{
preset
:
+
\expandafter
\strippedcsname
\csname
#
name
\endcsname
}
%
79
\expandafter\let\csname
#
name
\expandafter\endcsname
\page_otr_specifics_command
80
\fi
}
81 82
\let
\page_otr_specifics_preset
\page_otr_specifics_preset_normal
83 84
\unexpanded
\def
\traceoutputroutines
85
{
\the
\t_page_otr_tracers
}
86 87
\appendtoks
88
\let
\page_otr_specifics_preset
\page_otr_specifics_preset_traced
89
\to
\t_page_otr_tracers
90 91
%D We have a couple of output routines and the default one is
92
%D the single column routine. Then there is a multicolumn variant
93
%D that can be used mixed, and a columnset variant that is more
94
%D exclusive.
95 96
\installcorenamespace
{
otrtriggers
}
97 98
\newconstant
\c_page_otr_eject_penalty
\c_page_otr_eject_penalty
-
\plustenthousand
99
\newconstant
\c_page_otr_super_penalty
\c_page_otr_super_penalty
-
\plustwentythousand
100
\newcount
\c_page_otr_trigger_penalty
\c_page_otr_trigger_penalty
-
1
0
0
0
1
0
101 102
\newif
\ifinotr
% we keep this (name) for old times sake
103 104
\unexpanded
\def
\page_otr_message_b
{
\page_otr_message_s
+
}
105
\unexpanded
\def
\page_otr_message_e
{
\page_otr_message_s
-
}
106 107
\unexpanded
\def
\page_otr_message_s
#
sign
#
what
%
108
{
\writestatus
109
\currentoutputroutine
110
{
#
sign
\space
\space
111
#
what
\space
\space
112
p
:
\the\outputpenalty
,
\space
113
r
:
\the
\realpageno
,
\space
114
c
:
\number
\mofcolumns
,
\space
115
v
:
\the\vsize
,
\space
116
g
:
\the\pagegoal
,
\space
117
t
:
\the\pagetotal
118
\ifdim
\pagetotal
>
\pagegoal
119
,
\space
120
d
:
\the\dimexpr\pagetotal
-
\pagegoal\relax
121
\fi
}}
122 123
\unexpanded
\def
\page_otr_trigger
#
penalty
%
124
{
\begingroup
125
\par
126
\penalty
#
penalty
%
127
\endgroup
}
128 129
\unexpanded
\def
\installoutputroutine
#
invoke
#
action
% \invoke \action
130
{
\global\advance
\c_page_otr_trigger_penalty
\minusone
131
\edef
#
invoke
{
\page_otr_trigger
{
\number
\c_page_otr_trigger_penalty
}}
%
132
\setvalue
{
\??otrtriggers
\number
\c_page_otr_trigger_penalty
}{
#
action
}}
133 134
\unexpanded
\def
\page_otr_triggered_output_routine_traced
135
{
\ifcsname
\??otrtriggers
\the\outputpenalty\endcsname
136
\page_otr_message_b
{
special
}
%
137
\csname
\??otrtriggers
\the\outputpenalty\endcsname
% \lastnamedcs can be gone
138
\page_otr_message_e
{
special
}
%
139
\else
140
\page_otr_message_b
{
normal
}
%
141
\page_otr_command_routine
142
\page_otr_message_e
{
normal
}
%
143
\fi
}
144 145
\unexpanded
\def
\page_otr_triggered_output_routine_normal
146
{
\ifcsname
\??otrtriggers
\the\outputpenalty\endcsname
147
\lastnamedcs
148
\else
149
\page_otr_command_routine
150
\fi
}
151 152
\let
\page_otr_triggered_output_routine
\page_otr_triggered_output_routine_normal
153 154
\appendtoks
155
\let
\page_otr_triggered_output_routine
\page_otr_triggered_output_routine_traced
156
\to
\t_page_otr_tracers
157 158
%D The real routine handler:
159 160
\ifdefined
\everybeforeoutput
\else
\newtoks
\everybeforeoutput
\fi
161
\ifdefined
\everyafteroutput
\else
\newtoks
\everyafteroutput
\fi
162 163
\def
\page_otr_set_engine_output_routine
#
content
%
164
{
\global\output
165
{
\inotrtrue
166
\the
\everybeforeoutput
167
#
content
\relax
168
\the
\everyafteroutput
}}
169 170
% Just as fuzzy (and in 'one' we are okay with \aftergroup anyway):
171
%
172
% \ifdefined\everybeforeoutputgroup \else \newtoks\everybeforeoutputgroup \fi
173
% \ifdefined\everyafteroutputgroup \else \newtoks\everyafteroutputgroup \fi
174
%
175
% \def\page_otr_set_engine_output_routine#content%
176
% {\the\everybeforeoutputgroup
177
% \global\output
178
% {\inotrtrue
179
% \the\everybeforeoutput
180
% #content\relax
181
% \the\everyafteroutput
182
% \aftergroup\the\aftergroup\everyafteroutputgroup}}
183
%
184
% \appendtoks
185
% \ifnum\c_page_postponed_mode=\plusone
186
% \page_postponed_blocks_flush % and then not in \page_otr_construct_and_shipout
187
% \fi
188
% \to \everyafteroutputgroup
189 190
\page_otr_set_engine_output_routine
\page_otr_triggered_output_routine
191 192
\installoutputroutine
\synchronizeoutput
% use \triggerpagebuilder instead
193
{
\ifvoid
\normalpagebox
\else
194
\unvbox
\normalpagebox
195
% not \pagediscards as it does more harm than good
196
\fi
}
197 198
\installoutputroutine
\discardpage
199
{
\setbox
\scratchbox
\box
\normalpagebox
}
200 201
% todo: \resetpagebreak -> everyejectpage
202 203
\def
\page_otr_trigger_output_routine
204
{
\par
205
\ifvmode
206
\penalty
\c_page_otr_eject_penalty
207
\fi
208
\resetpagebreak
}
209 210
\def
\page_otr_fill_and_eject_page
211
{
\par
212
\ifvmode
213
\vfill
214
\penalty
\c_page_otr_eject_penalty
215
\fi
216
\resetpagebreak
}
217 218
\def
\page_otr_eject_page
219
{
\par
220
\ifvmode
221
\ifdim
\pagetotal
>
\pagegoal
\else
222
\normalvfil
223
\fi
224
\penalty
\c_page_otr_eject_penalty
225
\fi
226
\resetpagebreak
}
227 228
\def
\page_otr_eject_page_and_flush_inserts
% can be an installed one
229
{
\par
230
\ifvmode
231
\ifdim
\pagetotal
>
\pagegoal
\else
232
\normalvfil
233
\fi
234
\penalty
\c_page_otr_super_penalty
235
\fi
236
\resetpagebreak
}
237 238
\def
\page_otr_check_for_pending_inserts
239
{
\ifnum
\outputpenalty
>
\c_page_otr_super_penalty
\else
240
\ifnum
\insertpenalties
>
\zerocount
241
% something is being held over so we force a new page
242
\page_otr_force_another_page
243
\fi
244
\fi
}
245 246
\def
\page_otr_force_another_page
247
{
% we should actually remove the dummy line in the otr
248
\hpack
to
\hsize
{}
%
249
\kern
-
\topskip
250
\nobreak
251
\vfill
252
\penalty
\c_page_otr_super_penalty
253
\resetpagebreak
}
254 255
%D For those who've read the plain \TEX\ book, we provide the next
256
%D macro:
257 258
\unexpanded
\def
\bye
259
{
\writestatus
\m!system
{
Sorry
,
you
'
re
not
done
yet
,
so
no
goodbye
!
}}
260 261
%D We define a few constants because that (1) provides some checking
262
%D and (2) is handier when aligning definitions (checks nicer). Most
263
%D routines will use ard codes names but sometimes we want to adapt,
264
%D which is why we have these:
265 266
\definesystemconstant
{
page
_
otr
_
command
_
routine
}
267
\definesystemconstant
{
page
_
otr
_
command
_
package
_
contents
}
268
\definesystemconstant
{
page
_
otr
_
command
_
set
_
vsize
}
269
\definesystemconstant
{
page
_
otr
_
command
_
set
_
hsize
}
270
\definesystemconstant
{
page
_
otr
_
command
_
synchronize
_
hsize
}
271
\definesystemconstant
{
page
_
otr
_
command
_
next
_
page
}
272
\definesystemconstant
{
page
_
otr
_
command
_
next
_
page
_
and
_
inserts
}
273
\definesystemconstant
{
page
_
otr
_
command
_
set
_
top
_
insertions
}
274
\definesystemconstant
{
page
_
otr
_
command
_
set
_
bottom
_
insertions
}
275
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
top
_
insertions
}
276
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
bottom
_
insertions
}
277
\definesystemconstant
{
page
_
otr
_
command
_
check
_
if
_
float
_
fits
}
278
\definesystemconstant
{
page
_
otr
_
command
_
set
_
float
_
hsize
}
279
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
float
_
box
}
280
\definesystemconstant
{
page
_
otr
_
command
_
side
_
float
_
output
}
281
\definesystemconstant
{
page
_
otr
_
command
_
synchronize
_
side
_
floats
}
282
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
floats
}
283
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
side
_
floats
}
284
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
saved
_
floats
}
285
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
all
_
floats
}
286
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
margin
_
blocks
}
287
\definesystemconstant
{
page
_
otr
_
command
_
test
_
column
}
288
\definesystemconstant
{
page
_
otr
_
command
_
flush
_
facing
_
floats
}
289 290
\definesystemconstant
{
singlecolumn
}
291
\definesystemconstant
{
multicolumn
}
% will move
292
\definesystemconstant
{
columnset
}
% will move
293
\definesystemconstant
{
pagecolumn
}
% will move
294 295
\defineoutputroutinecommand
296
[
\s!page_otr_command_routine
,
297
\s!page_otr_command_package_contents
,
298
\s!page_otr_command_set_vsize
,
299
\s!page_otr_command_set_hsize
,
300
\s!page_otr_command_synchronize_hsize
,
% for columns of different width
301
\s!page_otr_command_next_page
,
302
\s!page_otr_command_next_page_and_inserts
,
303
\s!page_otr_command_set_top_insertions
,
304
\s!page_otr_command_set_bottom_insertions
,
305
\s!page_otr_command_flush_top_insertions
,
306
\s!page_otr_command_flush_bottom_insertions
,
307
\s!page_otr_command_check_if_float_fits
,
308
\s!page_otr_command_set_float_hsize
,
309
\s!page_otr_command_flush_float_box
,
310
\s!page_otr_command_side_float_output
,
% name will change as will hooks
311
\s!page_otr_command_synchronize_side_floats
,
312
\s!page_otr_command_flush_floats
,
313
\s!page_otr_command_flush_side_floats
,
314
\s!page_otr_command_flush_saved_floats
,
315
\s!page_otr_command_flush_all_floats
,
316
\s!page_otr_command_flush_margin_blocks
,
317
\s!page_otr_command_test_column
,
318
\s!page_otr_command_flush_facing_floats
]
319 320
\appendtoks
321
\setupoutputroutine
[
\s!singlecolumn
]
%
322
\to
\everydump
323 324
\protect
\endinput
325