% \iffalse meta-comment
%
%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
%
% The development version of the bundle can be found below
%
%    https://github.com/FrankMittelbach/...
%
% for those people who are interested or want to report an issue.
%
%    \begin{macrocode}
\providecommand\ltshipoutversion{v0.9a}
\providecommand\ltshipoutdate{2020/07/15}
%    \end{macrocode}
%
%<*driver>

\documentclass{l3doc}

% bug fix fo l3doc.cls
\ExplSyntaxOn
\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2
  {
    \vbox_set:Nn \l__codedoc_macro_box
      {
        \vbox_unpack_drop:N \l__codedoc_macro_box
        \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2
            \MacroFont       % <----- without it the \ is in lmr10 if a link is made
            \      
        } }
      }
    \int_incr:N \l__codedoc_macro_int
  }
\ExplSyntaxOff

\EnableCrossrefs
\CodelineIndex
\begin{document}
  \DocInput{ltshipout.dtx}
\end{document}
%</driver>
%
% \fi
%
%
% \long\def\fmi#1{\begin{quote}\itshape Todo: #1\end{quote}}
%
% \newcommand\hook[1]{\texttt{#1}}
%
%
% \title{The \texttt{ltshipout} package\thanks{This package has version
%    \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\
%    Project.}}
%
% \author{Frank Mittelbach}
%
% \maketitle
%
%
% \tableofcontents
%
% \section{Introduction}
%
%    The code provides an interface to the \cs{shipout} primitive of
%    \TeX{} which is called when a finished pages is finally
%    \enquote{shipped out} to the target output file, e.g., the
%    \texttt{.dvi} or \texttt{.pdf} file.
%    A good portion of the code is based on ideas by Heiko Oberdiek
%    implemented in his packages \pkg{atbegshi} and \pkg{atenddvi}
%    even though the interfaces are somewhat
%    different.\footnote{Heiko's interfaces are emulated by the kernel
%    code, if a document requests his packages, so older documents
%    will continue to work.}
%
%  \subsection{Overloading the \cs{shipout} primitive}
%
%
% \begin{function}{\shipout}
%    With this implementation \TeX's shipout primitive is no longer
%    available for direct use. Instead \cs{shipout} is running some
%    (complicated) code that picks up the box to be shipped out
%    regardless of how that is done, i.e., as a constructed \cs{vbox}
%    or \cs{hbox} or as a box register.
%
%    It then stores it in a named box register.  This box can then be
%    manipulated through a set of hooks after which it is shipped out
%    for real.
% \end{function}

%  \begin{variable}{\ShipoutBox,\l_shipout_box}
%    This box register is called \cs{ShipoutBox} (alternatively available via the
%    L3 name \cs{l_shipout_box}).
%  \end{variable}
%

%  \begin{variable}{\l_shipout_box_ht_dim,
%                   \l_shipout_box_dp_dim,\l_shipout_box_wd_dim,
%                   \l_shipout_box_ht_plus_dp_dim}
%    The shipout box dimensions are available in the L3 registers
%    \cs{l_shipout_box_ht_dim}, etc.\ (there are no \LaTeXe{}
%    names).\footnotemark{} These variables can be used
%    inside the hook code for \hook{shipout/before},
%    \hook{shipout/foreground} and \hook{shipout/background} if needed.
%  \end{variable}
%  \footnotetext{Might need changing, but HO's version as strings
%    is not really helpful I think).}
%
%
%
%
% \subsection{Provided hooks}
%
%  \begin{variable}{shipout/before,
%                   shipout/foreground,shipout/background,
%                   shipout/firstpage,
%                   shipout/lastpage}
%    The code offers a number of hooks into which packages (or the
%    user) can add code to support different use cases.
%    These are:
%    \begin{description}
%    \item[\hook{shipout/before}]
%
%       This hook is executed after the finished page has been stored in
%       \cs{ShipoutBox} / \cs{l_shipout_box}).
%       It can be used to alter that box content or to discard it
%       completely (see \cs{DiscardShipoutBox} below).
%
%    \item[\hook{shipout/background}]
%
%       This hook adds a picture environment into the background of
%       the page (with the \texttt{(0,0)} coordinate in the top-left
%       corner using a \cs{unitlength} of \texttt{1pt}.
%
%       It should therefore only receive \cs{put} commands or other
%       commands suitable in a \texttt{picture} environment and the
%       vertical coordinate values would normally be
%       negative.
%
%    \fmi{Again, mainly \pkg{atbegshi} compatibility. Not
%       sure it is best to have  to always use negative
%       coordinates.}
%
%       Technically this is implemented by adding a zero-sized
%       \cs{hbox} as the very first item into the \cs{ShipoutBox}
%       containing that \texttt{picture} environment. Thus the rest of
%       the box content will overprint what ever is typeset by that hook.
%
%
%    \item[\hook{shipout/foreground}]
%
%       This hook adds a picture environment into the foreground of
%       the page (with the \texttt{(0,0)} coordinate in the top-left
%       corner using a \cs{unitlength} of \texttt{1pt}.
%
%       Technically this is implemented by adding a zero-sized
%       \cs{hbox} as the very last item into the \cs{ShipoutBox} and
%       raising it up so that it still has its \texttt{(0,0)} point in
%       the top-left corner.
%       But being placed after the main box content it will be typeset
%       later and thus overprints it (i.e., is in the foreground).
%
%
%    \item[\hook{shipout/firstpage}]
%
%       The material from this hook is executed only once at the very
%       beginning of the first output page. It should only contain
%       \cs{special} commands needed to direct post processors
%       handling the \texttt{.dvi} or \texttt{.pdf} output.\fmi{not
%       sure it has to be that restrictive.}
%
%       In \LaTeXe{} that was already existing but implemented as a box
%       register \cs{@begindvibox}.
%       \fmi{drop or at least mark the obsolete code in latex.ltx}
%
%
%    \item[\hook{shipout/lastpage}]
%
%       The corresponding hook to add \cs{special}s at the very end of
%       the output file. It is only entered on the very last page.
%
%       It may not be possible for \LaTeX{} to correctly determine which page is
%       the last one without several reruns. If this happens and the
%       hook is non-empty then \LaTeX{} will add an extra page to
%       place the material and also request a rerun to get the correct
%       placement sorted out.
%
%    \end{description}
%  \end{variable}
%
%    As mentioned above the hook \hook{shipout/before} is executed
%    first and can manipulate the prepared shipout box stored in
%    \cs{ShipoutBox} or set things up for use in \cs{write} during the
%    actual shipout. The other hooks are added inside hboxes to the
%    box being shipped out in the following
%    order:
%    \begin{center}
%    \begin{tabular}{ll}
%       \hook{shipout/firstpage}   & only on the first page \\
%       \hook{shipout/background}  &                        \\
%       \meta{boxed content of \cs{ShipoutBox}} &             \\
%       \hook{shipout/foreground}  &                       \\
%       \hook{shipout/lastpage}    & only on the last page \\
%    \end{tabular}
%    \end{center}
%    If any of the hooks has no code then that particular no box is
%    added at that point.
%
%    In a document that doesn't produce pages, e.g., only makes
%    \cs{typeout}s, none of the hooks are executed (as there is no
%    \cs{shipout}) not even the \hook{shipout/lastpage} hook.
%
% \begin{function}{\AtBeginDvi,\AtEndDvi}
%    \cs{AtBeginDvi} is the existing \LaTeXe{} interface to fill the
%    \hook{shipout/firstpage} hook. This is not really a good name
%    as it is not just supporting \texttt{.dvi} but also \texttt{.pdf}
%    output or \texttt{.dvx}.
%
%    \cs{AtEndDvi} is the counterpart that was not available in the
%    kernel but only through the package \pkg{atenddvi}. It fills the
%    \hook{shipout/lastpage} hook.
%
%    \fmi{better names? Any suggestions?}
%
% \end{function}
%
% \subsection{Special commands for use inside the hooks}
%
% \begin{function}{\DiscardShipoutBox,\shipout_discard_box:}
%   \begin{syntax}
%     \cs{AddToHookNext} \texttt{\{shipout/before\} \{...\cs{DiscardShipoutBox}...\}}
%   \end{syntax}
%    The \cs{DiscardShipoutBox} declaration (L3 name
%    \cs{shipout_discard_box:})
%    requests that on the next
%    shipout the page box is thrown away instead of being shipped to
%    the \texttt{.dvi} or \texttt{.pdf} file.
%
%    Typical applications wouldn't do this unconditionally, but have
%    some processing logic that decides to use or not to use the page.
%
%    Note that if this declaration is used directly in the document it
%    may depend on the placement to which page it applies, given that
%    \LaTeX{} output routine is called in an asynchronous manner!
%
%    \fmi{Once we have a new mark mechanism available we can improve
%    on that and make sure that the declaration applies to the page
%    that contains it.}
%  \end{function}
%
%    In the \pkg{atbegshi} package there are a number of additional
%    commands for use inside the \hook{shipout/before} hook. They
%    should normally not be needed any more as one can instead simply
%    add code to the hooks \hook{shipout/before},
%    \hook{shipout/background} or
%    \hook{shipout/foreground}.\footnote{If that assumption turns out to
%    be wrong it would be trivial to change them to public functions
%    (right now they are private).} If \pkg{atbegshi} gets loaded then
%    those commands become available as public functions with their original
%    names as given below.
%
%
% \subsection{Information counters}
%
%
%  \begin{variable}{\ReadonlyShipoutCounter,\g_shipout_readonly_int}
%   \begin{syntax}
%     \cs{ifnum}\cs{ReadOnlyShipoutCounter}\texttt{=...}
%     \cs{int_use:N} \cs{g_shipout_readonly_int} \texttt{\% expl3 usage}
%   \end{syntax}
%    This integer holds the number of pages shipped out up to now
%    (including the one to be shipped out when inside the output
%    routine). More precisely, it is incremented only after it is
%    clear that a page will be shipped out, i.e., after the
%    \hook{shipout/before} hook (because that might discard the page)!

%    Just like with the \texttt{page} counter its value is
%    only accurate within the output routine. In the body of the
%    document it may be off by one as the output routine is called
%    asynchronously!
%
%    Also important: it \emph{must not} be set, only read. There are
%    no provisions to prevent that but if you do, chaos will be the
%    result. To emphasize this fact it is not provided as a \LaTeX{}
%    counter but as a \TeX{} counter (i.e., a command), so
%    \cs{Alph}\Arg{\cs{ReadonlyShipoutCounter}} etc, would not work.
%  \end{variable}
%
%  \begin{variable}{totalpages,\g_shipout_totalpages_int}
%   \begin{syntax}
%     \cs{arabic}\texttt{\{totalpages\}}
%     \cs{int_use:N} \cs{g_shipout_totalpage_int} \texttt{\% expl3 usage}
%   \end{syntax}
%    In contrast to \cs{ReadonlyShipoutCounter}, the
%    \texttt{totalpages} counter is a \LaTeX{} counter and incremented
%    for each shipout attempt including those pages that are discarded
%    for one or the other reason. Again \hook{shipout/before} sees
%    the counter before it is incremented).
%
%    Furthermore, while it is incremented for each page, its value is
%    never used by \LaTeX. It can therefore be freely reset or changed by user
%    code, for example, to additionally count a number of pages that
%    are not build by \LaTeX\ but are added in a later part of the
%    process, e.g., cover pages or picture pages made externally.
%
%    Important: as this is a page-related counter its value is only
%    reliable inside the output routine!
%  \end{variable}
%

%
% \subsection{Debugging shipout code}
%
% \begin{function}{\DebugShipoutOn,\DebugShipoutOff,
%         \shipout_debug_on:,\shipout_debug_off:}
%   \begin{syntax}
%     \cs{DebugShipoutOn}
%   \end{syntax}
%    Turn the debugging of shipout code on or off. This displays
%    changes made to the shipout data structures.  \fmi{This needs
%    some rationalizing and will probably not stay this way.}
% \end{function}
%
%

%
% \section{Emulating commands from other packages}
%
%    The packages in this section are no longer necessary but as they
%    are used in other packages they are emulated when they are loaded
%    via \cs{usepackage} or \cs{RequirePackage}.
%
%
% \subsection{Emulating \pkg{atbegshi}}
%
%
% \begin{function}{\AtBeginShipoutUpperLeft,\AtBeginShipoutUpperLeftForeground}
%   \begin{syntax}
%     \cs{AddToHook} \texttt{\{shipout/before\} \{...\cs{AtBeginShipoutUpperLeft}}\Arg{code}\texttt{...\}}
%   \end{syntax}
%    This adds a \texttt{picture} environment into the background of the shipout
%    box expecting \meta{code} to contain \texttt{picture}
%    commands. The same effect can be obtained by simply using kernel
%    features as follows:
%    \begin{quote}
%      \cs{AddToHook}\texttt{\{shipout/background\}}\Arg{code}
%    \end{quote}
%    There is one technical difference: if
%    \cs{AtBeginShipoutUpperLeft} is used several times each
%    invocation is put into its own box inside the shipout box whereas
%    all \meta{code} going into \hook{shipout/background} ends up
%    all in the same box in the order it is added or sorted based on
%    the rules for the hook chunks.
%
%    \cs{AtBeginShipoutUpperLeftForeground} is similar with the
%    difference that the \texttt{picture} environment is placed in the
%    foreground. To model it with the kernel functions use the hook
%    \hook{shipout/foreground} instead.
% \end{function}
%
%
% \begin{function}{\AtBeginShipoutAddToBox,\AtBeginShipoutAddToBoxForeground}
%   \begin{syntax}
%     \cs{AddToHook} \texttt{\{shipout/before\} \{...\cs{AtBeginShipoutAddToBox}}\Arg{code}\texttt{...\}}
%   \end{syntax}
%    These work like \cs{AtBeginShipoutUpperLeft} and
%    \cs{AtBeginShipoutUpperLeftForeground} with the difference that
%    \meta{code} is directly placed into an \cs{hbox} inside the
%    shipout box and not surrounded by a \texttt{picture} environment.
%
%    To emulate them using \hook{shipout/background} or
%    \hook{shipout/foreground} you may have to wrap \meta{code} into
%    a \cs{put} statement but if the code is not doing any typesetting
%    just adding it to the hook should be sufficient.
% \end{function}
%


% \begin{function}{\AtBeginShipoutBox}
%    This is the name of the shipout box as \pkg{atbegshi} knows it.
% \end{function}
%
% \begin{function}{\AtBeginShipoutInit}
%   By default \pkg{atbegshi} delayed its action until
%    \verb=\beg{document}=.  This command was forcing it in an earlier
%    place. With the new concept it does nothing.
% \end{function}
%
% \begin{function}{\AtBeginShipout,\AtBeginShipoutNext}
%   \begin{syntax}
% \cs{AtBeginShipout}\Arg{code} $\equiv$ \cs{AddToHook}\texttt{\{shipout/before\}}\Arg{code}
% \cs{AtBeginShipoutNext}\Arg{code} $\equiv$ \cs{AddToHookNext}\texttt{\{shipout/before\}}\Arg{code}
%   \end{syntax}
%   This is equivalent to filling the \hook{shipout/before} hook
%    by  either using \cs{AddToHook} or \cs{AddToHookNext}, respectively.
% \end{function}
%
% \begin{function}{\AtBeginShipoutFirst,\AtBeginShipoutDiscard}
%   The \pkg{atbegshi} names for \cs{AtBeginDvi} and \cs{DiscardShipoutBox}.
% \end{function}
%



% \subsection{Emulating \pkg{everyshi}}
%


% \begin{function}{\EveryShipout}
%   \begin{syntax}
% \cs{EveryShipout}\Arg{code} $\equiv$ \cs{AddToHook}\texttt{\{shipout/before\}}\Arg{code}
%   \end{syntax}
% \end{function}
%
% \begin{function}{\AtNextShipout}
%   \begin{syntax}
% \cs{AtNextShipout}\Arg{code} $\equiv$ \cs{AddToHookNext}\texttt{\{shipout/before\}}\Arg{code}
%   \end{syntax}
% \end{function}
%


% \subsection{Emulating \pkg{atenddvi}}
%
% The \pkg{atenddvi} package implemented only a single command:
%    \cs{AtEndDvi} and that is now available out of the box.



% \subsection{Emulating \pkg{everypage}}
%
%    This page takes over the original \cs{@begindvi} hook and replaces 
%    it. It should be all covered by the hooks offered here (details
%    need checking) and thus could simply use the provided hooks
%    rather than defining its own.
%
%
%
% \StopEventually{\setlength\IndexMin{200pt}  \PrintIndex  }
%
%
% \section{The Implementation}
%    \begin{macrocode}
%<*2ekernel>
%<@@=shipout>
\ExplSyntaxOn
%    \end{macrocode}
%
%
%  \subsection{Debugging}
%
%  \begin{macro}{\g_@@_debug_bool}
%    Holds the current debugging state.
%    \begin{macrocode}
\bool_new:N \g_@@_debug_bool
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\shipout_debug_on:,\shipout_debug_off:}
%  \begin{macro}{\@@_debug:n}
%  \begin{macro}{\@@_debug_gset:}
%    Turns debugging on and off by redefining \cs{@@_debug:n}.
%    \begin{macrocode}
\cs_new_eq:NN \@@_debug:n  \use_none:n
\cs_new_protected:Npn \shipout_debug_on:
  {
    \bool_gset_true:N \g_@@_debug_bool
    \@@_debug_gset:
  }
\cs_new_protected:Npn \shipout_debug_off:
  {
    \bool_gset_false:N \g_@@_debug_bool
    \@@_debug_gset:
  }
\cs_new_protected:Npn \@@_debug_gset:
  {
    \cs_gset_protected:Npx \@@_debug:n ##1
      { \bool_if:NT \g_@@_debug_bool {##1} }
  }
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%

%  \begin{macro}{shipout/before,
%                   shipout/foreground,shipout/background,
%                   shipout/firstpage,
%                   shipout/lastpage}
%    Declaring all hooks for the shipout code.
%    \begin{macrocode}
\hook_new:n{shipout/before}
\hook_new:n{shipout/foreground}
\hook_new:n{shipout/background}
\hook_new:n{shipout/firstpage}
\hook_new:n{shipout/lastpage}
%    \end{macrocode}
%  \end{macro}




%  \begin{macro}{\ShipoutBox,\l_shipout_box}
%    The box filled with the page to be shipped out (both L3 and
%       \LaTeXe{} name).
%    \begin{macrocode}
\box_new:N  \l_shipout_box
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_set_eq:NN \ShipoutBox \l_shipout_box
%    \end{macrocode}
%  \end{macro}




%  \begin{macro}{\@@_execute:}
%    This is going to the be the code run by \cs{shipout}. The code
%    follows closely the  ideas from \pkg{atbegshi}, so not
%    documenting that here for now.
%    \begin{macrocode}
\cs_set:Npn\@@_execute: {
  \tl_set:Nx \l_@@_group_level_tl
     { \int_value:w \tex_currentgrouplevel:D }
  \tex_afterassignment:D \@@_execute_test_level:
  \tex_setbox:D \l_shipout_box
}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\shipout}
%    Overloading the \cs{shipout} primitive:
%    \begin{macrocode}
\cs_gset_eq:NN \shipout \@@_execute:
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\l_@@_group_level_tl}
%    Helper token list to record the group level at which
%    \cs{@@_execute:} is encountered.  \begin{macrocode}
\tl_new:N \l_@@_group_level_tl
%    \end{macrocode}
%  \end{macro}

 

%  \begin{macro}{\@@_execute_test_level:}
%    If the group level has changed then we are still constructing
%    \cs{l_shipout_box} and to continue we need to wait until the
%    current group has finished, hence the \cs{tex_aftergroup:D}.
%    \begin{macrocode}
\cs_new:Npn \@@_execute_test_level: {
  \int_compare:nNnT
     \l_@@_group_level_tl < \tex_currentgrouplevel:D 
     \tex_aftergroup:D
  \@@_execute_cont:
}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\@@_execute_cont:}
%    When we have reached this point the shipout box has been
%    processed and is available in \cs{l_shipout_box} and ready for
%    real ship out (perhaps)..
%
%    First we quickly check if it is void (can't happen in the
%    standard \LaTeX{} output routine but \cs{shipout} might be called
%    from a package that has some special processing logic). If it is
%    void we aren't shipping anything out and processing ends.\footnote{In that
%    case we don't reset the deadcyles, that would be up to the OR
%    processing logic to do.}
%    \begin{macrocode}
\cs_new:Npn \@@_execute_cont: {
  \box_if_empty:NTF \l_shipout_box
    { \PackageWarning{ltshipout}{Ignoring~ void~ shipout~ box} }
    {
%    \end{macrocode}
%    Otherwise we assume that we will ship something and prepare for
%    final adjustments (in particular setting the state of
%    \cs{protect} while we are running the hook code).
%    \begin{macrocode}
      \bool_gset_false:N \g_@@_discard_bool
      \set@typeset@protect
%    \end{macrocode}
%    We also store the current shipout box dimension in registers, so that
%    they can be used in the hook code.\footnote{This is not really
%    necessary as the code could access them via \cs{box_ht:N}, etc.,
%    but it is perhaps convenient.}
%    \begin{macrocode}
      \@@_get_box_size:N \l_shipout_box
%    \end{macrocode}
%    Then we execute the \hook{shipout/before} hook.
%    \begin{macrocode}
      \hook_use:n {shipout/before}
%    \end{macrocode}
%    In \cs{g_shipout_totalpages_int} we count all shipout attempts so
%    we increment that counter already here (the other one is
%    incremented later when we know for sure that we do a
%    \cs{shipout}.
%
%     We increment it after running the above hook so that the values
%    for \cs{g_shipout_totalpages_int} and \cs{} are in sync while the
%    hook is executed (in the case that totalpages isn't manually
%    altered or through discarding pages that is).
%    \begin{macrocode}
      \int_gincr:N \g_shipout_totalpages_int
%    \end{macrocode}
%    The above hook might contain code that requests the page to be discarded so
%    we now test for it.
%    \begin{macrocode}
      \bool_if:NTF \g_@@_discard_bool
        { \PackageInfo{ltshipout}{Completed~ page~ discarded}
          \bool_gset_false:N \g_@@_discard_bool
%    \end{macrocode}
%    As we are discarding the page box and not shipping anything out,
%    we need to do some house cleaning and reset \TeX's deadcycles so
%    that it doesn't complain about too many calls to the OR without
%    any shipout.
%    \begin{macrocode}
          \tex_deadcycles:D \c_zero_int
%    \end{macrocode}
%    \fmi{In \pkg{atbegshi} the box was dropped but is that actually
%    needed? Or the resetting of \cs{protect} to its kernel value?}
%    \begin{macrocode}
%          \group_begin:
%            \box_set_eq_drop:NN \l_shipout_box \l_shipout_box
%          \group_end:
%          \cs_set_eq:NN \protect \exp_not:N
        }
%    \end{macrocode}
%    Even if there was no explicit request to discard the box it is
%    possible that the code for the hook \hook{shipout/before} has
%    voided the box (by mistake or deliberately). We therefore test
%    once more but this time make it a warning, because the best
%    practice way is to use the request mechanism.
%    \begin{macrocode}
        { \box_if_empty:NTF \l_shipout_box
            { \PackageWarning{ltshipout}{
                Shipout~ box~ was~ voided~ by~ hook,\MessageBreak
                ignoring~ shipout~ box  }
            }
%    \end{macrocode}
%    Finally, if the box is still non-empty we are nearly ready to
%    ship it out.
%    First we increment the total page counter so that we can later
%    test if we have reached the final page according to our available
%    information.\footnote{Doing that earlier would be wrong because we
%    might end up with the last page counted but discard and then we
%    have no place to add the final objects into the output file.}
%    \begin{macrocode}
            {
              \int_gincr:N \g_shipout_readonly_int
              \@@_debug:n {
                \typeout{Absolute~ page~ =~ \int_use:N \g_shipout_readonly_int
                         \space (target:~ \@abspage@last)}
              }
%    \end{macrocode}
%    Then we store the box sizes again (as they may have
%    changed) and then look at the hooks \hook{shipout/foreground}
%    and \hook{shipout/background}. If either or both are non-empty
%    we add a \texttt{picture} environment to the box (in the
%    foreground and or in the background) and execute the hook code
%    inside that environment.
%    
%    \begin{macrocode}
              \@@_get_box_size:N \l_shipout_box
              \@kernel@before@shipout@foreground
              \hook_if_empty:nF {shipout/foreground}
                   { \@@_add_foreground_picture:n
                     { \hook_use:n {shipout/foreground} } }
              \hook_if_empty:nF {shipout/background}
                   { \@@_add_background_picture:n
                     { \hook_use:n {shipout/background} } }
%    \end{macrocode}
%    We then run \cs{@@_execute_firstpage_hook:} that adds
%    the content of the hook \hook{shipout/firstpage} to the
%    start of the first page (if non-empty). It is then redefined to
%    do nothing on later pages.
%    \begin{macrocode}
              \@@_execute_firstpage_hook:
%    \end{macrocode}
%    The we check if we have to add the \hook{shipout/lastpage} hook
%    because we have reached the last page. This test will be false for
%    all but one (and hopefully the correct) page.
%    \begin{macrocode}
              \int_compare:nNnT \@abspage@last = \g_shipout_readonly_int
                { \hook_if_empty:nF {shipout/lastpage}
                    { \@@_debug:n { \typeout{Executing~ lastpage~ hook~
                          on~ page~ \int_use:N \g_shipout_readonly_int }        }
                      \_@@_add_foreground_box:n { \UseHook{shipout/lastpage}
                                                  \@kernel@after@shipout@lastpage }
                    }
                    \bool_gset_true:N \g_@@_lastpage_handled_bool
                }
%    \end{macrocode}
%    Finally we run the actual \TeX{} primitive for shipout. As that will
%    expand delayed \cs{write} statements inside the page in which
%    protected commands should not expand we first change \cs{protect}
%    to the appropriate definition for that case.
%    \begin{macrocode}
              \cs_set_eq:NN \protect \exp_not:N
              \tex_shipout:D \box_use:N \l_shipout_box
            }
        }
    }
}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\@kernel@after@shipout@lastpage,\@kernel@before@shipout@foreground}
%    
%    \begin{macrocode}
\let\@kernel@after@shipout@lastpage\@empty
\let\@kernel@before@shipout@foreground\@empty
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\@@_execute_firstpage_hook: }
%    This command adds any specials into a box and adds that to the
%    very beginning of the first box shipped out. After that we
%    redefine it to do nothing on later pages.
%    \begin{macrocode}
\cs_new:Npn \@@_execute_firstpage_hook: {
%    \end{macrocode}
%    Adding something to the beginning means adding it to the
%    background as that  layer is done first in the output. Of course
%    that is only needed if the hook actually contains anything.
%    \begin{macrocode}
  \hook_if_empty:nF {shipout/firstpage}
       { \@@_add_background_box:n { \UseHook{shipout/firstpage} } }
%    \end{macrocode}
%    Once we are here we change the definition to do nothing next time
%    and we also change the command used to implement \cs{AtBeginDvi}
%    to become a warning and not  add further material to a hook that
%    is never used again.
%    \begin{macrocode}
  \cs_gset_eq:NN \@@_execute_firstpage_hook: \prg_do_nothing:
  \cs_gset:Npn \@@_add_firstpage_material:Nn ##1 ##2 {
    \PackageWarning{ltshipout}{
        First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak
        \string##1 }
  }
}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\g_@@_lastpage_handled_bool}
%    A boolean to signal if we have already handled the
%    \hook{shipout/lastpage} hook.
%    \begin{macrocode}
\bool_new:N \g_@@_lastpage_handled_bool
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\@@_add_firstpage_material:Nn}
%    This command adds material to the
%    \hook{shipout/firstpage} hook. It is used in
%    \cs{AtBeginDvi}, etc. The first argument is the
%    command through which is it called. Initially this is ignored but
%    once we are passed the first page it can be used to generate a
%    warning message mentioning the right user command.
%    \begin{macrocode}
\cs_new:Npn \@@_add_firstpage_material:Nn #1#2 {
   \AddToHook{shipout/firstpage}{#2}
}
%    \end{macrocode}
%  \end{macro}







%  \begin{macro}{\@@_get_box_size:N}
%    Store the box dimensions in dimen registers.
%    \fmi{This could/should perhaps be generalized to set height depth and
%    width given an arbitrary box.}
%    \begin{macrocode}
\cs_new:Npn \@@_get_box_size:N #1 {
  \dim_set:Nn \l_shipout_box_ht_dim { \box_ht:N #1 }
  \dim_set:Nn \l_shipout_box_dp_dim { \box_dp:N #1 }
  \dim_set:Nn \l_shipout_box_wd_dim { \box_wd:N #1 }
  \dim_set:Nn \l_shipout_box_ht_plus_dp_dim { \l_shipout_box_ht_dim +
                                         \l_shipout_box_dp_dim }
}
%    \end{macrocode}
%  \end{macro}

%  \begin{macro}{\l_shipout_box_ht_dim,
%                   \l_shipout_box_dp_dim,\l_shipout_box_wd_dim,
%                   \l_shipout_box_ht_plus_dp_dim}
%    And here are the variables set by \cs{@@_get_box_size:N}.
%    \begin{macrocode}
\dim_new:N \l_shipout_box_ht_dim
\dim_new:N \l_shipout_box_dp_dim
\dim_new:N \l_shipout_box_wd_dim
\dim_new:N \l_shipout_box_ht_plus_dp_dim
%    \end{macrocode}
%  \end{macro}





%  \begin{macro}{\g_@@_discard_bool}
%    Indicate whether or not the current page box should be discarded
%    \begin{macrocode}
\bool_new:N \g_@@_discard_bool
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\l_@@_tmp_box,\l_@@_saved_badness_tl}
%    We need a box for the background and foreground material and a
%    token register to remember badness settings as we disable  them
%    during te buildup below.
%    \begin{macrocode}
\box_new:N \l_@@_tmp_box
\tl_new:N  \l_@@_saved_badness_tl
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\@@_add_background_box:n}
%    In standard \LaTeX{} the shipout box is always a \cs{vbox} but
%    here we are allow for other usage as well, in case some package
%    has its own output routine.
%    \begin{macrocode}
\cs_new:Npn \@@_add_background_box:n #1
{ \@@_get_box_size:N \l_shipout_box
%    \end{macrocode}
%    But we start testing for a vertical box as that should be the
%    normal case.
%    \begin{macrocode}
  \box_if_vertical:NTF \l_shipout_box
      {
%    \end{macrocode}
%    Save current values of \cs{vfuzz} and \cs{vbadness} then change
%    them to allow box manipulations without warnings.
%    \begin{macrocode}
        \tl_set:Nx \l_@@_saved_badness_tl
           { \vfuzz=\the\vfuzz\relax
             \vbadness=\the\vbadness\relax }
        \vfuzz=\c_max_dim
        \vbadness=\c_max_int
%    \end{macrocode}
%    Then we reconstruct \cs{l_shipout_box} \ldots
%    \begin{macrocode}
        \vbox_set_to_ht:Nnn \l_shipout_box \l_shipout_box_ht_plus_dp_dim 
             {
%    \end{macrocode}
%    \ldots{} the material in \verb=#1= is placed into a horizontal
%    box with zero dimensions.
%    \begin{macrocode}
               \hbox_set:Nn \l_@@_tmp_box
                    { \l_@@_saved_badness_tl #1 }
               \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim
               \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim
               \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim
%    \end{macrocode}
%    The we typeset that box followed by whatever was in
%    \cs{l_shipout_box} before (unpacked).
%    \begin{macrocode}
               \skip_zero:N \baselineskip
               \skip_zero:N \lineskip
               \skip_zero:N \lineskiplimit
               \box_use:N \l_@@_tmp_box
               \vbox_unpack:N \l_shipout_box
%    \end{macrocode}
%    The \cs{kern} ensures that the box has no depth which is
%    afterwards explicitly corrected.
%    \begin{macrocode}
               \kern \c_zero_dim
             }
        \box_set_ht:Nn \l_shipout_box \l_shipout_box_ht_dim
        \box_set_dp:Nn \l_shipout_box \l_shipout_box_dp_dim 
%    \end{macrocode}
%    \fmi{The whole boxing maneuver looks a bit like overkill to me, but for
%    the moment I leave.}               
%    \begin{macrocode}
        \l_@@_saved_badness_tl
      }
      {
%    \end{macrocode}
%    A horizontal box is handled in a similar way. The last case would
%    be a void box in which case we do nothing hence the missing
%    \texttt{F} branch. 
%    \begin{macrocode}
        \box_if_horizontal:NT \l_shipout_box
            {
              \tl_set:Nx \l_@@_saved_badness_tl
                 { \hfuzz=\the\hfuzz\relax
                   \hbadness=\the\hbadness\relax }
              \hfuzz=\c_max_dim
              \hbadness=\c_max_int
              \hbox_set_to_wd:Nnn \l_shipout_box \l_shipout_box_wd_dim
                   {
                     \hbox_set:Nn \l_@@_tmp_box
                          { \l_@@_saved_badness_tl #1 }
                     \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim
                     \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim
                     \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim
                     \box_move_up:nn
                         \l_shipout_box_ht_dim 
                         { \box_use:N \l_@@_tmp_box }
                     \hbox_unpack:N \l_shipout_box
                   }
              \l_@@_saved_badness_tl
            }
      }
}
%    \end{macrocode}
%  \end{macro}




%  \begin{macro}{\@@_add_foreground_box:n}
%    Foreground boxes are done in the same way, only the order and
%    placement of boxes has to be done differently.
%    \begin{macrocode}
\cs_new:Npn \@@_add_foreground_box:n #1
{
  \box_if_vertical:NTF \l_shipout_box
    {
      \tl_set:Nx \l_@@_saved_badness_tl
         { \vfuzz=\the\vfuzz\relax
           \vbadness=\the\vbadness\relax }
      \vfuzz=\c_max_dim
      \vbadness=\c_max_int
      \vbox_set_to_ht:Nnn \l_shipout_box \l_shipout_box_ht_plus_dp_dim
           {
             \hbox_set:Nn \l_@@_tmp_box
                  { \l_@@_saved_badness_tl #1 }
             \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim
             \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim
             \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim
             \skip_zero:N \baselineskip
             \skip_zero:N \lineskip
             \skip_zero:N \lineskiplimit
             \vbox_unpack:N \l_shipout_box
             \kern -\l_shipout_box_ht_plus_dp_dim
             \box_use:N \l_@@_tmp_box
             \kern  \l_shipout_box_ht_plus_dp_dim
           }
      \l_@@_saved_badness_tl
      \box_set_ht:Nn \l_shipout_box \l_shipout_box_ht_dim
      \box_set_dp:Nn \l_shipout_box \l_shipout_box_dp_dim 
    }
    {
      \box_if_horizontal:NT \l_shipout_box
        {
          \tl_set:Nx \l_@@_saved_badness_tl
            { \hfuzz=\the\hfuzz\relax
              \hbadness=\the\hbadness\relax }
          \hfuzz=\c_max_dim
          \hbadness=\c_max_int
          \hbox_set_to_wd:Nnn \l_shipout_box \l_shipout_box_wd_dim
               {
                 \hbox_unpack:N \l_shipout_box
                 \kern -\box_wd:N \l_shipout_box
                 \hbox_set:Nn \l_@@_tmp_box
                     { \l_@@_saved_badness_tl #1 }
                 \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim
                 \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim
                 \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim
                 \box_move_up:nn { \box_ht:N \l_shipout_box }
                               { \box_use:N \l_@@_tmp_box }
                 \kern \box_wd:N \l_shipout_box
               }%
               \l_@@_saved_badness_tl
        }
    }
}
%    \end{macrocode}
%  \end{macro}




%  \begin{macro}{\c_@@_horigin_tl,\c_@@_vorigin_tl}
%    Two constants holding the offset of the top-left with respect to
%    the media box.
%
%    Setting the constants this way is courtesy of Bruno.
%    \begin{macrocode}
\tl_gput_right:Nn \@kernel@after@begindocument {
  \tl_const:Nx \c_@@_horigin_tl
     {
       \cs_if_exist_use:NTF \pdfvariable { horigin }
          { \cs_if_exist_use:NF \pdfhorigin { 1in } }
     }
  \tl_const:Nx \c_@@_vorigin_tl
     {
       \cs_if_exist_use:NTF \pdfvariable { vorigin }
          { \cs_if_exist_use:NF \pdfvorigin { 1in } }
     }
}     
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\@@_picture_overlay:n}
%    Put the argument into a \texttt{picture} environment that doesn't take up
%    any size and uses \texttt{1pt} for \cs{unitlength}.
%    \fmi{Could perhaps be generalized as it might be useful elsewhere. For
%    not it is not.}
%    \begin{macrocode}
\cs_new:Npn \@@_picture_overlay:n #1 {
    \kern -\c_@@_horigin_tl \scan_stop:
    \vbox_to_zero:n {
      \kern -\c_@@_vorigin_tl \scan_stop:
      \unitlength 1pt \scan_stop:
      \hbox_set_to_wd:Nnn \l_@@_tmp_box \c_zero_dim { \ignorespaces #1 }
%      \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim
      \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim
      \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim
      \box_use:N \l_@@_tmp_box
      \tex_vss:D
    }
}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\@@_add_background_picture:n}
%    Put a \texttt{picture} env in  the background of the shipout box
%    with its reference point in the top-left corner.
%    \begin{macrocode}
\cs_new:Npn \@@_add_background_picture:n #1 {
   \@@_add_background_box:n { \@@_picture_overlay:n {#1} }
}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\@@_add_foreground_picture:n}
%    
%    Put a \texttt{picture} env in  the foreground of the shipout box
%    with its reference point in the top-left corner.
%    \begin{macrocode}
\cs_new:Npn \@@_add_foreground_picture:n #1 {
   \@@_add_foreground_box:n { \@@_picture_overlay:n {#1} }
}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\shipout_discard:}
%    Request that the next shipout box should be discarded. At the
%    moment this is just setting a boolean, but we may want to augment
%    this behavior that the position of the call is taken into account
%    (in case \LaTeX{} looks ahead and is not using the position for
%    on the next page).
%    \begin{macrocode}
\cs_new:Npn \shipout_discard: {
  \bool_gset_true:N \g_@@_discard_bool
}
%    \end{macrocode}
%  \end{macro}




% \subsection{Handling the end of job hook}

%    At the moment this is partly solved by using the existing hooks.
%    But rather than putting the code into these hooks it should be
%    moved to the right place directly as we shouldn't prefill hooks
%    with material unless it needs to interact with other code. 
%

%    
%  \begin{macro}{\g_shipout_readonly_int,\ReadonlyShipoutCounter}
%    We count every shipout activity that makes a page (but not those
%    that are discarded) in order to know how many pages got produced.
%    \begin{macrocode}
\int_new:N \g_shipout_readonly_int
%    \end{macrocode}
%    For \LaTeXe{} it is available as a command (i.e., a \TeX{}
%    counter only.
%    \begin{macrocode}
\cs_new_eq:NN \ReadonlyShipoutCounter  \g_shipout_readonly_int
%    \end{macrocode}
%  \end{macro}

%  \begin{macro}{\g_shipout_totalpages_int,\c@totalpages}
%    We count every shipout attempt (even those that are discarded) in
%    tis counter. It is not used in the code but may get used in user
%    code.
%    \begin{macrocode}
\int_new:N \g_shipout_totalpages_int
%    \end{macrocode}
%    For \LaTeXe{} this is offered as a \LaTeX{} counter so can be
%    easily typeset inside the output routine to display things like
%    \enquote{\cs{thepage}\texttt{/}\cs{thetotalpages}}, etc.
%    \begin{macrocode}
\cs_new_eq:NN \c@totalpages \g_shipout_totalpages_int
\cs_new:Npn \thetotalpages { \arabic{totalpages} }
%    \end{macrocode}
%  \end{macro}
%



%  \begin{macro}{\@abspage@last}
%    In \cs{@abspage@last} record the number of pages from the last
%    run. This is written to the \texttt{.aux} and this way made
%    available to the next run. In case there is no \texttt{.aux} file
%    or the statement is missing from it we initialize it with the
%    largest possible number in \TeX{}. We use this a s the default
%    because then we are inserting the \hook{shipout/lastpage} on
%    the last page (or after the last page but not on page 1 for a
%    multipage document.
%    \begin{macrocode}
\xdef\@abspage@last{\number\maxdimen}
%    \end{macrocode}
%  \end{macro}


% \begin{macro}{\enddocument}
%
%    Instead of using the hooks \hook{enddocument} and
%    \hook{enddocument/afterlastpage} we add this code to private
%    kernel hooks to be 100\% when it is executed and to avoid
%    cluttering the hooks with data that is always there.
%
%    Inside \cs{enddocument} there is a \cs{clearpage}. Just before
%    that we execute this code here. There is a good change that we
%    are on the last page. Therefore, if we don't know the value from
%    the last run, we assume that the current page is the right
%    one. So we set \cs{@abspage@last} and as a result the next
%    shipout will run the \hook{shipout/lastpage} code. Of course,
%    if there are floats that still need a placement this guess will
%    be wrong but then rerunning the document will give us the correct
%    value next time around.
%
% \begin{macro}{\@kernel@after@enddocument}
%    \begin{macrocode}
\g@addto@macro \@kernel@after@enddocument {
  \int_compare:nNnT \@abspage@last = \maxdimen
    {
%    \end{macrocode}
%    We use \LaTeXe{} coding as \cs{@abspage@last} is not an L3 name.
%    \begin{macrocode}
      \xdef\@abspage@last{ \int_eval:n {\g_shipout_readonly_int + 1} }
    }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@kernel@after@enddocument@afterlastpage}
%    Once the \cs{clearpage} has done its work inside \cs{enddocument}
%    we know for sure how many pages this document has, so we record
%    that in the \texttt{.aux} file for the next run.
%
%    \begin{macrocode}
\g@addto@macro \@kernel@after@enddocument@afterlastpage {
%    \end{macrocode}
%    There is one special case: If no output is produced then there is
%    no point in a) recording the number as 0 will never match the
%    page number of a real page and b) adding an extra page to ran the
%    \hook{shipout/lastpage} is pointless as well (as it would
%    remain forever). So we test for this and run the code only if
%    there have been pages.
%    \begin{macrocode}
  \int_compare:nNnF \g_shipout_readonly_int = 0
    {
%    \end{macrocode}
%     This ends up in the \texttt{.aux} so we use \LaTeXe{} names here.
%     \fmi{this needs an interface for \cs{nofiles} in expl3, doesn't at the moment!}
%    \begin{macrocode}
     \if@filesw
        \iow_now:Nx \@auxout {
          \gdef\string\@abspage@last {\int_use:N \g_shipout_readonly_int}}
     \fi
%    \end{macrocode}
%    But we may have guessed wrongly earlier and we still have to run the
%    \hook{shipout/lastpage} even though there is no page to place
%    it into. If that is the case we make a trivial extra page and put
%    it there. This temporary page will then vanish again on the next
%    run but helps to keep pdf viewers happy.
%    \begin{macrocode}
      \bool_if:NF \g_@@_lastpage_handled_bool
        { \tex_shipout:D\vbox to\textheight{
            \hbox{\UseHook{shipout/lastpage} \@kernel@after@shipout@lastpage }
%    \end{macrocode}
%    This extra page could be totally empty except for the hook
%    content, but to help the user understanding why it is there we
%    put some text into it.
%    \begin{macrocode}
            \@@_excuse_extra_page:
            \null
          }
%    \end{macrocode}
%    At this point we should also signal to \LaTeX{} that a rerun is
%    necessary so that an appropriate message can be shown on the
%    terminal.
%
%    \fmi{integrate warning ``Rerun \ldots'' }
%    \begin{macrocode}
      }
    }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}



%  \begin{macro}{\@@_excuse_extra_page:}
%    Say mea culpa \ldots
%    \begin{macrocode}
\cs_new:Npn \@@_excuse_extra_page: {
  \vfil
  \begin{center}
    \bfseries Temporary~ page! 
  \end{center}
    \LaTeX{}~ was~ unable~ to~ guess~ the~ total~ number~ of~ pages~
    correctly.~ ~ As~ there~ was~ some~ unprocessed~ data~ that~
    should~ have~ been~ added~ to~ the~ final~ page~ this~ extra~
    page~ has~ been~ added~ to~ receive~ it.
    \par
    If~ you~ rerun~ the~ document~ (without~ altering~ it)~ this~
    surplus~ page~ will~ go~ away,~ because~ \LaTeX{}~ now~ knows~
    how~ many~ pages~ to~ expect~ for~ this~ document.
  \vfil
}
%    \end{macrocode}
%  \end{macro}




% \section{Legacy \LaTeXe{} interfaces}



%  \begin{macro}{\DiscardShipoutBox}
%    Request that the next shipout box is to be discarded.
%    \begin{macrocode}
\cs_new_eq:NN \DiscardShipoutBox \shipout_discard:
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\AtBeginDvi}
%    
%    \begin{macrocode}
\renewcommand \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi}
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\DebugShipoutOn,\DebugShipoutOff}
%    
%    \begin{macrocode}
\cs_new_eq:NN \DebugShipoutOn  \shipout_debug_on:
\cs_new_eq:NN \DebugShipoutOff \shipout_debug_off:
%    \end{macrocode}
%  \end{macro}





% \section{Package emulation for compatibility}


% \subsection{Package \pkg{atbegshi} emulation}

%  \begin{macro}{\AtBeginShipoutBox}
%    \begin{macrocode}
\cs_new_eq:NN \AtBeginShipoutBox \ShipoutBox
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\AtBeginShipoutInit}
%    Compatibility only, we aren't delaying \ldots
%    \begin{macrocode}
\cs_set_eq:NN\AtBeginShipoutInit\@empty 
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\AtBeginShipout,\AtBeginShipoutNext}
%    Filling hooks
%    \begin{macrocode}
\newcommand\AtBeginShipout     {\AddToHook{shipout/before}}
\newcommand\AtBeginShipoutNext {\AddToHookNext{shipout/before}}
%    \end{macrocode}
%  \end{macro}



%  \begin{macro}{\AtBeginShipoutFirst}
%    Slightly more complex as we need to know the name of the command under which the
%    \hook{shipout/firstpage} hook is filled.
%    \begin{macrocode}
\newcommand\AtBeginShipoutFirst{\@@_add_firstpage_material:Nn \AtBeginShipoutFirst}
%    \end{macrocode}
%  \end{macro}



% This is somewhat different from the original where
% \cs{ShipoutBoxHeight} etc.\ only holds the \verb=\the\ht<box>= value. This
% may has some implications in some use cases and if that is a problem
%    then it might need changing.
%    
%    \begin{macrocode}
\cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim }
\cs_new:Npn \ShipoutBoxDepth  { \dim_use:N \l_shipout_box_dp_dim }
\cs_new:Npn \ShipoutBoxWidth  { \dim_use:N \l_shipout_box_wd_dim }
%    \end{macrocode}


%  \begin{macro}{\AtBeginShipoutDiscard}
%    Just a different name.
%    \begin{macrocode}
\cs_new_eq:NN \AtBeginShipoutDiscard \DiscardShipoutBox
%    \end{macrocode}
%  \end{macro}


%  \begin{macro}{\AtBeginShipoutAddToBox,\AtBeginShipoutAddToBoxForeground,
%                \AtBeginShipoutUpperLeft,\AtBeginShipoutUpperLeftForeground}
%    We don't expose them.
%    \begin{macrocode}
\cs_new_eq:NN \AtBeginShipoutAddToBox           \@@_add_background_box:n
\cs_new_eq:NN \AtBeginShipoutAddToBoxForeground \@@_add_foreground_box:n 
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_new_eq:NN\AtBeginShipoutUpperLeft           \@@_add_background_picture:n
\cs_new_eq:NN\AtBeginShipoutUpperLeftForeground \@@_add_foreground_picture:n
%    \end{macrocode}
%  \end{macro}

%
%
%    We prevent the package \pkg{atbegshi} from loading:
%    \begin{macrocode}
\expandafter\cs_set_eq:NN\csname ver@atbegshi.sty\endcsname\fmtversion
%    \end{macrocode}
%    \pkg{hyperref} code (and \pkg{ltxcmds}) doesn't understand 2020-10-01
%       and thinks it is before 1994, so for now \ldots
%    \begin{macrocode}
\@namedef {ver@atbegshi.sty}{2020/10/01}
%    \end{macrocode}



% \subsection{Package \pkg{everyshi} emulation}
%
%  \begin{macro}{\EveryShipout,\AtNextShipout}
%    This package has only two public commands to simulating it is easy:
%    \begin{macrocode}
\cs_new_eq:NN\EveryShipout\AtBeginShipout
\cs_new_eq:NN\AtNextShipout\AtBeginShipoutNext
%    \end{macrocode}
%  \end{macro}
%
%    \begin{macrocode}
\expandafter\cs_set_eq:NN\csname ver@everyshi.sty\endcsname\fmtversion
\@namedef {ver@everyshi.sty}{2020/10/01}
%    \end{macrocode}



% \subsection{Package \pkg{atenddvi} emulation}
%
%  \begin{macro}{\AtEndDvi}
%    This package has only one public command to simulating it is easy:
%    \begin{macrocode}
\cs_new:Npn \AtEndDvi {\AddToHook{shipout/lastpage}}
%    \end{macrocode}
%  \end{macro}
%
%
%    \begin{macrocode}
\expandafter\cs_set_eq:NN\csname ver@atenddvi.sty\endcsname\fmtversion
\@namedef {ver@atenddvi.sty}{2020/10/01}
%    \end{macrocode}




%    \begin{macrocode}
\ExplSyntaxOff
%</2ekernel>
%    \end{macrocode}

%    \Finale
%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
\endinput
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  


