%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \nopagenumbers {Output routine <2022-10-20>} % preloaded in format

   \_doc -----------------------------
   \`\_optexoutput` is the default output routine. You can create another...\nl
   The \^`\_preshipout``<destination box number><box specification>` used
   here behaves similarly like `\setbox` but it does not only copy the box
   contents but adds the color literals depending on used attributes.
   It is defined using lua code, see section~\ref[lua].
   \_cod -----------------------------

\_output={\_optexoutput}
\_def \_optexoutput{\_begoutput \_preshipout0\_completepage \_shipout\_box0 \_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.\nl
   The \^`\_resetattrs` used here means that all newly created texts in
   output routine (texts used in headline, footline) have default color
   and no transparency.
   \_cod -----------------------------

\_def\_completepage{\_vbox{%
     \_resetattrs
     \_istoksempty \_pgbackground
        \_iffalse \_backgroundbox{\_the\_pgbackground}\_nointerlineskip \_fi
     \_makeheadline
     \_vbox to\_vsize {\_boxmaxdepth=\_maxdepth \_pagecontents}% \pagebody in plainTeX
     \_makefootline}%
}
\_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{\_normalbaselines\_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{\_normalbaselines\_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`.\nl
   The \`\_footnoterule` is defined here.
   \_cod -----------------------------

\_def\_pagecontents{\_pagedest % destination of the page
  \_ifvoid\_topins \_else \_unvbox\_topins\_fi
  \_dimen0=\_dp255 \_unvbox255 % open up \box255
  \_ifvoid\_footins \_else % footnote info is present
    \_vskip\_skip\_footins
    \_footnoterule \_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
  \_resetattrs
  #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\_egroup}
\_def\_vfootB #1{#1\_unskip\_strut\_egroup}
\_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\_resetattrs} % 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{\_setgreycolor{.8}#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{\_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

2022-10-22 \_normalbaselines added to \makehead/foot/line
2022-03-07 \_resetattrs instead \_resetcolor
2021-07-16 output routine supports colors via attributes
2021-02-25 \_draftbox improved
2021-02-15 \_advance -> \_decr
2020-05-12 \vfootB: \uskip -> \unskip bug fixed
2020-03-28 Released
