summaryrefslogtreecommitdiff
path: root/macros/optex/base/output.opm
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-04-20 03:00:55 +0000
committerNorbert Preining <norbert@preining.info>2021-04-20 03:00:55 +0000
commitd65c208b161ffee9ce5343fdfdb17d00523cecae (patch)
tree6829c46d8881891365b9be3fb660dba3ca79e6f5 /macros/optex/base/output.opm
parent272d21375e83d59014b6591075291d172bbfa007 (diff)
CTAN sync 202104200300
Diffstat (limited to 'macros/optex/base/output.opm')
-rw-r--r--macros/optex/base/output.opm267
1 files changed, 267 insertions, 0 deletions
diff --git a/macros/optex/base/output.opm b/macros/optex/base/output.opm
new file mode 100644
index 0000000000..5bb93c2477
--- /dev/null
+++ b/macros/optex/base/output.opm
@@ -0,0 +1,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