% \iffalse % This is versonotes.dtx, which supports adding notes on verso pages, % opposite annotation on the recto pages. Still sketchy %% %% Release version 0.5, 2023 December 31. %% %% Copyright 2014, 2015, 2019, 2023 Norman Gray %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3 %% of this license or (at your option) any later version. %% The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% and version 1.3 or later is part of all distributions of LaTeX %% version 2005/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. %% %% The Current Maintainer of this work is Norman Gray %% %% This work consists of the files versonotes.dtx and versonotes.ins %% and the derived file versonotes.sty. %% %%%% File: versonotes.dtx %<+package|driver|example>%%%% Source: b86314fff92e, 2023-12-31T14:55:52+00:00 %% %<+package>\NeedsTeXFormat{LaTeX2e} %<+package>\ProvidesPackage{versonotes}[2023/12/31 v0.5] % %<*driver> \documentclass{ltxdoc} \title{versonotes: Notes on verso pages} \author{Norman Gray\\\url{https://nxg.me.uk}} \date{Release 0.5, 2023 December 31} \usepackage{url} \newcommand\Lopt[1]{\textsf {#1}} % options \newcommand\file[1]{\texttt {#1}} \newcommand\Lcount[1]{\textsl {\small#1}} \newcommand\Lenv[1]{\texttt{\{#1\}}} %environments \newcommand\Lpackage[1]{\{\textsf{#1}\}} %packages %Make command strings easier to write %{\catcode`\<=\active \gdef<#1>{\meta{#1}}} {\catcode`\<=\active \gdef<#1>{{\ensuremath\langle\normalfont\textsl{#1}\ensuremath\rangle}}} \def\cmd{\begingroup \catcode`\\=12 \catcode`\{=12 \catcode`\}=12 \catcode`\<=\active \catcode`\|=12 \docmd} \def\docmd|#1|{\texttt{#1}\endgroup} %%% \url macro (url.sty does this better) %\def\setpathdots{\discretionary{.}{}{.}} %\def\setpathslash{\discretionary{/}{}{/}} %{\catcode`\.=\active % \catcode`\/=\active % \gdef\pathcats{% % \catcode`\%=12 \catcode`\~=12 % \catcode`\.=\active \let.\setpathdots % \catcode`\/=\active \let/\setpathslash % \catcode`\#=12 \catcode`\_=12}% % } %\def\setpath#1{\ttfamily <\nobreak #1\nobreak>\endgroup} %\def\url{\begingroup\pathcats\setpath} \def\bs{$\backslash$} \begin{document} \maketitle %\tableofcontents %\bigskip \DocInput{versonotes.dtx} \end{document} % % % \fi % % \noindent This package allows you to place notes on the verso pages % of an otherwise single-sided document. If, in the run % of text, you include a call to the macro % |\versonote{This is a remark}|, % then that text will be placed on the opposite (ie, `verso') page, % lined up with the macro call. % The notes may contain more than one paragraph. % % All the pages in the document appear as recto pages % (ie, right-hand pages), % and are numbered as such; % the document should be formatted with that in mind. % % Since there is no page opposite the first page, any notes which are % positioned to appear opposite page 1 are silently discarded. % % To invoke the package, use the command |\usepackage{versonotes}|. % % It is possible to start the document other than on page one. To do % this, you can call |\setcounter{page}{|\emph{n}|}| as usual, but it % must be done \emph{before} the line |\usepackage{versonotes}|. The % package may get confused if the page number is changed at other times. % % If two notes come too close after one another, the second would % overprint the first if we did not take steps to avoid this. By % default, they are separated from each other by a short horizontal % line, but if the \Lopt{mergecollisions} option is provided when % loading the package, then such notes are instead merged into a % single block of text. If a sequence of notes needs to be merged, % then they will be added to the merged block one at a time in % successive \LaTeX\ runs, since merging one note may make it % unnecessary to merge the next. If a large block of such notes need % to be merged, it will therefore take several runs before the package % finds a stable state. If you find yourself inconvenienced by this, % it sounds as if you are preparing a critical edition, and you might % want to venture into a closer relationship with the % \Lpackage{reledmac} % package.\footnote{\texttt{https://www.ctan.org/pkg/reledmac} -- this % is the current incarnation, as of 2023, of the eledmac, ledmac and % edmac packages for scholarly editions.}. % % \emph{Note}: % If we have a long versonote at the bottom of a page, then we % don't try to spill over onto the next (that would be possible to % implement, but would be a significant jump in complication). We % regard this situation as one for the user to work out for themself, % perhaps with some strategic page-breaks. % % The dimensions |\versoleftmargin| and |\versotextwidth| specify the % position of the text block on the verso page. The defaults for % these are based on the |\textwidth| and |\evensidemargin| of the % document \emph{at the time the package is loaded}. % By default, verso paragraphs are set ragged-left; with the % declarations in |\versolayout| setting the paragraph parameters. % You may reset the first two dimensions with for example % |\versoleftmargin=4cm|, and use |\renewcommand\versolayout{...}| to % override the paragraph formatting (this will typically require % changing |\rightskip|, |\leftskip| and |\parfillskip|). For more % elaborate effects (for example changing the note font size and % spacing), you will need to redefine |\versolayout|. % % \subsection*{Recto notes} % % If the package is invoked with the \Lopt{rectonotes} option, then it % runs in a complementary mode in which the notes are placed on the % recto page (the right-hand one) instead of the verso. The default % |\versolayout| in this case (which of course is really a recto % layout) is slightly different, and is based on the preexisting % document |\oddsidemargin|. All the pages in the document (apart % from the front page) are then formatted as verso pages, though still % only the non-note pages are numbered. % % In this mode, the `add a note' command is still called % |\versonote|. You may find it convenient to rename that with % |\let\rectonote = \versonote| or |\let\sidenote = \versonote|. % % \subsection*{Notes} % \begin{itemize} % \item The package uses the |\pdfsavepos| primitive (or the % Lua\TeX\ equivalent), and so requires \texttt{pdflatex}, % \texttt{xelatex}, or \texttt{lualatex}. In practice, this should % mean that it will work with any reasonably current \LaTeX\ engine. % % \item The notes are handled using the |.aux| file, and so (i) they will % only appear on the second and subsequent runs; and (ii) they will be % located opposite the position where the |\versonote| macro was % called on the \emph{previous} run. % % \item If notes collide, you may well have to re-run \LaTeX\ several % times. There is quite a lot of state in the |.aux| file. % % \item The package is available on CTAN at % \texttt{macros/latex/contrib/versonotes/}. The source is hosted at % \url{https://heptapod.host/nxg/versonotes/}. % % \end{itemize} % % \subsection*{Acknowledgements, and release notes} % % \iffalse @RELEASENOTES@ \fi % % % Thanks to Thomas H. Luxon for permission to include the % Dartmouth Milton text\footnote{\url{https://milton.host.dartmouth.edu/}} of % ‘Paradise Lost’ notes in the sample text. % % \begin{description} % \item[Version 0.5, 2023 December 31]\relax % \leavevmode\begin{itemize} % \item Now compatible with LuaTeX. % \item Now uses L3-style hooks, but retains compatibility with pre-2020 engines. % \item Updated the links to the repository, and to the Dartmouth Milton text. % \end{itemize} % \item[Version 0.4, 2019 July 6]\relax % Support changing the initial page number % (thanks to P J Couch for the suggestion). % \item[Version 0.3, 2015 December 8]\relax % \leavevmode\begin{itemize} % \item Minor documentation adjustments. % \item Added the [rectonotes] option % (thanks to Axel Berger for this suggestion). % \end{itemize} % \item[Version 0.2, 2015 February 16]\relax % Initial public release. % \end{description} % % % \StopEventually{} % \newpage % \section{Implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % The package contains a single user-visible command, and three % configuration parameters. % % The normal behaviour of this package is to place notes on the verso % page (ahem, hence the name). But we can swap that around. % \begin{macrocode} \newif\if@verso@notesonleft \@verso@notesonlefttrue % \end{macrocode} % % Define configuration options for the user: % \begin{macrocode} \def\verso@resetmergestate{\verso@mergestate=2} \DeclareOption{mergecollisions}{\def\verso@resetmergestate{\verso@mergestate=0}} \DeclareOption{rectonotes}{\@verso@notesonleftfalse} \ProcessOptions % \end{macrocode} % % The single user-visible command is |\versonote|. % Use |\unexpanded| (from e-\TeX) so that macros in the argument are % not expanded into the aux file. % \begin{macrocode} \long\def\versonote#1{\@bsphack \pdfsavepos \write\@auxout{\string\verso@note{\the\c@page}{\the\pdflastypos sp}\unexpanded{{#1}}}% \@esphack} % \end{macrocode} % % \subsection{Housekeeping: sizes and sentinels} % % Now the layout parameters, and defaults. % The dimensions |\versoleftmargin| and |\versotextwidth| specify the % position of the text block on the verso page, and the declarations % in |\versolayout| set the paragraph parameters. % \begin{macrocode} \newdimen\versotextwidth \versotextwidth=\textwidth \newdimen\versoleftmargin \versoleftmargin=\paperwidth \advance\versoleftmargin -\textwidth \advance\versoleftmargin -\hoffset \advance\versoleftmargin -1in \if@verso@notesonleft \advance\versoleftmargin -\evensidemargin \def\versolayout{ \leftskip=0pt plus 1fil \rightskip=0pt \parfillskip=0pt \parindent=0pt \parskip=\medskipamount } \else \advance\versoleftmargin -\oddsidemargin \def\versolayout{ \leftskip=0pt \rightskip=0pt plus 4em \parindent=0pt \parskip=\medskipamount } \fi % \end{macrocode} % % Add a sentinel at the end of the document % \begin{macrocode} \def\end@versonote{% \write\@auxout{\string\verso@note{\the\c@page}{-1pt}{}}} \AtEndDocument{\end@versonote} % \end{macrocode} % % Define various bits of working storage. % % The |\verso@pages| token list needs to have an extra leading `page' % since the logic in |\verso@processonepage@| can skip it. % \begin{macrocode} \newtoks\verso@pages \if@verso@notesonleft \verso@pages={} \else \verso@pages={{}} \fi % \end{macrocode} % Notes on a single page (which is kept track of by % |\verso@currentpagenum| are assembled into |\verso@currentpage| % before being transferred as a unit into |\verso@pages|. % \begin{macrocode} \newtoks\verso@currentpage % \end{macrocode} % We keep track of page numbers when invoking |\verso@note| below. We % initialise this to be the current page number (typically~1). Doing % this this way means that if the document sets the current page % number using |\setcounter{page}{n}| \emph{before} loading the % package, then we will respect that. We will get confused if the % page number is changed at other points. % \begin{macrocode} \newcount\verso@currentpagenum \verso@currentpagenum=\c@page \newcount\verso@currentnotenum \verso@currentnotenum=0 \newdimen\verso@spacerskip \verso@spacerskip=10pt % \end{macrocode} % Flag |\if@verso@processversonotes| is set true if there are any % |\verso@note|s found in the aux file. If there are none -- so that % this is still false at the first |\shipout| -- then the package % carefully does nothing. % \begin{macrocode} \newif\if@verso@processversonotes \@verso@processversonotesfalse % \end{macrocode} % % We need to be able to calculate our position on the page. % The |\verso@pagebottom| is the position of the bottom of the page, % in the same coordinates as |\verso@currentposition|, and is % (textheight + top margin + \dots). % \begin{macrocode} \newdimen\verso@pagebottom \verso@pagebottom=1in \advance\verso@pagebottom \topskip \advance\verso@pagebottom \topmargin \advance\verso@pagebottom \headheight \advance\verso@pagebottom \headsep \advance\verso@pagebottom \textheight \newdimen\verso@currentposition % \end{macrocode} % The paper size options to class files set |\paperheight| but not (or % not necessarily) |\pdfpageheight|. If we don't set this, then % output vertical positions will come out incorrectly if the latter % parameter doesn't default to the right value. Lua\TeX\ and pdf\TeX\ % (which includes Xe\TeX\ for this purpose) have slightly different % ways of organising page sizes, so we do have to conditionalise. % Here, we assume that everything that isn't Lua\TeX\ is pdf\TeX-like % enough that it has |\pdfpageheight|. % \begin{macrocode} \RequirePackage{iftex} \ifluatex \typeout{Detected LuaTeX} \pageheight=\paperheight \let\pdfsavepos=\savepos \let\pdflastypos=\lastypos \else \pdfpageheight=\paperheight \fi % \end{macrocode} % % \subsection{Core logic} % % Macro |\verso@note| is what's written to the aux file, and so is % what we process on the next run, to discover the set of verso-notes % we need to produce. % \begin{macrocode} \long\def\verso@note#1#2#3{% \global\@verso@processversonotestrue % \end{macrocode} % Store the target page number. It would be nice to issue a warning if this is % indicated to appear on the (ignored) first page; such notes are % silently discarded below. However detecting this here requires that % |\@tempcnta| is equal to~1 on the call of this, and we can't % guarantee this if we support calling |\setcounter{page}{x}| before % loading the package. % \begin{macrocode} \@tempcnta=#1 % \end{macrocode} % Gather pages from the .aux file, assembling them into a single list % in |\verso@pages| with one group per page, each containing a % sequence of |\\{...}| note specifications. This inserts empty % groups for pages which have no verso-notes. % \begin{macrocode} \@tempdima=#2 % #2 < 0pt is the end-of-document flag \loop \@tempswafalse \ifnum\@tempcnta > \verso@currentpagenum \@tempswatrue \fi \ifdim\@tempdima < 0pt \@tempswatrue \@tempdima=0pt \fi \if@tempswa \edef\@tempa{\the\verso@pages {\the\verso@currentpage}} \global\verso@pages=\expandafter{\@tempa} \advance\verso@currentpagenum 1 \verso@currentpage={} \repeat \verso@currentpage=\expandafter{\the\verso@currentpage \\{{#1}{#2}{#3}}} % \end{macrocode} % The last time around, add an extra pair of tokens at the end of the % |\verso@pages| list. These provide the arguments to % |\verso@processonepage@| on the last time it's called. % \begin{macrocode} \ifdim\@tempdima=0pt \global\verso@pages=\expandafter{\the\verso@pages {}{}} \fi } % \end{macrocode} % % Disable |\verso@note| in time for the end-document aux reading. % This isn't quite necessary, but it's tidy. % \begin{macrocode} \AtEndDocument{\long\def\verso@note#1#2#3{}} % \end{macrocode} % % Test whether we want to merge the current note with the following % one. The arguments to this macro are the contents of % |\verso@mergenotelist|, which is assembled from the % |\verso@mergenote| commands read from the aux file. % \begin{macrocode} \def\verso@testmergenote#1,#2\@nil{ \def\@tempa{#1} \ifx\@tempa\@empty \@tempcnta=-1 \else \@tempcnta=#1 \fi \advance\@tempcnta -1 \ifnum\@tempcnta=\verso@currentnotenum % \end{macrocode} % Set |\if@tempswa| true, set |\verso@mergenotelist| to the tail of % the list, and ensure that this note is merged next time round. % \begin{macrocode} \@tempswatrue \xdef\verso@mergenotelist{#2} \immediate\write\@auxout{\string\verso@mergenote{#1}} \else \@tempswafalse \fi } % \end{macrocode} % % The macro |\verso@setnote| is the one which does the work of % positioning a single note on the (verso) page. We potentially work % quite hard to avoid notes overwriting each other here. If % |\verso@mergestate| is greater than one (by default, it's % initialised to~2, but any number greater than~1 would be equivalent) % then when two notes collide, we simply put a horizontal bar between % them, and hope for the best. Each time we have a collision we % increment this number, and if we find it has a value~1 (ie, the % first collision) we we record in the aux file that this note should % be merged with its predecessor, by writing a |\verso@mergenote| % command. Next time round, when we are about to set the note % \emph{before} that one, we avoid setting it, and instead start % accumulating the text of such merged notes, in the token register % |\verso@accumulatenote|. We only add a single note to the list of % merged notes on each \LaTeX\ run, since merging one note may make it % unnecessary to merge any more. The only way to delete the % collections of merged notes is to delete the aux file. % \begin{macrocode} \newcount\verso@mergestate \verso@resetmergestate \newtoks\verso@accumulatenote \verso@accumulatenote={} % \end{macrocode} % % Set the note. The arguments are (1) the page number, (2) the % position on the page, and (3) the text of the note. % \begin{macrocode} \long\def\verso@setnote#1#2#3{ \@tempdima=\paperheight \advance\@tempdima -#2 % target position; will become skip to add \@tempdimb=\verso@currentposition \global\advance\verso@currentnotenum 1 % \end{macrocode} % Check whether we're to merge the following note into this one. % \begin{macrocode} \expandafter\verso@testmergenote\verso@mergenotelist,\@nil \if@tempswa \verso@accumulatenote=\expandafter{% \the\verso@accumulatenote #3% \quad\P~\nobreak} %\PackageInfo{versonotes}{\typeout{Merging notes on p#1}} \else % \end{macrocode} % No merging: set the current note, possibly along with any % accumulated notes, in a box, and then start to work out where to put it. % \begin{macrocode} \setbox0=\vtop{ \versolayout \the\verso@accumulatenote #3\par} \verso@accumulatenote={} % \end{macrocode} % We now know how big this box is (|\ht0|), how far down the page the % accumulated boxes are (|\verso@currentposition|), and where the box % is to appear, as an offset from the top of the paper (|\@tempdima|). % Work how how much of a skip we have to add to get there. % \begin{macrocode} \ifdim\@tempdima>\verso@currentposition % \end{macrocode} % The target position is below the current position; add a skip. This % is the straightforward case, and leaves the skip in |\@tempdima| and % the new current position in |\@tempdimb|. % \begin{macrocode} \advance\@tempdima -\verso@currentposition \advance\@tempdima -\ht0 \advance\@tempdimb \@tempdima \verso@resetmergestate \else % \end{macrocode} % Or the target position is above the current position; % thus the new material will have to be moved down % (I'm not sure how best to handle the case where this skip results % in the note hitting the bottom of the page. Should it be merged % with that case below, somehow?). % \begin{macrocode} % note: \PackageWarning seems to produce odd effects here \message{^^Jversonotes warning: Moved versonote text on p.#1.} \advance\verso@mergestate 1 \ifnum\verso@mergestate=1 \immediate\write\@auxout{\string\verso@mergenote{\the\verso@currentnotenum}} \fi \nointerlineskip \vbox to \verso@spacerskip{\vfil \hbox to \hsize{\hfil\vrule height 0.4pt width 10em} \vfil} \advance\@tempdimb \verso@spacerskip \@tempdima=0pt % ...so don't add any more skip \fi \advance\@tempdimb \ht0 \advance\@tempdimb \dp0 % \end{macrocode} % Parameter |\@tempdimb| now holds the expected new value of % |\verso@currentposition|. Check to see if this would be beyond the bottom % of the page, and move the text upwards in that case. % \begin{macrocode} \ifdim\@tempdimb>\verso@pagebottom \message{^^Jversonotes warning: versonote text on p.#1 hit bottom of page.} \advance\@tempdima -\@tempdimb \advance\@tempdima \verso@pagebottom \@tempdimb=\verso@pagebottom \fi % \end{macrocode} % Finally, do the skip and add the box. % \begin{macrocode} \vskip\@tempdima \verso@currentposition=\@tempdimb \nointerlineskip \box0 \fi } % \end{macrocode} % % Log notes where a previous run has discovered they collide. % \begin{macrocode} \def\verso@mergenotelist{} \def\verso@mergenote#1{\xdef\verso@mergenotelist{\verso@mergenotelist #1,}} % \end{macrocode} % % \subsection{Overall processing logic, and shipout} % % We want to use the current shipout mechanism, but also to remain % compatible with pre-2020 \LaTeX, so conditionalise appropriately. % Note that we can't use the (apparently preferable) % |\IfFormatAtLeastTF| command to do this test: we want to continue to % work even when we're using a \LaTeX\ which is too old for this % command to be defined. % \begin{macrocode} \newif\ifverso@Liii \@ifl@t@r\fmtversion{2020/10/01}\verso@Liiitrue\verso@Liiifalse \PackageInfo{versonotes} {choosing support for \ifverso@Liii L3\else pre-L3\fi} % \end{macrocode} % % For the L3 case, we will use the |shipout/before| hook, and use % |\RawShipout| to output the separate versonotes pages. % See the \texttt{ltshipout-doc} documentation for details. % But in the pre-L3 case, save the original definition of |\shipout| % (using the L3 |\RawShipout| name for clarity), % prior to our redefining it below. % We could do this perfectly well using the \Lpackage{everyshi} package, % but we do it by hand in order to avoid the extra dependency. % \begin{macrocode} \ifverso@Liii\else \let\RawShipout\shipout \fi % \end{macrocode} % % We process the versonotes a page at a time. We don't have to do % anything clever, because the page that a versonote lands on is % governed by the page that the |\versonote| call appears on. If we % have a long versonote at the bottom of a page, then we don't try to % spill over onto the next (that would presumably be possible, using % the inserts mechanism, but would be a significant jump in % complication). We regard this situation as one for the user to work % out for themself. % % Macro |\verso@processonepage@| consumes the next group in the % |\verso@pages| list. % % Macro |\verso@processonepage| is called just before each shipout of % a `real' page, as the content of the \texttt{shipout/before} hook % (or as part of the redefined |\shipout| in the pre-L3 case). % If we are putting notes on verso pages % (ie, the usual case, as opposed to recto notes), % then \emph{before} we ship out page~2, we must construct and % ship out the notes for page~2; we will have a set of notes for % page~1 (which we expect will be empty), which we must discard; we % achieve this by simply doing nothing if the current page is page~1. % If, on the other hand, we are putting notes on recto pages, then we % must instead ship out the notes for page~2 just before shipping out page~3, and % must similarly do nothing on pages~1 and~2. This works because % in the latter case we have initialised |\verso@pages| with an extra % leading |{{}}|. % % We manage the page skipping by decrementing a `pages to skip' % counter. The more obvious way of doing that it to test the value of % |\@tempcnta|, which at this point holds the current page number, but % this produces the wrong answer if the document starts at other than % page~1 (perhaps because the document includes |\setcounter{page}{99}|). % \begin{macrocode} \newcount\verso@pagestoskip \if@verso@notesonleft \verso@pagestoskip=1 \else \verso@pagestoskip=2 \fi % \end{macrocode} % % Define |\verso@processonepage@|. % \begin{macrocode} \long\def\verso@processonepage@#1#2\@nil{ \def\@tempa{#1} % \end{macrocode} % Do nothing on page~1 (in the verso case), or pages~1 and~2 (in the % recto case). Any notes which would appear in such a position are % silently discarded. % \begin{macrocode} \ifnum\verso@pagestoskip=0 % \end{macrocode} % If there are no verso-notes on this page, then ship out an empty box. % \begin{macrocode} \ifx\@tempa\@empty \RawShipout\vbox{} % \end{macrocode} % This is the normal case: % create a box containing the |\\{...}| contents of the % current page's verso-notes % \begin{macrocode} \else \begingroup % \end{macrocode} % Within the box we're about to create, we have to `un-protect' things. % Robust commands (including for example |\emph| and other font-changing commands) are % defined using |\protect|, which in the present context, inside % |\@outputpage|, is |\let| equal to |\noexpand|. % We must set this to be simply |\relax|, % as it is in the normal run of text elsewhere % (see \url{http://tex.stackexchange.com/questions/206673/}). % \begin{macrocode} \let\protect\relax % \end{macrocode} % Set everything up for setting the verso page. % \begin{macrocode} \hoffset=-1in \advance\hoffset \versoleftmargin \voffset=-1in \hsize=\versotextwidth \topskip=0pt \topmargin=0pt \headheight=0pt \headsep=0pt \vsize=1000mm % larger than any actual note \normalfont\normalsize % \end{macrocode} % Construct and ship out the page contents. % \begin{macrocode} \long\def\\##1{\verso@setnote ##1} \RawShipout\vbox{ \verso@currentposition=0pt #1} \endgroup \fi % \end{macrocode} % Otherwise, the |\verso@pagestoskip| counter is still positive, % indicating that we are skipping pages. % Decrement the counter and do nothing else. % \begin{macrocode} \else \global\advance\verso@pagestoskip -1 \fi % \end{macrocode} % Finally, set |\verso@pages| to the tail of the list. % \begin{macrocode} \global\verso@pages={#2}} % \end{macrocode} % % The command |\verso@processonepage| is invoked once on every |\shipout|. % \begin{macrocode} \def\verso@processonepage{ \if@verso@processversonotes \expandafter\verso@processonepage@\the\verso@pages\@nil % \end{macrocode} % If this test is false, then we don't seem to have any versonotes in this file, % so don't come here again. % \begin{macrocode} \else \global\let\verso@processonepage\relax \fi } % \end{macrocode} % % And finally, do the |\shipout| gymnastics. % \begin{macrocode} \ifverso@Liii \AddToHook{shipout/before}{\verso@processonepage} \else \def\shipout{\verso@processonepage \RawShipout} \fi % \end{macrocode} % % All done! % \begin{macrocode} % % \end{macrocode} % \Finale % \endinput