summaryrefslogtreecommitdiff
path: root/macros/optex/base/output.opm
blob: 5bb93c24773cfd873ac3f0df19993a4ba60e4ccf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \nopagenumbers {Output routine <2021-02-25>} % preloaded in format

   \_doc -----------------------------
   \`\_optexoutput` is the default output routine. You can create another...
   \_cod -----------------------------

\_output={\_optexoutput}
\_def \_optexoutput{\_begoutput \_shipout\_completepage \_endoutput}

   \_doc -----------------------------
   Default \`\_begoutput` and \`\_endoutput` is defined.
   If you need another functionality implemented in the output routine, you can
   \^`\addto``\_begoutput{...}` or \^`\addto``\_endoutput{...}`. The settings
   here are local in the `\output` group.

   The \`\_prepoffsets` can set `\hoffset` differently for the left or right
   page. It is re-defined by the \^`\margins` macro..

   The \^`\_regmark` tokens list includes accumulated `#2` from the \^`\regmacro`.
   Logos and other macros are re-defined here (locally) for their usage
   in headlines or footlines.
   \_cod -----------------------------

\_def \_begoutput{\_incr\_gpageno
   \_immediate\_wref\_Xpage{{\_the\_gpageno}{\_folio}}%
   \_setxhsize \_prepoffsets \_the\_regmark}
\_def \_endoutput{\_advancepageno
   {\_globaldefs=1 \_the\_nextpages \_nextpages={}}%
   \_ifnum\_outputpenalty>-20000 \_else\_dosupereject\_fi
}
\_def \_prepoffsets {}

   \_doc -----------------------------
   The `\hsize` value can be changed at various places in the document but
   we need to have a constant value \`\_xhsize` in the output routine
   (for headlines and footlines, for instance). This value is set
   from the current value of `\hsize` when \`\_setxhsize` macro is called.
   This macro destroys itself, so the value is set only once. Typically it is
   done in \^`\margins` macro or
   when first \^`\_optexoutput` routine is called (see \^`\_begoutput`).
   Or it is called at the begining of the \^`\begtt`...`\endtt` environment before
   `\hsize` value is eventually changed by the user in this environment.
   \_cod -----------------------------

\_newdimen \_xhsize
\_def\_setxhsize {\_global\_xhsize=\_hsize \_global\_let\_setxhsize=\_relax}

   \_doc -----------------------------
   \`\gpageno` counts pages from one in the whole document
   \_cod -----------------------------

\_newcount\_gpageno
\_public \gpageno ;

   \_doc -----------------------------
   The \`\_completepage` is similar to what plain \TeX/ does in its output routine.
   New is only \`\_backgroundbox`. It is `\vbox` with zero height with its
   contents (from \^`\pgbackground`) extended down. It is shifted directly to the
   left-upper corner of the paper.

   The \`\_ensureblack` sets the typesetting of its parameter locally to `\Black`
   color. We needn't do this if colors are never used in the document. So,
   the default value of the `\_ensureblack` macro is empty. But the first usage of
   color macros in the document re-defines `\_ensureblack`.
   See the section~\ref[colors] for more details.
   \_cod -----------------------------

\_def\_completepage{\_vbox{%
     \_istoksempty \_pgbackground
        \_iffalse \_ensureblack{\_backgroundbox{\_the\_pgbackground}}\_nointerlineskip \_fi
     \_ensureblack{\_makeheadline}%
     \_vbox to\_vsize {\_boxmaxdepth=\_maxdepth \_pagecontents}% \pagebody in plainTeX
     \_ensureblack{\_makefootline}}%
}
\_def \_ensureblack #1{#1} % will be re-defined by color macros
\_let \_openfnotestack = \_relax % will be re-defined by color macros
\_def \_backgroundbox #1{\_moveleft\_hoffset\_vbox to\_zo{\_kern-\_voffset #1\_vss}}

   \_doc -----------------------------
   \`\_makeheadline` creates `\vbox to0pt` with its contents (the \^`\headline`)
   shifted by \^`\headlinedist` up.
   \_cod -----------------------------

\_def\_makeheadline {\_istoksempty \_headline \_iffalse
   \_vbox to\_zo{\_vss
                 \_baselineskip=\_headlinedist \_lineskiplimit=-\_maxdimen
                 \_hbox to\_xhsize{\_the\_headline}\_hbox{}}\_nointerlineskip
   \_fi
}

   \_doc -----------------------------
   The \`\_makefootline` appends the \^`\footline` to the page-body box.
   \_cod -----------------------------

\_def\_makefootline{\_istoksempty \_footline \_iffalse
      \_baselineskip=\_footlinedist
      \_lineskiplimit=-\_maxdimen \_hbox to\_xhsize{\_the\_footline}
   \_fi
}

   \_doc -----------------------------
   The \`\_pagecontents` is similar as in plain \TeX/. The only differnece is
   that the \`\_pagedest` is inserted at the top of `\_pagecontents` and
   \^`\_ensureblack` is applied to the \^`\topins` and \^`\footins` material.\nl
   The \`\_footnoterule` is defined here.
   \_cod -----------------------------

\_def\_pagecontents{\_pagedest % destination of the page
  \_ifvoid\_topins \_else \_ensureblack{\_unvbox\_topins}\_fi
  \_dimen0=\_dp255 \_unvbox255 % open up \box255
  \_ifvoid\_footins \_else % footnote info is present
    \_vskip\_skip\_footins
    \_ensureblack{\_footnoterule \_openfnotestack \_unvbox\_footins}\_fi
  \_kern-\_dimen0 \_vskip \_pgbottomskip
}
\_def \_pagedest {{\_def\_destheight{25pt}\_dest[pg:\_the\_gpageno]}}
\_def \_footnoterule {\_kern-3pt \_hrule width 2truein \_kern 2.6pt }

   \_doc -----------------------------
   \`\pageno`, \`\folio`, \`\nopagenumbers`, \`\advancepageno`
   and \`\normalbottom`
   used in the context of the output routine
   from plain \TeX/ is defined here.
   Only the \`\raggedbottom` macro is defined differently. We use the
   \^`\pgbottomskip` register here which is set to 0\,pt by default.
   \_cod -----------------------------

\_countdef\_pageno=0 \_pageno=1 % first page is number 1
\_def \_folio {\_ifnum\_pageno<0 \_romannumeral-\_pageno \_else \_number\_pageno \_fi}
\_def \_nopagenumbers {\_footline={}}
\_def \_advancepageno {%
   \_ifnum\_pageno<0 \_decr\_pageno \_else \_incr\_pageno \_fi
} % increase |pageno|
\_def \_raggedbottom {\_topskip=\_dimexpr\_topskip plus60pt \_pgbottomskip=0pt plus1fil\_relax}
\_def \_normalbottom {\_topskip=\_dimexpr\_topskip \_pgbottomskip=0pt\_relax}

\_public \pageno \folio \nopagenumbers \advancepageno \raggedbottom \normalbottom ;

   \_doc -----------------------------
   Macros for footnotes are the same as in plain \TeX. There is only one
   difference: \`\vfootnote` is implemented as \`\_opfootnote` with empty
   parameter `#1`. This parameter should do local settings inside
   the \`\footins` group and it does it when `\fnote` macro is used.\nl
   The `\_opfootnote` nor `\vfootnote` don't take the footnote text
   as a parameter. This is due to a user can do catcode settings (like inline
   verbatim) in the footnote text. This idea is adapted from plain \TeX.\nl
   The \`\footnote` and \`\footstrut` is defined as in plain \TeX/.
   \_cod -----------------------------

\_newinsert\_footins
\_def \_footnote #1{\_let\_osf=\_empty % parameter #2 (the text) is read later
   \_ifhmode \_edef\_osf{\_spacefactor\_the\_spacefactor}\/\_fi
  #1\_osf\_vfootnote{#1}}
\_def\_vfootnote{\_opfootnote{}}
\_def \_opfootnote #1#2{\_insert\_footins\_bgroup
  \_interlinepenalty=\_interfootnotelinepenalty
  \_leftskip=\_zo \_rightskip=\_zo \_spaceskip=\_zo \_xspaceskip=\_zo \_relax
  \_let\_colorstackcnt=\_fnotestack % special color stack for footnotes
  #1\_relax % local settings used by \fnote macro
  \_splittopskip=\_ht\_strutbox % top baseline for broken footnotes
  \_splitmaxdepth=\_dp\_strutbox \_floatingpenalty=20000
  \_textindent{#2}\_footstrut
  \_isnextchar \_bgroup
     {\_bgroup \_aftergroup\_vfootA \_afterassignment\_ignorespaces \_let\_next=}{\_vfootB}%
}
\_def\_vfootA{\_unskip\_strut\_isnextchar\_colorstackpop\_closefncolor\_vfootF}
\_def\_vfootB #1{#1\_unskip\_strut\_vfootF}
\_def\_vfootF{\_egroup} % close \_insert\_footins\_bgroup
\_def\_closefncolor#1{#1\_isnextchar\_colorstackpop\_closefncolor\_vfootF}
\_def \_footstrut {\_vbox to\_splittopskip{}}
\_skip\_footins=\_bigskipamount % space added when footnote is present
\_count\_footins=1000 % footnote magnification factor (1 to 1)
\_dimen\_footins=8in % maximum footnotes per page
\_public
   \footins \footnote \vfootnote \footstrut ;

   \_doc -----------------------------
   The \`\topins` macros
   \`\topinsert`, \`\midinsert`, \`\pageinsert`, \`\endinsert`
   are the same as in plain \TeX/.
   \_cod -----------------------------

\_newinsert\_topins
\_newifi\_ifupage \_newifi\_ifumid
\_def \_topinsert {\_umidfalse \_upagefalse \_oins}
\_def \_midinsert {\_umidtrue \_oins}
\_def \_pageinsert {\_umidfalse \_upagetrue \_oins}
\_skip\_topins=\_zoskip % no space added when a topinsert is present
\_count\_topins=1000 % magnification factor (1 to 1)
\_dimen\_topins=\_maxdimen % no limit per page
\_def \_oins {\_par \_begingroup\_setbox0=\_vbox\_bgroup} % start a \_vbox
\_def \_endinsert {\_par\_egroup % finish the \_vbox
  \_ifumid \_dimen0=\_ht0 \_advance\_dimen0 by\_dp0 \_advance\_dimen0 by\_baselineskip
    \_advance\_dimen0 by\_pagetotal \_advance\_dimen0 by-\_pageshrink
    \_ifdim\_dimen0>\_pagegoal \_umidfalse \_upagefalse \_fi \_fi
  \_ifumid \_bigskip \_box0 \_bigbreak
  \_else \_insert \_topins {\_penalty100 % floating insertion
    \_splittopskip=0pt
    \_splitmaxdepth=\_maxdimen \_floatingpenalty=0
    \_ifupage \_dimen0=\_dp0
    \_vbox to\_vsize {\_unvbox0 \_kern-\_dimen0}% depth is zero
    \_else \_box0 \_nobreak \_bigskip \_fi}\_fi\_endgroup}

\_public \topins \topinsert \midinsert \pageinsert \endinsert ;

   \_doc -----------------------------
   The \`\draft` macro is an example of usage `\_pgbackground` to create
   watercolor marks.
   \_cod -----------------------------

\_def \_draft {\_pgbackground={\_draftbox{\_draftfont DRAFT}}%
   \_fontdef\_draftfont{\_setfontsize{at10pt}\_bf}%
   \_global\_let\_draftfont=\_draftfont
}
\_def \_draftbox #1{\_setbox0=\_hbox{#1}%
   \_kern.5\_vsize \_kern\_voffset \_kern4.5\_wd0
   \_hbox to0pt{\_kern.5\_xhsize \_kern\_hoffset \_kern-2\_wd0
   \_pdfsave \_pdfrotate{55}\_pdfscale{10}{10}%
   \_hbox to0pt{\_localcolor\_setgreycolor{.8}\_box0\_hss}%
   \_pdfrestore
   \_hss}%
}
\_public \draft ;

\_endcode % -------------------------------------


The output routine \^`\_optexoutput` is similar as in plain \TeX. It does:

\begitems
* \^`\_begoutput` which does:
  \begitems
  * increments \^`\gpageno`,
  * prints `\_Xpage{<gpageno>}{<pageno>}` to the `.ref` file
    (if \^`\openref` is active),
  * calculates `\hoffset`,
  * sets local meaning of macros used in headlines/footlines (see \^`\regmacro`).
  \enditems
* `\shipout`\^`\_completepage`, which is `\vbox` of --
  \begitems
  * backrground box, if \^`\pgbackground` is non-empty,
  * headline box by \^`\_makeheadline`, if the \^`\headline` is nonempty,
  * `\vbox to\vsize` of \^`\_pagecontents` which cosnists of --
    \begitems
    * \^`\_pagedest`, the page destination `pg:<gpageno>` for hyperlinks is created here,
    * \^`\topins` box if non-empty (from \^`\topinsert`s),
    * `\box255` with completed vertical material from main vertical mode,
    * \^`\_footnoterule` and \^`\footins` box if nonempty (from \^`\fnote`, \^`\footnote`),
    * \^`\pgbottomskip` (default is 0\,pt).
    \enditems
  * footline box by `\_makefootline`, if the \^`\footline` is nonempty
  \enditems
* \^`\_endoutput` which does:
  \begitems
  * increments \^`\pageno` using \^`\advancepageno`
  * runs output routine repeatedly if \^`\dosupereject` is activated.
  \enditems
\enditems

\_endinput

2021-02-25 \_draftbox improved
2021-02-15 \_advance -> \_decr
2020-05-12 \vfootB: \uskip -> \unskip bug fixed
2020-03-28 Released