%:strip
% ptx-diglot.tex: Diglot(v2) processing for xetex paratext2.tex
% Copyright (c) 2008-2021 by SIL International 
% written by David Gardner
%
% Permission is hereby granted, free of charge, to any person obtaining
% a copy of this software and associated documentation files (the  
% "Software"), to deal in the Software without restriction, including  
% without limitation the rights to use, copy, modify, merge, publish,  
% distribute, sublicense, and/or sell copies of the Software, and to  
% permit persons to whom the Software is furnished to do so, subject to  
% the following conditions:
%
% The above copyright notice and this permission notice shall be  
% included in all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  
% NONINFRINGEMENT. IN NO EVENT SHALL SIL INTERNATIONAL BE LIABLE FOR  
% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  
% CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
% WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
% Except as contained in this notice, the name of SIL International  
% shall not be used in advertising or otherwise to promote the sale,  
% use or other dealings in this Software without prior written  
% authorization from SIL International.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcount\diglotDbgJoinboxes%
\diglotDbgJoinboxes=-1% Set to the debug message of a joinboxes to execute showbox on that join. Also works at other number-showing messages
\def\diglotDbgeachcol{-1}% Define to begin tracingmacros and tracing assigns at each@col with TRACEcount
\def\diglotDbgupdtPtl{-1}% Define to begin tracingmacros and tracing assigns at n@xtpartial  with TRACEcount

\def\diglotbadbrk{\penalty 10000}

%\def\TRshipout#1{\shipout#1}
\def\TRshipout#1{}
\def\b@xbotmark{}

% THis is a crude hack to make main titles line up nicely. For some reason
% they seem to already be vtops with depth info lost. 
%
\def\dstrut#1{{\setbox0\hbox{#1}\hbox{\vrule height \ht0 depth \dp0 width 0pt}}}
%
%
\newif\ifdiglotInnerOuter% Do pages switch columns based on page number (odd pages Left-Right, even Right-left)?
\newif\ifdiglotSwap% Do we invert the columns?
\diglotInnerOuterfalse
\newif\ifdiglotN@rmal % Which way round for this page?
\newif\ifuseLeftMarks %Do we use marks from the left column
\newif\ifuseRightMarks %Do we use them from the right column
\newif\ifunprintable % The 'correct' logic results in a page that won't fit. Something breaks.
\newif\ifdiglotDebugFollowContents% Fill the log with showboxes
\newif\ifdiglotcolh@scontent % Set false at start of column, made true by \everyparhooks
\newif\ifdiglot@pos@top % Set if the current chunk is at the top of the page.
\newif\ifdiglot@ecols % set if there are any empty columns
\addtoeveryparhooks{\global\diglotcolh@scontenttrue}
\useLeftMarkstrue
\useRightMarkstrue
\diglotDebugFollowContentsfalse

\def\firstLmark{} % First mark in left column
\def\botLmark{} % last mark in left column
\def\firstRmark{} % First mark in right column
\def\botRmark{} % last mark in right column
\def\nextp@gefirstmark{}
\def\n@xtfirstLmark{} %First Lmark in the n@xt chunk
\def\n@xtfirstRmark{} %First Rmark in the n@xt chunk
\def\n@xtbotLmark{} %First Lmark in the n@xt chunk
\def\n@xtbotRmark{} %First Rmark in the n@xt chunk
\def\LeftMarkstrue{\useLeftMarkstrue\useRigthMarksfalse}
\def\LeftMarksfalse{\useLeftMarkstrue\useRigthMarkstrue}

%Defined penalties
\newsp@cialpen{dgl@tPenColSwap}%
\newsp@cialpen{dgl@tPenInternalRpt}
\newsp@cialpen{dgl@tPenLtrialEnd}
\newsp@cialpen{dgl@tPenRtrialEnd}

\def\oldRmark{}
\def\oldLmark{}
\def\p@gebotmark{}
\newif\ifVisTrace% Show lines where boxes are joined
\newif\ifVisTraceExtra %Do VisTrace even in places where this breaks the layout.
\VisTracefalse%
\VisTraceExtrafalse%
\newif\ifdiglot %If there is diglot material
\newif\ifp@gestart % temporary hold while things get going.
\def\setsid@{\xdef\sid@{\c@rrdstat}}

%+cdig_define-hooks
\newtoks\diglotLho@ks
\newtoks\diglotRho@ks
\def\addToSideHooks#1#2{\x@\let\x@\tmp\csname diglot#1ho@ks\endcsname \x@\global\x@\tmp\x@{\the\tmp #2}}
\def\addToLeftHooks#1{\x@\global\x@\diglotLho@ks\x@{\the\diglotLho@ks #1}}
\def\addToRightHooks#1{\x@\global\x@\diglotRho@ks\x@{\the\diglotRho@ks #1}}
\def\addToLHooks{\addToSideHooks{L}}
\def\addToRHooks{\addToSideHooks{R}}
%-cdig_define-hooks

\def\stylesheetL{\gdef\ds@ffix{L}\stylesh@@t}%Need to reset ds@ffix to {}, so that side-specific settings can be applied.
\def\stylesheetR{\gdef\ds@ffix{R}\stylesh@@t}
\def\stylesh@@t#1{\stylesheet{#1}\gdef\ds@ffix{}}

%LRspecific holds a list of things that get redefined on side-switching. Now split into Definitions and Dimensions.
\def\LRspecificDef{AdornVerseNumber,VerticalSpaceFactor,LineSpacingFactor,regular,bold,italic,bolditalic,SpaceStretchFactor,SpaceShrinkFactor,ifOmitVerseNumberOne,MakeChapterLabel,ColAdjskip,intercharspace}
\def\LRspecificDim{FontSizeUnit,le@dingunit,onel@neunit,verticalsp@ceunit,IndentUnit} 
%LRspecificVarIf lists **internal boolean variables** that need to carry over from one paragraph to the next. For global config values, insert name in LRspecificDef, and add line(s) for newsideSpecificIf into initcolumndef@ults
\def\LRspecificVarIf{dr@ppednumber,dr@ppedother}
\def\LRspecificVarDef{ch@pterc@tnum} % \def based variables that need to carry over from one par to the next

%Because some people may have adjust-lists using the old broken numbering, we make 2 versions of this.
\def\LRspecificCountFixed{curr@djpar,p@rnum,@numcuts,dropped@ther@lines} 
\def\LRspecificCountBroken{@numcuts,dropped@ther@lines}
\let\LRspecificCount\LRspecificCountFixed


% Code to cycle through \LRspecific, setting them to their L/R values, modified
% from what the code to count callers does in ptx-callers.tex
%Would be nice to re-use \\, but this might get called defining a font in footnotes, so shouldn't mess with that
%Therefore use \wh@t instead.
\def\@rig{@orig}
% These do the looping
\def\pr@cessSp@cific#1,#2\E{\def\t@st{#1}\ifx\t@st\empty\let\n@xt\l@stSpecific\else\let\n@xt\pr@cessSp@cific\wh@t{#1}\fi\n@xt #2,\E}
\def\l@stSpecific#1\E{}
\def\pr@cessSpecificAll{\edef\LRs{\LRspecificDef,\LRspecificDim,\LRspecificCount,\LRspecificVarDef}\x@\pr@cessSp@cific \LRs,\E} % ONLY used for saving original values
\def\pr@cessSpecificDef{\edef\LRs{\LRspecificDef,\LRspecificVarDef}\x@\pr@cessSp@cific \LRs,\E}
\def\pr@cessSpecificVarDef{\edef\LRs{\LRspecificVarDef}\x@\pr@cessSp@cific \LRs,\E}
\def\pr@cessSpecificDim{\edef\LRs{\LRspecificDim}\x@\pr@cessSp@cific \LRs,\E}
\def\pr@cessSpecificCount{\edef\LRs{\LRspecificCount}\x@\pr@cessSp@cific \LRs,\E}
\def\pr@cessSpecificVarIf{\edef\LRs{\LRspecificVarIf}\x@\pr@cessSp@cific \LRs,\E}

\def\saveVarLRSpecific{%
  \let\wh@t\s@veSpecificSideIf\pr@cessSpecificVarIf
  \let\wh@t\s@veSpecificSideDef\pr@cessSpecificVarDef
}
% These are the things that might get called by the loop.

% If theres a side-specific version, switch to it. If there's no side-specific version, 
% switch to the \original version, if that exists.
\def\sp@cificSideDef#1{\ifcsname #1\sfx\endcsname\x@\let\csname#1\x@\endcsname\csname #1\sfx\endcsname
  \trace{S}{SpS: #1\sfx\space selected}\else
  \ifcsname #1\@rig\endcsname\x@\let\csname#1\x@\endcsname\csname #1\@rig\endcsname
    \trace{S}{SpS: #1 returned to original }\else\trace{S}{SpS: #1 unmodified (no #1\sfx, no #1\@rig)}\fi\fi}

% If theres a side-specific version and its not -1sp, switch to it. If there's no side-specific verision,
% switch to the \original version, if that exists.
\def\sp@cificSideDim#1{\x@\ifdim\csname #1\sfx\endcsname=-1sp%
   \ifcsname #1\@rig\endcsname\x@\let\csname#1\x@\endcsname\csname #1\@rig\endcsname
     \trace{S}{SpS: #1 returned to original (\x@\the\csname #1\@rig\endcsname)}\else\trace{S}{SpS: #1 unmodified}%
    \fi
  \else
   \x@\let\csname#1\x@\endcsname\csname #1\sfx\endcsname\trace{S}{SpS: #1\sfx\space selected (\the\csname #1\sfx\endcsname)}%
  \fi
}
\def\sp@cificSideIf#1{\x@\ifx\csname IF#1\sfx\endcsname\tr@e\csname #1true\endcsname\else\csname #1false\endcsname\fi
  \trace{S}{SpS: IF#1\sfx\space (\csname IF#1\sfx\endcsname) selected}%
}

\def\sp@cificSideCount#1{\x@\ifnum\csname #1\sfx\endcsname=\m@ncount
   \ifcsname #1\@rig\endcsname\x@\let\csname#1\x@\endcsname\csname #1\@rig\endcsname
     \trace{S}{SpS: #1 returned to original}\else\trace{S}{SpS: #1 unmodified}%
    \fi
  \else
   \x@\let\csname#1\x@\endcsname\csname #1\sfx\endcsname\trace{S}{SpS: #1\sfx\space selected (\the\csname #1\endcsname)}%
  \fi
}

\def\s@veSpecificOrig#1{\ifcsname #1\endcsname \x@\let\csname #1\@rig\x@\endcsname\csname #1\endcsname
    \let\sSotmp=\col@do
    \def\col@do##1{\ch@ckLR{#1}{##1}}%
    \x@\each@col\diglot@list\E % Check all columns
    \let\col@do=\sSotmp
  \else\MSG{No global definition for #1}\fi} % If the item exists, save its current value. 

\def\ch@ckLR#1#2{\ifcsname#1#2\endcsname\trace{S}{SpS: #1#2 exists}\else\x@\let\csname #1#2\x@\endcsname\csname #1\@rig\endcsname
  \ifdiglot\MSG{Side-specific #1#2 not defined, global #1 will be used}\fi\fi}% Helper function
\def\restoreLR@rig#1{\x@\let\csname #1\x@\endcsname\csname #1\@rig\endcsname}

\def\n@wSpecificDim#1{\x@\newdim@n\csname #1\sfx\endcsname \x@\global\csname #1\sfx\endcsname=-1sp 
}
% Savr the current if value 
\def\s@veSpecificSideIf#1{\ifcsname if#1\endcsname \x@\csname if#1\endcsname \x@\let\csname IF#1\sfx\endcsname\tr@e\else \x@\let\csname IF#1\sfx\endcsname\false\fi\else\message{*** Probable typo: if#1 does not exist in side-specific switching}\fi}
% set the if value based on the saved logic
% If the item exists, save its current value. 
\def\s@veSpecificSideDef#1{\ifcsname #1\endcsname \x@\let\csname #1\sfx\x@\endcsname\csname #1\endcsname\fi}
\def\s@veSpecificSideDim#1{\ifcsname #1\endcsname\ifcsname #1\sfx\endcsname  \x@\global\csname #1\sfx\endcsname=\csname #1\endcsname\else\errmessage{dimension #1 does not exist}\fi\else\errmessage{dimension #1\sfx does not exist}\fi}
% Output routine for normal things.
\def\sh@wSpecificDef#1{\ifcsname #1\sfx\endcsname\trace{S}{#1\sfx: \x@\meaning\csname #1\sfx\endcsname}\else
  \trace{S}{#1\sfx: undefined}\fi}
% Output routine for  dimensions
\def\sh@wSpecificDim#1{\ifcsname #1\sfx\endcsname\trace{S}{#1\sfx: \the\csname #1\sfx\endcsname}\else
  \trace{S}{#1\sfx: undefined}\fi}
%
% And these are the interface functions. They should all set \sfx  to L, R or \@rig
%
\def\l@stLRspecific{}
\def\setLRspecific{\ifx\l@stLRspecific\c@rrdstat\else
    \edef\sfx{\ifdiglot\c@rrdstat\else \@rig\fi}%
    \trace{D}{setLRspecific:\l@stLRspecific -> \sfx}%
    \let\l@stLRspecific\c@rrdstat
    \let\wh@t\sp@cificSideDef\pr@cessSpecificDef
    \let\wh@t\sp@cificSideDim\pr@cessSpecificDim
    \let\wh@t\sp@cificSideCount\pr@cessSpecificCount
    \let\wh@t\sp@cificSideIf\pr@cessSpecificVarIf
  \fi
}% For use with style definitions, etc.

\def\SSsetLRspecific{\ifx\ds@ffix\empty\def\sfx{\@orig}\else\edef\sfx{\ds@ffix}\fi
  \let\wh@t\sp@cificSideDef\pr@cessSpecific}% for use in stylesheet, no need to check dimensions, just existance

\def\showLRspecific{\edef\sfx{\ifdiglot \c@rrdstat\else \@rig\fi}%
  \let\wh@t\sh@wSpecificDef\pr@cessSpecificDef
  \let\wh@t\sh@wSpecificDim\pr@cessSpecificDim
  \let\wh@t\sh@wSpecificDim\pr@cessSpecificCount %No need for separate sh@w.. macro
}% Call the output routines
\def\saveLRspecificSide#1{\edef\sfx{#1}% Save current values (side defined by #1) 
  \ifx\sfx\empty\let\sfx\@rig\fi
  \trace{S}{Redefining #1-specific values to current settings}%
  \let\wh@t\s@veSpecificSideDef\pr@cessSpecificDef
  \ifx\sfx\l@stLRspecific\else %If  l@stSpecific is #1, then \foo IS \foo#1 
    \let\wh@t\s@veSpecificSideDim\pr@cessSpecificDim
   %\let\wh@t\s@veSpecificSideCount\pr@cessSpecificCount % So far, nothing needs saving
  \fi
}
%
% Except this one:
%
\def\saveLRspecificOrig{% Save original values of side-specific variables. Force it to single use
  \trace{d}{saveLRspecificOrig \c@rrdstat}%
  \let\wh@t\s@veSpecificOrig\pr@cessSpecificAll\let\saveLRspecificOrig=\relax}

\def\restoreLRorig{%Dimens and counts must point back to their original value on closing a file
  \trace{d}{restoreLRorig}%
  %\tracingassigns=1
  \let\wh@t\restoreLR@rig\pr@cessSpecificDim
  \let\wh@t\restoreLR@rig\pr@cessSpecificCount
  %\tracingassigns=0
}
  

\maxdeadcycles=100
\newdimen\FontSizeUnitL\FontSizeUnitL=-1sp\newdimen\FontSizeUnitR\FontSizeUnitR=-1sp
\newdimen\le@dingunitL\le@dingunitL=-1sp\newdimen\le@dingunitR\le@dingunitR=-1sp
\newdimen\onel@neunitL\onel@neunitL=-1sp\newdimen\onel@neunitR\onel@neunitR=-1sp
\newdimen\verticalsp@ceunitL\verticalsp@ceunitL=-1sp\newdimen\verticalsp@ceunitR\verticalsp@ceunitR=-1sp
\newdimen\IndentUnitL\IndentUnitL=-1sp\newdimen\IndentUnitR\IndentUnitR=-1sp
\def\SpaceStretchFactorL{}\def\SpaceStretchFactorR{}
\def\SpaceShrinkFactorL{}\def\SpaceShrinkFactorR{}
\newif\ifRTLL \newif\ifRTLR
\x@\newif\csname ifinp@r-L\endcsname % Used for parlocs analysis
\x@\newif\csname ifinp@r-R\endcsname % Used for parlocs analysis
\x@\newcount\csname p@rlinesgone-L\endcsname % Used for parlocs analysis
\x@\newcount\csname p@rlinesgone-R\endcsname % Used for parlocs analysis
\x@\newcount\csname curr@djparL\endcsname % Used for adjust list
\x@\newcount\csname curr@djparR\endcsname % Used for adjust list
\x@\newcount\csname p@rnumL\endcsname % Used for triggers
\x@\newcount\csname p@rnumR\endcsname % Used for triggers
\newcount\@numcutsL % Used for cutouts
\newcount\@numcutsR % Used for cutouts
\newcount\dropped@ther@linesL % Used for cutouts
\newcount\dropped@ther@linesR % Used for cutouts

\def\xdef@cseq#1#2{\x@\xdef\csname #1\endcsname{#2}}% Helper function
\def\def@cseq#1#2{\x@\def\csname #1\endcsname{#2}}% Helper function
\def\empty@cseq#1{\x@\xdef\csname #1\endcsname{}}% Helper function
\def\newsideSpecificIf#1{% 'Tristate' if - true / false / default for configuration-file booleans (where default means the side-specific logic ought to let the global value take precedence
  \x@\def\csname #1true\endcsname{\x@\let\csname if#1\endcsname\iftrue}%
  \x@\def\csname #1false\endcsname{\x@\let\csname if#1\endcsname\iffalse}%
  \x@\def\csname #1default\endcsname{\x@\let\csname if#1\endcsname\undefined}%
}

\def\initcolumndef@ults#1{%
    \empty@cseq{n@xtbot#1mark}% Last X mark in the next chunk 
    \empty@cseq{n@xtfirst#1mark}%First X mark in the next chunk 
    \empty@cseq{old#1mark}%last X mark 
    \empty@cseq{first#1mark}%First X mark on this pave
    \empty@cseq{bot#1mark}%bottom X mark on this page
    \empty@cseq{oldfirst#1mark}%old First X mark on this pave
    \empty@cseq{oldbot#1mark}%old First X mark on this pave
    \empty@cseq{book#1}% Name of book to put in PDF.
    \empty@cseq{ch@plabel#1}% Chapter label
    \empty@cseq{@ch@pter#1}% Chapter Nuber
    \empty@cseq{@v@rse#1}% verse label
    \empty@cseq{BelowBaseline#1}% If not empty, fraction of baselineskip due to interlinear lines
    %\newsideSpecificIf{OmitChapterNumber#1} % global config option
    \newsideSpecificIf{OmitVerseNumberOne#1} % global config option
    \xdef@cseq{@cur#1ht}{0pt}% 
    \xdef@cseq{@cur#1dp}{0pt}% 
    \def@cseq{stylesheet#1}{\gdef\ds@ffix{#1}\stylesh@@t}% column-specific stylesheet
    \x@\def\csname addTo#1Hooks\endcsname{\addToSideHooks{#1}}
}
\initcolumndef@ults{L}%
\initcolumndef@ults{R}%

\def\doVisTrace#1{%
  \setbox0=\vtop to 0pt{\hrule height 0pt depth 0.5pt width 15pt \hbox{\VisTracefont #1 \the\TRACEcount}\vss}\ht0=0pt \dp0=0pt
}
\def\doVisTraceT#1{%
  \setbox0=\vbox to 0pt{\vss\hbox{\VisTracefont #1 \the\TRACEcount}\hrule height 0pt depth 0.5pt width 15pt}\ht0=0pt \dp0=0pt
}

\diglotfalse%
\newif\ifdiglotSepNotes %If the footnotes from the versions should be split (true) or merged together
\diglotSepNotestrue%
\newif\ifdiglotBalNotes %If a left column footnote steals space from the right column also
\diglotBalNotesfalse%
\newif\iftrialfailed
\global\def\n@xtc@mmand{}%

%\partial % fully set Partial page (both columns)
\newbox\n@xtpartialNrml % next chunk that we'll add to partial assuming all goes well - normal orientatin
\newbox\n@xtpartialRev % next chunk that we'll add to partial assuming all goes well - reversed orientation
\let\n@xtpartial=\n@xtpartialNrml

%\galley - as used in monoglot routines. This is the (holdinginserts=1) text. 
% saved by the first output routine. Unless void, it always ends with the appropriate
% end-of-trial penalty
\newbox\galleyexc@ss %This is the bit of the galley that didn't make it onto the current page
\newbox\wholeL  % input Galley contents on the left side
\newbox\partialL  % last Galley contents on the left side
\newbox\excessL  % Excess left material, aligning with the next right chunk.
\newbox\excessR  % Excess right material, once we know we're on the next page 
\newbox\wholeR  % input Galley contents on the right side
\newbox\partialR  % last Galley contents on the right side
\newbox\trialbox  % result of current trial, filled by  diglot@any@trial

%\newbox\partialPage \setbox\partialPage=\vbox{}
%\diglotLeft={\hsize=\columnLwidth\global\setbox\partialL=\vbox{\unvbox\partialL\unvbox255}}

\newif\ifrunLtrial % logic test in diglotLeft
\newif\ifintrial %flag to let setbox know...
\newif\ifloc@lht % loc@lhttrue when local column height tweaks should apply, false when this is for page full calcns, etc.

% Not the same as \c@lcavailht from paratext2.tex
\def\dglt@calc@vailht{%
   \trace{D}{dglt@calc@vailht \ifloc@lht loc@lht \else page \fi \c@rrdstat (\number\partial), \the\dimexpr \ht\partial+\dp\partial\relax + \the\dimexpr \ht\n@xtpartial+\dp\n@xtpartial\relax \space th=\the\textheight, trh=\the\trialheight}%
   \global\availht=\textheight %
   \global\advance\availht by -\ht\partial\relax %
   \global\advance\availht by -\dp\partial\relax %
   \global\advance\availht by -\ht\n@xtpartial\relax %
   \global\advance\availht by -\dp\n@xtpartial\relax %
   \trace{Dh}{after part1:\the\availht}%
   \ifcsname @nxtchunkLht\endcsname
     \ifdim\availht=\textheight\relax \else % joint calcs only apply if the page has content!
      
       {\edef\tmsg{@cur}\empty\l@gvals{@cur}{ht} \edef\tmsg{\tmsg\space @nxtchunk}\l@gvals{@nxtchunk}{ht}%
         \x@\def\x@\tmsg\x@{\tmsg}%
         \trace{Dh}{dglt@calc@vailht:  \tmsg}
       }%
       \ifcsname cts@list\endcsname \else\let\cts@list\diglot@list\fi
       \csname @do@jointcalc@\diglotlayout\endcsname{@nxtchunk}%
       \global\advance\availht by -\thisjointDelta \relax%
     \fi
   \fi
   \global\advance\availht by \adjustp@ge\relax % Panic measure.. Needs to be applied after checking for content.
   \trace{Dh}{after part2:\the\availht}%
   \f@rstnotetrue
   \let\\=\reduceavailht \the\n@tecl@sses % reduce it by the space needed for each note class
   \iff@rstnote\else
      \global\advance\availht by -\AboveNoteSpace\relax
   \fi
   \trace{Dh}{after notes:\the\availht}%
   \ifunprintable\else 
     \decr{\availht}{\topins}%pictures
     % Reduce by the height of whichever top picture takes the most space.
     \let\col@do=\max@Tinsdim
     \dimen1=0pt
     \x@\each@col\diglot@list\E%
     \trace{D}{inserts: \the\dimen1}%
     \ifdim\ht\topleftins>\ht\toprightins %
       \decr{\availht}{\topleftins}%
     \else%
       \decr{\availht}{\toprightins}%
     \fi%
     \trace{Dh}{after top:\the\availht (\the\ht\topleftins,\the\ht\toprightins}%
     \ifdim\ht\bottomleftins>\ht\bottomrightins %
       \decr{\availht}{\bottomleftins}%
     \else%
       \decr{\availht}{\bottomrightins}%
     \fi%
     \decr{\availht}{\bottomins}%
     \decr{\availht}{\verybottomins}%
   \fi
   \ch@ckiftextborderadj
   \iftemp
     \trace{Dh}{Border: \pretextb@rderskip, \posttextb@rderskip}%
     \global\advance\availht -\pretextb@rderskip  % Space reserved for text border.
     \global\advance\availht -\posttextb@rderskip 
   \fi
   \x@\global\x@\csname availht@com\endcsname=\availht
   \ifloc@lht
     \@bls=\csname b@selineskip\c@rrdstat\endcsname
     %\ifdim\baselineDelta<0pt %Account for space (falsely) lost to topskip FIXME, shouldn't this be side-dependent?
     %  \global\advance\availht by -\baselineDelta\relax%
     %\else
     %  \global\advance\availht by +\baselineDelta\relax%
     %\fi
     \global\advance\availht by \dimexpr -\@minb@seline-\baselineDelta\relax% 
     \trace{Dh}{Bld mod: -\@minb@seline - \the\baselineDelta -> \the\availht}%
     \dglt@calc@vailht@mods
   \fi
   \x@\global\x@\csname availht\c@rrdstat\endcsname=\availht
   \trace{D}{final:\the\availht}%
}

\def\dglt@calc@vailht@mods{%
   \x@\ifx\csname BelowBaseline\c@rrdstat\endcsname\empty\else
     \global\advance\availht by -\dimexpr \csname BelowBaseline\c@rrdstat\endcsname\dimexpr \csname b@selineskip\c@rrdstat\endcsname\relax\relax
     \trace{Dh}{BelowBaseline: \csname BelowBaseline\c@rrdstat\endcsname x \csname b@selineskip\c@rrdstat\endcsname -> \the\availht}%
   \fi
}
\newif\ifnastybox  % Signal that box must be treated specially
% The \lastpenalty before a \lefttext or \righttext issues a fake one,
% or similarly penalty to apply at end of trial text, and scratch space

%%%%%%%%%%%
% All penalties
%
\newcount\savedpenalty  % The penalty immediately preceeding a side-swap. AND ONLY THAT!
\def\savedLpenalty{0}% just storage.
\def\savedRpenalty{0}

\newcount\tmpcount%scratchspace
\newcount\curactivecols%how many active columns
\newcount\Lboxpenalty% The penalty that goes between Lbox and partialL
\newcount\Rboxpenalty%  ~"~
\newcount\partialLpenalty% The penalty that goes between partialL and excessL (also used while loading excessL during excessL
\newcount\partialRpenalty% ~"~
\newcount\endtri@lpen@lty %the penalty we EXPECT at the end of the trial
\newcount\chunkpenalty %highest penalty encoutered yet for this chunk 
\newcount\lastchunkpenalty %highest penalty previouschunk
\newif\ifLneedsemptying
\newif\ifallNeedEmptying %set by lefttext, etc. to indicate that the current chunk ends with the next side-transition. 
%\galleypenalty %the penalty we FOUND at the break between the %galley and \galleyexc@ss

% Initial \output routine for any side of scripture.
\def\diglot@any@primary{%
   \ifnum\the\outputpenalty=\dgl@tPenColSwap
     \setf@lwgdstat{\n@xtdstat}%
   \fi
   \trace{D}{diglot@any@primary: \show@dstat}%
   \p@gestarttrue % or at least, this isn't the right place to place things that go after a paragraph
} 


\newif\ifboxmoved%



\def\undog@lley{%
  \trace{d}{undog@lley}%
  \dimen9=\dp\galley
  \unvbox\galley\count255=\lastpenalty\unpenalty
  \tmpcount=\lastnodetype
  \ifnum\tmpcount=12\else\kern-\dimen9\fi%\lastnotedype=12 is eTeX test for kern (see above for longer list
  \ifVisTraceExtra\hbox to 0pt{\doVisTrace{t \the\ht\galleyexc@ss}\box0\hss}\fi
  \traceNum{D}{removed penalty \the\count255, replacing with \the\galleypenalty. lnt:\the\tmpcount (\decod@lastnode{\tmpcount})}%
  \ifvoid\galleyexc@ss\else
    \penalty\galleypenalty
    \unvbox\galleyexc@ss
  \fi
  \global\setbox\galleyexc@ss=\box\voidb@x\global\setbox\galley=\box\voidb@x
  \ifdiglotDebugFollowContents
    \trace{D}{Galley unrolled}%
    \showlists
  \fi
}

\def\rej@ctgalley{%For calling by trial routines that don't like the galley they've just been given 
  \trace{d}{rej@ctgalley (\c@rrdstat) reflow:\refl@wlist}%
  \r@storenotes{\g@tndstat}{1}%
  \r@storeinserts{col}
  \restore@oldmarks{\c@rrdstat}%
  \ifdim\trialheight<0pt
    \boxmovedtrue % and drop through
  \else
    \d@resplit@galley %
    %\global\output={\diglot@backingup}%
    %\global\intrialtrue
    %\global\vsize=\trialheight
    %\global\holdinginserts=1
    %\undog@lley
    %\penalty\endtri@lpen@lty
    %\relax
  \fi
}

\def\d@resplit@galley{%Old diglot@backingup's use of input stack caused needless problems.
  \traceNum{d}{d@resplit@galley \c@rrdstat\space\the\trialheight\space bls:\the\baselineskip\space @bls:\the\@bls}%
  \dimen0=\vfuzz
  \vfuzz=\maxdimen
  \global\setbox\galleyexc@ss\vbox{\undog@lley}%
  \setbox0\vbox{\penalty9000\unvcopy\galleyexc@ss}%
  \dimen1=\ht\galleyexc@ss\advance\dimen1 by \dp\galleyexc@ss\relax
  \ifdim\dimen1<\trialheight
    \trace{D}{ODD: trialheight bigger than contents. Probably a footnote/fig.  Reducing trialheight from \the\trialheight to \the\dimen1}%
    \global\trialheight=\dimen1
  \fi
  %\splittopskip=0pt
  \setbox1=\vsplit0 to \trialheight
  \setbox1=\vbox{\unvbox1}%
  \ifnum 1=\ifdim \ht1=0pt \ifdim\dp1=0pt 1 \else 0\fi \else 0\fi
    \trace{D}{Nothing wants to split from top of box: trial failed}%
    \ifdiglotDebugFollowContents\showbox\galleyexc@ss \fi
    \trialfailedtrue
    \global\trialheight=-\@bls
    \global\setbox\galley\box\voidb@x
    \vfuzz=\dimen0
    \let\after@this=\whichtrial
  \else 
    \trace{D}{Split result:ht=\the\ht1, dp=\the\dp1. Remainder \ifvoid 0 void\else \the\ht0+\the\dp0\fi}%
    \savingvdiscards=1
    \global\setbox\galley=\vsplit\galleyexc@ss to \trialheight
    \ifdiglotDebugFollowContents
      \trace{D}{Showing galley locn 3}%
      \showbox\galley%
    \fi
    \setbox3=\vbox{\vskip\dp\galley\splitdiscards}%
    \trace{D}{discard ht:\the\ht3}%
    \ifdiglotDebugFollowContents\showbox3 \fi
    \vfuzz=\dimen0
    \global\setbox\galley=\vbox{\unvbox\galley\global\galleypenalty=\lastpenalty\unpenalty\penalty\endtri@lpen@lty}%
    \ifvoid\galleyexc@ss\else
      \global\setbox\galleyexc@ss\vbox{\vskip\ht3\penalty10000\unvbox\galleyexc@ss}%
    \fi
    \trace{D}{galley/xs now \the\ht\galley+\the\dp\galley, / \the\ht\galleyexc@ss+\the\dp\galleyexc@ss, gp:\the\galleypenalty}%
    \ifnum\TRACEcount=\diglotDbgJoinboxes
     \showbox\galley\showbox\galleyexc@ss
    \fi
    \let\after@this=\d@rerun@trial
  \fi
  \after@this
}

\def\d@rerun@trial{%
  \global\holdinginserts=0
  \global\trialfailedfalse
  \global\intrialtrue
  \global\vsize=\availht
  \global\setbox\trialbox=\box\voidb@x
  \global\output={\diglot@any@trial}%calls \whichtrial on success
  \unvcopy\galley\relax %process newly-shrunk galley
  \ifdiglotDebugFollowContents
    \trace{D}{Showing galley Locn 1}%
    \showbox\galley
  \fi
}
\newif\ifNoMergeReflow
\newif\ifextr@content
\NoMergeReflowtrue % What to do when lastestagereflow is true and p@rtial is not empty. Changed on 16Dec2024. With false, an earlier column got repeated.

\def\run@a@trial{%
  \x@\global\x@\endtri@lpen@lty\x@=\csname dgl@tPen\c@rrdstat trialEnd\endcsname
  \traceNum{d}{run@a@trial \show@dstat, \the\availht>\csname b@selineskip\c@rrdstat\endcsname?, etp:\the\endtri@lpen@lty}%
  \x@\let\x@\p@rtl\csname partial\c@rrdstat\endcsname %last galley
  \x@\let\x@\@xcs\csname excess\c@rrdstat\endcsname %source
  \trace{D}{partial\c@rrdstat: \the\ht\p@rtl+\the\dp\p@rtl x\the\wd\p@rtl}% The contents of the galley that went to page last time
  \trace{D}{excess\c@rrdstat (\csname digl@txcs\c@rrdstat\endcsname): \the\ht\@xcs+\the\dp\@xcs x\the\wd\@xcs}% Material for this time
  \ifnum 1= \ifdiglotDebugFollowContents 1 \else \ifnum\TRACEcount=\diglotDbgJoinboxes 1\else 0\fi\fi
   \showbox\p@rtl
   \showbox\@xcs
  \fi
  \global\let\tri@lfirstmarks\empty
  \extr@contentfalse
  \let\after@run@a@trial=\relax
  \s@tbaseline{p}{p}%
  \trace{D}{baseline: \the\baselineskip, av:\the\availht}%
  \ifdim\availht>\baselineskip
    \trace{D}{Preparing for trial}%
    \global\trialheight=\availht
    \global\let\whichtrial=\after@a@trial
    \global\setbox\trialbox=\box\voidb@x
    \global\setbox\galleyexc@ss=\box\voidb@x
    \global\trialfailedfalse
    \global\intrialtrue
    \global\deadcycles=0
    \global\holdinginserts=0
    %Make sure partialX (last galley) is dropped or recycled ...
    \iflate@stage@reflow
      \trace{D}{restoring notes, re-flowing (\refl@wlist) partial\c@rrdstat\space and excess\c@rrdstat,}%
      \r@storenotes{\g@tndstat}{1}%
      %\showbox\p@rtl
      \ifvoid\p@rtl\else
        % FIXME: Merge boxes back together? More data needed! It didn't used to
        % be here, but surely it ought to be?
        % 2024-dec: one case where merging is wrong - duplicated chunk.
        \message{+++RARE CONDITION MET. Maybe doing wrong thing on page \the\pageno, debug posn \the\TRACEcount. Toggle with NoMergeReflow\ifNoMergeReflow false\else true\fi}%
        \ifNoMergeReflow\else
          \global\setbox\@xcs\vbox{\joinboxes{\p@rtl}{\@xcs}{2}{0}}%
          \x@\xdef\csname digl@txcs\c@rrdstat\endcsname{\c@rrdstat}%
        \fi
      \fi
      % No need to *save* notes after restoring, because they're already saved.
    \else
      \s@venotes{\g@tndstat}{1}%
    \fi
    \s@veinserts{col}%
    %grab 1st trialheight from excessX
    \ifnum\diglotDbgJoinboxes=\TRACEcount
      \showbox\@xcs
    \fi
    \dimen0=\ht\@xcs\advance\dimen0 by \dp\@xcs \relax
    \ifdim\dimen0<\trialheight
      \global\trialheight=\dimen0 %save useless trims.
    \fi
    \ifdiglotDebugFollowContents
      \trace{D}{Showing xcs before split}%
      \showbox\@xcs
    \fi
    \savingvdiscards=1
    \global\setbox\p@rtl=\vsplit\@xcs to \availht
    \edef\tmpbadness{\the\badness}%
    \global\p@rtlsettrue
    \global\setbox\p@rtl\vbox{\unvbox\p@rtl}%
    \setbox3=\vbox{\vskip\dp\p@rtl\splitdiscards}%
    \trace{D}{discard ht was \the\ht3}%
    \ifdiglotDebugFollowContents
      \showbox3
      \showbox\p@rtl
    \fi
    {\advance\availht by \baselineskip \relax% avoid underfull box in case of footnote
    \global\vsize=\availht}% let grouping undo addition
    \ifvoid\@xcs
      \x@\xdef\csname digl@txcs\c@rrdstat\endcsname{}%
    \else
      \x@\xdef\csname digl@txcs\c@rrdstat\endcsname{\c@rrdstat}%
      \global\setbox\@xcs=\vbox{\vskip\ht3\penalty10000\unvbox\@xcs}% %TeX will not split at glue with a penalty after it.
      \ifdiglotDebugFollowContents
        \trace{D}{Showing xcs after split}%
        \showbox\@xcs
      \fi
    \fi
    % Sadly, there isn't a \splitpenalty. Unwrap split discards and use that to see if there's a penalty there
    \setbox3\vbox{\count255=\csname partial\c@rrdstat penalty\endcsname\unvbox3 \unskip\unskip\count0=\lastnodetype \ifnum\count0=13 
        \count255=\lastpenalty \ifnum \count255>9999 \unpenalty\unskip\unskip\count255=\lastpenalty\fi %
        \trace{D}{Resetting partial\c@rrdstat penalty from \the\csname partial\c@rrdstat penalty\endcsname to \the\count255}%
        \global\csname partial\c@rrdstat penalty\endcsname=\count255 
      \fi
    }%
    \global\galleypenalty=0
    \global\setbox\galley=\vbox{\x@\unvcopy\p@rtl\unpenalty\global\@ftergalleyskip=\lastskip\unskip\penalty\endtri@lpen@lty}%
    \trace{D}{Running trial th:\the\trialheight, galley:\the\ht\galley+\the\dp\galley (\the\ht\@xcs+\the\dp\@xcs left for next time). ags=\the\@ftergalleyskip}%
    \ifdim\ht\galley=0pt \ifdim\dp\galley=0pt
      \trace{D}{How come galley has no size? (check with  scrollmode) \the\interactionmode}%
      \ifnum\interactionmode=2
        \showbox\galley
      \fi
    \fi\fi
    \global\output{\diglot@any@trial}
    \ifdiglotDebugFollowContents
      \trace{D}{Showing galley locn 4}%
      \showbox\galley
    \fi
    \unvcopy\galley
    \unpenalty
    \penalty\endtri@lpen@lty
    \relax\relax
    \let\after@run@a@trial=\relax
  \else
    \trace{D}{No space for trial}%
    \global\trialfailedtrue
    \let\after@run@a@trial=\after@after@a@trial
  \fi
  \after@run@a@trial
}


\newm@rknum{L}% registers m@rknumL
\newm@rknum{R}% registers m@rknumR

\def\after@a@trial{%
  %After this runs: (example with L)
  % Lbox contains *typeset* material
  % partialL contains *galley* for typeset material
  % excessL contains surplus material
  % Lboxpenalty contains penalty for a break after Lbox
  \traceNum{d}{after@a@trial \c@rrdstat, \the\holdinginserts, Op:\the\outputpenalty,
    tb:\the\ht\trialbox+\the\dp\trialbox,
    LBP:\the\Lboxpenalty, PLP:\the\partialLpenalty, SLP:\savedLpenalty,
    RBP:\the\Rboxpenalty, PRP:\the\partialRpenalty, SRP:\savedRpenalty,
    DCyc:\the\deadcycles,
    LB:\the\ht\Lbox+\the\dp\Lbox, av:\the\availht, vs:\the\vsize, pg:\the\pagegoal iftrialfailed\iftrialfailed true\else false\fi}%
  \ifnum\TRACEcount=\diglotDbgJoinboxes
   \showbox\trialbox\showbox\galleyexc@ss\showlists
  \fi
  \ifnum\outputpenalty=\endtri@lpen@lty
    \global\intrialfalse
  \fi
  \trace{H}{after@a@trial: b:\botmark/\botmarks1/\botmarks2, t:\topmark/\topmarks1/\topmarks2, f:\firstmarks1/\firstmarks2, fr:\firstRmark, br:\botRmark ol:\oldLmark}%
  %
  %Testing acceptability of result:
  \tempfalse
  \let\after@this=\after@after@a@trial
  \iftrialfailed\else
    \TempDim=\dimexpr \availht-\ht\trialbox\relax
    \ifdim \dp\trialbox > 0.5\baselineskip % Is the depth of the box significant?
      \advance\TempDim by -\dp\trialbox \relax
    \fi
    \ifvoid\galleyexc@ss %Was that the whole input?
      \x@\ifvoid\csname excess\c@rrdstat\endcsname
        \x@\ifnum\csname saved\c@rrdstat penalty\endcsname>9999
          \advance\TempDim by -2\baselineskip\relax
          \trace{D}{Penalty does not allow this as last item on page, checking there's 2 lines space: -> \the\TempDim}%
        \fi
        \ifdim \TempDim<-0.2\baselineskip %then Unacceptably over-full
          \trace{D}{Not enough space for the suggested galley}%
          \temptrue %
        \else
          \trace{D}{OK}%
        \fi
      \fi
    \fi
  \fi
  \iftemp
    \traceNum{D}{Rejecting \the\ht\partialL+\the\dp\partialL,\the\ht\galley+\the\dp\galley, :: \the\ht\galleyexc@ss+\the\dp\galleyexc@ss (\the\trialheight}%
    \ifnum\TRACEcount=\diglotDbgJoinboxes \relax
      \x@\showbox\csname partial\c@rrdstat\endcsname 
      \x@\showbox\csname excess\c@rrdstat\endcsname 
      \showbox\galley
    \fi
    \global\advance\trialheight by -1\baselineskip\relax
    \ifdim\trialheight>\baselineskip
      \let\after@this=\rej@ctgalley %reject and try again
    \else
      \global\trialfailedtrue
      \global\pagefulltrue
      \@trial@failed{2}%
    \fi
  \else
    \iftrialfailed %The 'simple' case.
      \@trial@failed{1}%
    \else
      \makevtop{\trialbox}%
      \ifvoid\galleyexc@ss
        %\tracingmacros=1\tracingassigns=1
        \TempDim=\availht %Recalc in case there's an issue
        \count255=\csname partial\c@rrdstat penalty\endcsname \def\tmp{partial }%
        \ifnum\count255=-10000 
          \x@\global\csname partial\c@rrdstat penalty\endcsname=0 
        \else
          \count255=\csname saved\c@rrdstat penalty\endcsname \def\tmp{saved }%
        \fi
        \trace{D}{\c@rrdstat boxpenalty changed from \the\csname \c@rrdstat boxpenalty\endcsname\space to \tmp value \the\count255}%
        \x@\global\csname \c@rrdstat boxpenalty\endcsname=\count255
      \else
        \trace{D}{\c@rrdstat boxpenalty changed from \the\csname \c@rrdstat boxpenalty\endcsname\space to galley value \galleypenalty}%
        \x@\global\csname\c@rrdstat boxpenalty\endcsname =\galleypenalty
        \x@\global\x@\setbox\csname excess\c@rrdstat\endcsname\vbox{\joinboxes{\galleyexc@ss}{\csname excess\c@rrdstat\endcsname}{4}{\x@\the\csname partial\c@rrdstat penalty\endcsname}}%
        \x@\xdef\csname digl@txcs\c@rrdstat\endcsname{\c@rrdstat}%
      \fi
      \global\setbox\galleyexc@ss=\box\voidb@x
      \ifdiglotDebugFollowContents
        \trace{D}{Showing galley locn 2}%
        \showbox\galley
      \fi
      \x@\global\x@\setbox\csname partial\c@rrdstat\endcsname\box\galley% Remember the old galley
      \x@\global\csname \c@rrdstat ht\endcsname=\dimexpr \ht\trialbox + \dp\trialbox\relax
      \x@\global\x@\setbox\x@\csname \c@rrdstat box\endcsname\box\trialbox
      \x@\global\x@\let\x@\m@rknum\csname m@rknum\c@rrdstat\endcsname
      \update@marks
    \fi
    \trace{D}{End of after@a@trial (\c@rrdstat) LB:\the\ht\Lbox+\the\dp\Lbox (\the\Lboxpenalty), RB:\the\ht\Rbox+\the\dp\Rbox (\the\Rboxpenalty)}%
    %\showlists
  \fi
  \after@this
}

\def\@trial@failed#1{%
  \trace{D}{trial failed (class #1), (end of?) input moved. refilling excess\c@rrdstat - \refl@wlist. \ifp@rtlset partial\c@rrdstat\space was set\fi}%(the start may have been set already
  %Undo the vsplit (all mtl into excessX)
  \x@\global\x@\setbox\csname excess\c@rrdstat\endcsname\vbox{\joinboxes{\csname partial\c@rrdstat\endcsname}{\csname excess\c@rrdstat\endcsname}{3}{\x@\the\csname partial\c@rrdstat penalty\endcsname}}%
  \x@\xdef\csname digl@txcs\c@rrdstat\endcsname{\c@rrdstat}%
  \ifdiglotDebugFollowContents
    \trace{D}{Showing galley@xcess}%
    \x@\showbox\galleyexc@ss
    \trace{D}{Showing restored excess\c@rrdstat}%
    \x@\showbox\csname excess\c@rrdstat\endcsname
    \x@\showbox\csname partial\c@rrdstat\endcsname
  \fi
  %\ifdim\dimexpr \ht\@xcs + \dp\@xcs + \wd\@xcs\relax=0pt \relax
  %\fi
  \let\col@do=\restore@oldmarks
  \x@\each@col\diglot@list\E
}


\def\update@marks@partone{%Called on the first part of any galley, finally (successful or not)
  \bgroup
    \x@\let\x@\m@rknum\csname m@rknum\c@rrdstat\endcsname
    \trace{H}{update@marks@partone: \c@rrdstat\space uses marks\m@rknum\space fm:\firstmarks\m@rknum, tm:\topmarks\m@rknum, bm:\botmarks\m@rknum}%
    \edef\t@st{\firstmarks\m@rknum}%
    \ifx\t@st\empty%
      \trace{H}{u@m@1: First mark was empty}% Presumably others also
    \else
      \x@\let\x@\t@@st\csname bot\c@rrdstat mark\endcsname%
      \x@\let\x@\ot@@st\csname oldbot\c@rrdstat mark\endcsname%
      \trace{H}{bot\c@rrdstat mark='\t@@st', firstmark:'\t@st', oldbot\c@rrdstat mark '\ot@@st'}%
    \fi 
    \ifx\t@@st\empty
      \let\t@@st\ot@@st
    \fi
    \trace{H}{u@m@1:'\t@st'='\t@@st'?}% 
    \ifx\t@st\t@@st
      \trace{H}{u@m@1: First mark was carry-over, not remembering it}% Presumably others also
    \else
      \trace{H}{u@m@1: remembering firstmark}% Presumably others also
      \global\let\tri@lfirstmarks\t@st
      \global\extr@contentfalse % This is ONLY valid if there's acceptable content later on.
    \fi
  \egroup
}

\def\update@marks{% Called on successful galley
\x@\let\x@\m@rknum\csname m@rknum\c@rrdstat\endcsname
\trace{H}{update@marks: \c@rrdstat\space uses marks\m@rknum\space fm:\firstmarks\m@rknum, tm:\topmarks\m@rknum, bm:\botmarks\m@rknum}%
  \ifextr@content
    \ifx\tri@lfirstmarks\empty%
      \edef\tri@lfirstmarks{\firstmarks\m@rknum}%
    \fi
  \else
    \edef\tri@lfirstmarks{\firstmarks\m@rknum}%
  \fi
  \ifx\tri@lfirstmarks\empty%
    \trace{H}{u@m: First mark was empty}% Presumably others also
  \else%
    \x@\let\x@\t@@st\csname bot\c@rrdstat mark\endcsname%
    \x@\let\x@\ot@@st\csname oldbot\c@rrdstat mark\endcsname%
    \trace{H}{bot\c@rrdstat mark='\t@@st', firstmark:'\tri@lfirstmarks', oldbot\c@rrdstat mark '\ot@@st'}%
    \ifx\t@@st\empty
      \let\t@@st\ot@@st
    \fi
    \trace{H}{u@m:'\tri@lfirstmarks'='\t@@st'?}% 
    \ifx\tri@lfirstmarks\t@@st
      \trace{H}{update@marks: First mark was carry-over}% Presumably others also
      \x@\xdef\csname n@xtfirst\c@rrdstat mark\endcsname{}%
    \else % do not use if \firstmark,botmark are a carry-over,
      \trace{H}{u@m: Setting bot\c@rrdstat mark to \botmarks\m@rknum [!=\csname oldbot\c@rrdstat mark\endcsname]}%
      \global\m@rksonpagetrue
      \x@\xdef\csname oldfirst\c@rrdstat mark\endcsname{\csname first\c@rrdstat mark\endcsname}%
      \x@\xdef\csname oldbot\c@rrdstat mark\endcsname{\csname bot\c@rrdstat mark\endcsname}% Remember botmark in case this chunk isn't on the page
      \x@\xdef\csname bot\c@rrdstat mark\endcsname{\botmarks\m@rknum}%
      \x@\xdef\csname n@xtfirst\c@rrdstat mark\endcsname{\tri@lfirstmarks}%If the chunk moves, then this will be the appropriate start-point
      \x@\xdef\csname n@xtbot\c@rrdstat mark\endcsname{\botmarks\m@rknum}%If the chunk moves, then this will be the appropriate end-point
      \x@\ifx\csname first\c@rrdstat mark\endcsname\empty
        \trace{H}{u@m: Setting first\c@rrdstat mark to \tri@lfirstmarks}%
        \x@\xdef\csname first\c@rrdstat mark\endcsname{\tri@lfirstmarks}%If the chunk moves, then this will be the appropriate start-point
        \edef\t@st{\p@gefirstmark}%
        \ifx\t@st\empty%
          \trace{H}{dlt3: Setting (default) pagefirstmark to \tri@lfirstmarks}%
          \xdef\p@gefirstmark{\tri@lfirstmarks}%
        \fi
      \fi
    \fi
  \fi
}


\newdimen\@bls % Temp baselineskip
\def\diglot@any@trial{%output routine for any column
 % Handles calling d@resplit@galley
 %Stashes set material in \trialbox, discards extra,
 %if the galley fits then there are no discards and 
 %it calls whichtrial 
 %as though it hadn't been here.
 %Assumptions: holdinginserts=1 material in \galley and \galleyexc@ss
  \traceNum{d}{diglot@any@trial \c@rrdstat\space \the\ht255+\the\dp255 \space hIns=\the\holdinginserts(==0 1st time) op=\the\outputpenalty, etp=\the\endtri@lpen@lty, dc=\the\deadcycles, xs:\the\ht\galleyexc@ss+\the\dp\galleyexc@ss, th:\the\trialheight, p:\the\ht\p@rtl}%
  \@bls=\csname b@selineskip\c@rrdstat\endcsname
  \ifnum\holdinginserts=0\relax\else
    \ifvoid\trialbox
      \MSG{*** Internal error caught. Incorrect internal state found in during trial run. Text or footnotes may have been lost.}%
      \ifnum\interactionmode=2
        \showbox255
        \showlists
      \fi
    \fi
  \fi
  \ifdim\@ftergalleyskip=0pt \else 
    \setbox255\vbox{\unvbox255}%
    \ifdim\dimexpr \trialheight-\ht255-\dp255 - \@ftergalleyskip\relax >0pt
      \trace{D}{reinserting @ftergalleyskip (\the\@ftergalleyskip) after trial}%
      \setbox255\vbox{\unvbox255\vskip\@ftergalleyskip}%
    \else
      \trace{D}{Not reinserting @ftergalleyskip (\the\@ftergalleyskip), as there's no space for it}%
  \fi\fi
  \ifnum\diglotDbgJoinboxes=\TRACEcount\relax
    %{\setbox0\vbox{\pagediscards}\showbox0}%
    \showbox255
  \fi
  \ifm@rksonpage\else
    \tempfalse{%
    \ifvoid\trialbox %This is the 1st box
      \setbox0\copy255
    \else
      \setbox0\copy\trialbox
    \fi
    \setbox1=\vsplit 0 to \maxdimen \edef\tmp{\splitbotmark}%
    \ifx\empty\tmp\else
      \ifx\tmp\t@tle\else
        \aftergroup\temptrue% Pass out true value
      \fi
    \fi
    }\iftemp
      \trace{D}{m@rks on trial chunk}%
      \m@rksonpagetrue %here are marks in this trial column. Don't set it globally as it might not stick.
    \fi
  \fi
  \loc@lhttrue\dglt@calc@vailht
  \TempDim=\availht
  \trace{dP}{bld:\the\baselineDelta}%
  {% Don't autmatically remove baselinedelta... that'd be wrong for titles, etc.
    \vfuzz=\maxdimen
    \setbox0=\vbox{\penalty0\unvcopy255}%
    \setbox1=\vsplit0 to 0pt % Remove topskip glue
    \setbox2=\hbox{\count255=\XeTeXuseglyphmetrics\relax\XeTeXuseglyphmetrics=0\relax \char65  \XeTeXuseglyphmetrics=\count255}%
    \setbox3=\vbox{\splitdiscards}% Discards contains topskip glue and other stuff. Other stuff should have gone into page discards by  now.
    \dimen1=\ht3
    \ifdim\dimen1>\topskip
      \message{+++Uh oh. Didn't expect this. Now what? Discards \the\dimen1 > topskip \the\topskip}%
    \fi
    \dimen3=\csname gridding@scent\c@rrdstat\endcsname
    \trace{D}{Topskip glue was \the\ht3, basic line is \the\dimen3\space high.  bls:\the\@bls}%
    \dimen0=\baselineDelta
    %\showbox3
    \ifdim\dimen1=0pt 
      \dimen0=0pt %No adjustment, it's too tall and already been gridded, we hope
    \fi
    \xdef\@djustskip{\the\dimen0}%
    \trace{D}{Adjusted topskip correction \the\dimen0}%
  }%
  \setbox255=\vbox{\vskip\@djustskip\penalty10000\unvbox255}%
  \ifdiglotDebugFollowContents
    \showbox255
  \fi
  \ifdim\ht255>0pt
    \advance\TempDim by -\ht255\relax
    \advance\TempDim by -\dp255\relax
  \else
    \advance\TempDim by \ht255\relax
    \advance\TempDim by -\dp255\relax
  \fi 
  \ifvoid\trialbox
    \global\setbox\trialbox=\vbox{\unvbox255}%
    \ifdiglotDebugFollowContents
      \showbox\trialbox
    \fi
    \update@marks@partone
    \ifdim\TempDim<-0.3\@bls % Coarse test. main trial routine can be pickier if it wants
      \trace{D}{Initial Content does not fit (\the\trialheight, \the\TempDim, \the\availht)}%
      \global\holdinginserts=1
      \global\trialfailedtrue
    \else
      \trace{D}{Initial content fits(th:\the\trialheight, av:\the\availht, box:\the\ht\trialbox d:\the\TempDim)}%
      \ifdim \TempDim > 2\@bls
        \vsize=\TempDim
      \fi
    \fi
  \else
    \advance\TempDim by -\ht\trialbox\relax
    \advance\TempDim by -\dp\trialbox\relax
    \ifdim\TempDim<-0.3\@bls 
      \trace{D}{Extra content found before end of trial, \the\ht255+\the\dp255}%
      \ifnum\outputpenalty=\endtri@lpen@lty\relax\else
        %\showbox\trialbox
        %\showbox\galley
        %\showbox\galleyexc@ss
        %\showlists
      \fi
      \global\holdinginserts=1
      \global\trialfailedtrue
      \global\vsize=\textheight
      \global\setbox255\box\voidb@x
    \else
      \iftrialfailed
        \global\setbox255\box\voidb@x
      \else
        \dimen1=\csname baselineDelta\c@rrdstat\endcsname 
        \advance\dimen1 -\baselineDelta
        \global\extr@contenttrue
        \trace{d}{Extra material found, which also fits (\the\ht255+\the\dp255) - \the\dimen1 \space \the\TempDim remaining. \show@dstat}%
        \setbox255=\vbox{\vskip\dimen1\unvbox255}%
        \global\setbox\trialbox=\vbox{\joinboxes{\trialbox}{255}{5}{0}}%
        \ifdim \TempDim > 2\@bls
          \vsize=\TempDim
        \fi
      \fi
    \fi
  \fi
  \let\after@this=\relax
  \ifnum\outputpenalty=\endtri@lpen@lty\relax
    \global\intrialfalse
    \iftrialfailed
      \global\advance\trialheight by -1\@bls\relax
      \ifdim\trialheight<0.5\@bls
        \trace{D}{Abandoning trial for \c@rrdstat, no space for galley at all}%
        %\ifdiglotDebugFollowContents
          %\ifp@rtlset \showbox\p@rtl\fi
        %\fi
        \r@storenotes{\g@tndstat}{1}% As if galley hadn't happened.
        \r@storeinserts{col}%
        \global\setbox\galleyexc@ss\vbox{\undog@lley}%
        \global\galleypenalty=0 
        \global\setbox255=\box\voidb@x
        \let\after@this=\whichtrial% 
      \else 
        \traceNum{D}{Backing up \the\@bls \space and trying again (\the\trialheight)}%
        \r@storenotes{\g@tndstat}{1}%
        \r@storeinserts{col}
        \let\after@this=\d@resplit@galley
      \fi
    \else
      \trace{D}{All looks good!  \the\ht\trialbox+\the\dp\trialbox (gp:\the\galleypenalty, op: \the\outputpenalty)}%
      %\box\trialbox
      %\global\outputpenalty=\galleypenalty
      \let\after@this=\whichtrial
    \fi
  \else
    \iftrialfailed
      \traceNum{D}{Trial failed with output penalty \the\outputpenalty}%
      %\global\setbox\galleyexc@ss\vbox{\undog@lley}% This didn't help
    \fi
  \fi
  \after@this
}

% Change which side we're adding to
\def\pr@sideswitch#1#2{%
  \tmpcount=\lastpenalty% This MUST be first (at least, before any writes), or the last /thing/ won't be a penalty
  \ifdiglotcolh@scontent %Only actually save lastpenalty if there is some real content before it. 
    \global\savedpenalty=\tmpcount
  \else
    \ifdim\pagetotal>0pt
      \global\savedpenalty=\tmpcount
    \fi
  \fi
  \tmpcount=\lastnodetype
  \ifintrial
    %\showlists
    \message{!!! EEK. Internal error detected. #1 met during trial, somewhere near \c@rref}%
  \fi
  \traceNum{D}{Initial savepenalty \the\savedpenalty}%
  \IfTr@ce{C}{{%
    \x@\let\x@\tmp\csname ch@pter\g@tdstat waiting\endcsname
    \x@\let\x@\tmpL\csname ch@pterwaiting\endcsname\ifx\tmpL\relax\let\tmpL\space\fi
    \x@\let\x@\tmpR\csname ch@pterRwaiting\endcsname\ifx\tmpR\relax\let\tmpR\space\fi
    \tr@ceout{C}{pr@sideswitch \c@rrdstat: \ifx\tmp\relax\else cw:\tmp\fi(\tmpL/\tmpR), ccn:\ch@pterc@tnum, nc:\the\@numcuts}%
  }}%
  \ifx\c@rrdstat\empty
    \trace{d}{\c@rrdstat is empty, somehow, making it L for sanity}%
    \gdef\c@rrdstat{L}%
  \fi
  \endlastp@rstyle{p}%
  \saveVarLRSpecific
  \x@\ifnum\csname saved\c@rrdstat penalty\endcsname=-10000
    \trace{D}{restoring savedpenalty (was\the\savedpenalty) to -10000 from saved\c@rrdstat penalty}%
    \global\savedpenalty=-10000
  \fi
  \global\let\layoutstylebreak\enddigl@t % 
  \ifhe@dings\endhe@dings
    \global\savedpenalty=\lastpenalty % Pick up revised after-heading penalty
    \traceNum{D}{Got \the\savedpenalty from headings}%
    \ifnum\TRACEcount=\diglotDbgJoinboxes
      \showboxbreadth=100
      \showlists
    \fi
  \fi%
  \trace{d}{pr@sideswitch #1 #2, sp:\the\savedpenalty\space lnt:\the\tmpcount, op:\the\outputpenalty, pg: \the\pagegoal, pt:\the\pagetotal}%
  \checkfort@c % as good a place as any
  %\ifnum\outputpenalty=-10000 %User-pagebreak
    %\global\savedpenalty=\outputpenalty
  %\fi
  \x@\xdef\csname saved\c@rrdstat penalty\endcsname{\the\savedpenalty}%
  \ifinn@te\errmessage{*** #1text called from inside footnote?!?}\fi
  \ifx\last@popped@parstyle\relax\else
    \x@\let\csname m@rker\c@rrdstat\endcsname\last@popped@parstyle %save the old (paragraph-style) marker 
  \fi
  \x@\global\x@\let\csname mcstack\c@rrdstat\endcsname\mcstack %save the current (stack) 
  \trace{d}{pr@sideswitch #1 (\c@rrdstat) pL:\the\dp\partialL, xL:\the\dp\excessL, pR:\the\dp\partialR, xR\the\dp\excessR, lp:\the\savedpenalty \ifallNeedEmptying\space  allNeedemptying\fi \ifdiglotcolh@scontent\space diglolcolh@scontent\fi [\digl@tc@ntentlist|\digl@tc@ntent@xcs]}%
  \edef\tmp{#2}
  
  \ifdiglotcolh@scontent
    \ifx\tmp\empty\else
      \save@cutouts{\c@rrdstat}%
    \fi
  \else
    \del@from@digl@tc@ntentlist{\c@rrdstat}%
  \fi
  %\showlists
  %\global\savedpenalty=0 % avoid cross-contamination
  \global\output={\diglotCollect}%Why woudn't it be? Don't know, but sometimes it's not.
  \let\@ldstat=\c@rrdstat
  \@@setside{#2}%Set the side to occur after the next swapcols penalty
  \ifx\tmp\empty\else
    \restore@cutouts{#2}%
  \fi
  \ifdiglotcolh@scontent \temptrue \fi
  \ifnum\savedpenalty=-10000 \temptrue\fi
  \iftemp
    \endgraf\penalty\dgl@tPenColSwap\relax %Trigger collection of text.
    % <<< Diglot collect runs HERE! (and sets n@xtc@mmand
    \relax
  \fi
  \ifintrial 
    \message{EEK! Still in trial! on page \the\pageno, somewhere near \c@rref. Expect synchronisation and text loss}%
    \vskip0pt % some content...
    \penalty\dgl@tPenColSwap\relax %Trigger collection of text.
  \fi
  \let\t@mpc@mmand=\n@xtc@mmand% This bit may process the collected input. 
  \x@\xdef\csname c@rrfontsize\@ldstat\endcsname{\c@rrfontsize}% Remember the fontsize before column-swap
  \trace{D}{c@rrfontsize saved for side \@ldstat.}%
  \global\def\n@xtc@mmand{}%
  \t@mpc@mmand
} 


\outer\def\lefttext{%
  \pr@sideswitch{lefttext}{L}%
  \global\allNeedEmptyingfalse
  \swap@diglot{L}%sets diglot state, etc
  \global\vsize=\maxdimen
  \global\availht=\vsize
  %Other Left parameters
  \output={\diglotCollect}\relax%
  \global\holdinginserts=1
  \the\diglotLho@ks
}%

\outer\def\righttext{%
  \pr@sideswitch{righttext}{R}%
  \global\allNeedEmptyingtrue % Text after this needs emptying
  \swap@diglot{R}%sets diglot state, etc
  \global\vsize=\maxdimen
  \relax\output={\diglotCollect}%
  \global\holdinginserts=1
  \the\diglotRho@ks
}
%
% When there's a header on the left but not the right, but we want the verses
% to line up nicely...
\def\norighttext{%
  \global\allNeedEmptyingtrue% Text before the swap needs emptying
  \pr@sideswitch{norighttext}{L}%
  \swap@diglot{L}%sets diglot state, etc
  \global\vsize=\maxdimen
  \global\holdinginserts=1
  \the\diglotLho@ks
}

%Similarly when there's no left text, almost-copying \righttext seems OK ...
\def\nolefttext{%
  \global\allNeedEmptyingtrue% Text before the swap needs emptying
  \pr@sideswitch{nolefttext}{R}%
  \global\allNeedEmptyingtrue% Text after the swap ALSO needs emptying, in case \righttext not used
  \swap@diglot{R}%sets diglot state, etc
  \global\vsize=\maxdimen
  \global\holdinginserts=1
  \the\diglotRho@ks
}

\def\polyglotendcols{%
  \global\allNeedEmptyingtrue% Text before the swap needs emptying
  \trace{D}{t@tle is \ift@tle set\else  not set\fi}%
  \trace{D}{he@dingstyle is \ifhe@dingstyle set\else  not set\fi}%
  \trace{D}{he@dings is \ifhe@dings set\else  not set\fi}%
  \pr@sideswitch{endcols}{\empty}%
  \diglot@run@trials
  \global\allNeedEmptyingfalse
}

\def\polyglotcolumn#1{%
  \uppercase{\edef\reqcol{#1}}%
  \seriesdiglotfalse
  \global\let\layoutstylebreak\enddigl@t
  \ifx\reqcol\empty\errmessage{polyglotcolumn may not be called with an empty argument}\fi
  \pr@sideswitch{polyglotcolumn #1}{\reqcol}% Before any non-fatal writes
  \ifcsname #1isDiglotColumn\endcsname % 
    \csname @preswap@\diglotlayout\endcsname{#1}%
    \swap@diglot{#1}%sets diglot state, etc
    \csname @postswap@\diglotlayout\endcsname{#1}%
    \global\vsize=\maxdimen
    \global\holdinginserts=1\relax
    \x@\the\csname diglot#1ho@ks\endcsname\relax
  \else
    \errmessage{polyglotcolumn must be followed by a sensible argument. '#1' Hasn't been specified as a polyglot column (with newPolyglotCol), before any USFM files are read.}%
  \fi
}

\def\zglot|#1\*{\edef\tmp{\zap@space #1 \empty}%
  \ifx\tmp\empty\diglotfalse
    \ifinptxfile\else\gdef\atn@xtptxfile{\message{starting monglot file with no specific side (\c@rrdstat)}}\fi
    \global\let\c@rrdstat\empty
  \else\x@\monoglotcolumn\x@{\tmp}\fi}

\newif\ifseriesdiglot

\def\monoglotcolumn#1{%
  \trace{d}{monoglotcolumn #1 (\show@dstat)}%
  \ifcsname #1isDiglotColumn\endcsname % 
    \ifinptxfile
      \ifsk@pping\egroup\fi
      \endlastp@rstyle{monoglotcol}%
      \diglottrue % Use diglot settings/styles
      \seriesdiglottrue %
      \@setside{#1}%
      \@@switchstyles{#1}%
      \x@\the\csname diglot#1ho@ks\endcsname\relax
    \else
      \diglotfalse
      \gdef\atn@xtptxfile{\monoglotcolumn{#1}}%
    \fi
  \else
    \errmessage{zglot must be followed by a sensible argument. '#1' Hasn't been specified as a polyglot column (with newPolyglotCol), before any USFM files are read.}%
  \fi
}

\let\LisDiglotColumn\empty
\let\RisDiglotColumn\empty

\newdimen\columnLwidth%
\newdimen\columnRwidth%
\newdimen\availhtL
\newdimen\availhtR
\newdimen\availht@com % Common 
\newdimen\chunkDelta % Difference between the last boxes prepared for the page (-ve=left longer)
\newdimen\p@geChunkDelta \p@geChunkDelta=0pt %as above, but *added* to the page.
\newdimen\baselineDelta % semi-constant: largest difference between any  baselines and \topskip.  
\newdimen\baselineDeltaL % semi-constant: difference between the L baseline and \topskip.  Set in ptx-stylesheet (should be -ve=topskip longer) 
\newdimen\baselineDeltaR % semi-constant: difference between the R baseline and \topskip.  Set in ptx-stylesheet (should be -ve=topskip longer) 
\newdimen\thisjointDelta % difference between the L and R boxes (-ve=left longer)
\newcount\cumulativeDeltaL % Sum of \chunkDelta values, in points
\newcount\cumulativeDeltaR % Sum of \chunkDelta values, in points
\cumulativeDeltaL=0
\cumulativeDeltaR=0
\newcount\cumulativeDelta % Sum of \chunkDelta values, in points
\newdimen\adjustp@ge %emergency stretch to page
\newdimen\@ftergalleyskip % if there's a skip at the end of the galley, it gets stored here.
\adjustp@ge=0pt
\def\m@rkerL{}
\def\m@rkerR{}
\let\mcstackL\mcstack@mpty
\let\mcstackR\mcstack@mpty
%Diglotstate.
\def\n@xtdstat{L}%What does the diglotstate become at the next \dgl@tPenColSwap penalty?
\def\f@lwgdstat{L}%What is the diglotstate of the 'recent contributions'? (i.e. next material to read)
\def\c@rrdstat{}%What is the current diglotstate, in loops?
\def\@g@tdst@t#1{\ifdiglot\if L#1\else#1\fi\fi}% Returns "" or "R" (Or other state values in the future)
\def\g@tdstat{\@g@tdst@t\c@rrdstat}% Normal access routine for above
\def\@g@tndstat#1{\ifdiglotSepNotes \if L#1\else#1\fi\fi} %if notes are merged, there should be no R (etc)  suffix notes.
\def\g@tndstat{\@g@tndstat{\c@rrdstat}} %if notes are merged, there should be no R (etc)  suffix notes.

\def\show@dstat{\c@rrdstat\f@lwgdstat\n@xtdstat}% for debugging output 
\def\setc@rdstat#1{\xdef\c@rrdstat{#1}%
 \ifx\c@rrdstat\empty
   \diglotfalse % Is this necessary? YES.
   \trace{d}{current diglot state set to empty! End of diglot?}%
 \else 
   %\diglottrue % Is THIS necessary?
 \fi
}
\def\usediglot#1{\xdef\c@rrdstat{#1}}

\def\resetc@rdstat{\xdef\c@rrdstat{\f@lwgdstat}}% Restore to correct value for new text. Mainly for use in Collect

\def\diglotLtrue{%
  \oldboole@n{L}{diglotLtrue}%
}
\def\diglotRtrue{%
  \oldboole@n{R}{diglotRtrue}%
}
\def\diglotLfalse{%
  \oldboole@n{L}{diglotLfalse}%
}
\def\diglotRfalse{%
  \oldboole@n{R}{diglotRfalse}%
}

\def\oldboole@n#1#2{%
  \message{diglot#1true is deprecated. The normal column switching method is to use (no)lefttext / (no)righttext or the new  polyglotcolumn and endcols macros}%
  \polyglotcolumn{#1}%
}

\def\setf@lwgdstat#1{\xdef\f@lwgdstat{#1}%
}

\def\@setside#1{\setf@lwgdstat{#1}\setc@rdstat{#1}\xdef\n@xtdstat{#1}}

\def\@@setside#1{\trace{D}{@@setside #1}%
   \xdef\n@xtdstat{#1}%
   }%

\def\filter@list#1{%Add #1 to  @results if it is NOT \test
  \edef\t@st{#1}\ifx\t@st\test\else
    \edef\@results{\@results#1}%
  \fi
}
  
\def\del@from@digl@tc@ntentlist#1{% This column had no context, despite what we expected
  \ifx\digl@tc@ntentlist\empty\else
    \edef\test{#1}\let\@results\empty%
    \let\col@do=\filter@list
    \x@\each@col\digl@tc@ntentlist\E
    \global\let\digl@tc@ntentlist\@results
  \fi
}

\def\check@dup#1{%set temptrue if \test is the same as #1
  \edef\t@st{#1}\ifx\t@st\test\temptrue\fi
}

\def\add@to@digl@tc@ntentlist#1{%
  \trace{d}{add@to@digl@tc@ntentlist #1 (\digl@tc@ntentlist)}%
  \edef\test{#1}%
  \tempfalse
  \let\col@do=\check@dup
  \ifx\digl@tc@ntentlist\empty\else
    \x@\each@col\digl@tc@ntentlist\E
  \fi
  \iftemp
    \trace{D}{Surprising request ignored}%
  \else
    \xdef\digl@tc@ntentlist{\digl@tc@ntentlist #1}%
  \fi
  \trace{D}{digl@tc@ntentlist now:(\digl@tc@ntentlist)}%
}

\def\swap@diglot#1{% Because we need to set things appropriately.
 %Swapping fonts isn't actually needed, as that's done elsewhere, but do need to set
 %baselineskip and other things
 \trace{d}{swap@diglot #1 (\show@dstat)}%
 \trace{D}{t@tle is \ift@tle set\else  not set\fi}%
 \trace{D}{he@dingstyle is \ifhe@dingstyle set\else  not set\fi}%
 \trace{D}{he@dings is \ifhe@dings set\else  not set\fi}%
 %All sorts of things should follow if mcstack is set properly...
 \@setside{#1}%Ought to be needless
 \@@switchstyles{#1}% Set up fonts and things.
 \add@to@digl@tc@ntentlist{#1}%
 \ifnum\@numcuts>0
   \x@\let\x@\tmp\csname @#1egap\endcsname
   \ifdim \tmp >\baselineskip
     \count255=\dimexpr \tmp / \baselineskip\relax
     \trace{C}{Cutout \c@rrdstat \space needs to be adjusted by (\tmp / \the\baselineskip) \the\count255}%
     \prevgraf=\the\count255 
     \cutoutcarryover
   \fi
 \fi
 \x@\let\x@\w@dth\csname column#1width\endcsname
 \global\hsize=\w@dth\relax
 \global\diglotcolh@scontentfalse
 \trace{D}{end of swap@diglot: lsl=\the\lineskiplimit, ts=\the\topskip, bs=\the\baselineskip}%
}%


\def\setdiglotlang#1{
 \ifcsname language#1\endcsname
    \x@\language\csname language#1\endcsname
 \fi
}
\def\@@switchstyles#1{%
  \ifcsname c@rrfontsize#1\endcsname
    \global\x@\let\x@\c@rrfontsize\csname c@rrfontsize#1\endcsname
    \trace{D}{c@rrfontsize set to \c@rrfontsize}%
  \fi
  \x@\global\x@\let\x@\mcstack\csname mcstack\c@rrdstat\endcsname
  \x@\global\x@\let\x@\m@rker\csname m@rker\c@rrdstat\endcsname
  \ifx\mcstack\empty\let\mcstack\mcstack@mpty\fi
  \s@tstyst@k
  \trace{D}{mcstack set to '\mcstack', styst@k set to '\styst@k', m@rker to '\m@rker'}%
  \x@\stystacksplit\styst@k+\E
  \x@\global\x@\let\x@\ch@pter\csname @ch@pter\g@tdstat\endcsname
  \x@\global\x@\let\x@\ch@ptert@xt\csname @ch@ptert@xt\g@tdstat\endcsname
  \x@\global\x@\let\x@\v@rse\csname @v@rse\g@tdstat\endcsname
  \x@\global\x@\let\x@\m@rknum\csname m@rknum\c@rrdstat\endcsname
  \p@rstyle@everypar{\m@rker}\ifx\m@rker\empty\else\s@tfont{\m@rker}{\m@rker}\fi
  \trace{D}{chapter/verse set to \ch@pter(\ch@ptert@xt)/\v@rse(\m@rknum)}%%
  \setLRspecific %ensure that all the units, etc. are correct.
  \trace{D}{Leadingunit: \the\le@dingunit, stylestack:\styst@k, \mcstack}%
 \ifdim\le@dingunit>0pt %
   \s@tbaseline{p}{p}%
 \fi%
 \ifdim\baselineskip=0pt %
  \message{baseline set to 0pt EEK}%
  \global\baselineskip=12pt
 \fi%
 %Also need to switch hyphenation patterns. if there's a lang@\csname languageX\endcsname (as defined by addlanguage) use that. If not, use \languageX as an int.
 \setdiglotlang{#1}%
 \tmpcount=\the\pageno
 \advance\tmpcount by \MaxPagesPerChunk\relax 
 %\message{\the\pageno + \MaxPagesPerChunk = \the\tmpcount}%
 \ifnum\tmpcount>\MaxPages \global\MaxPages=\tmpcount
   %\message{Maxpages now : \the\MaxPages}%
 \fi
}

%\output={\diglotLeft}
%\hsize=\columnLwidth
\newif\ifpagefull % Is the page full?
\newif\iflate@stage@reflow % Is the trial code re-running a previous galley or processing the next chunk?

\newdimen\Lht
\newdimen\Rht %
\newdimen\TempDim %
\newbox\Lbox % The processed version of partialL (inserts released)
\newbox\Rbox % The processed version of partialR (inserts released)
%\newbox\Ldiscards %what did tex discard at the top of this chunk?
%\newbox\Rdiscards %what did tex discard at the top of this chunk?

%when there's no more input, make sure partial gets printed
\def\emitpartial{%
       \traceNum{d}{Emitpartial \the\ht\partial+\the\dp\partial, \the\ht\n@xtpartial+\the\dp\n@xtpartial}%
       \@add@n@xtpartial
       \@writep@ge\@writep@ge%
       \global\pagefullfalse%
}

\def\makevtop#1{%There is a strong posibility that a vbox has a depth that
%is unrecoverable on changing it to a vtop, e.g. if the last item in the
%vbox is a \mark. To rejoin boxes on a page accurately we need to preserve
\global%the depth of the box. We therefore *assume* the box will be joined and if
%the depth is not recoverable we add a kern to remove the orignial depth.
 \s@tbaseline{p}{p}%
 \trace{D}{makevtop #1, before vtop dp=\the\dp#1, ht=\the\ht#1}%
 \TempDim=\dp#1\relax%
 \ifdim\TempDim>\baselineskip \trace{D}{Looks like this is already a vtop}%
   %\TempDim=0pt
 \fi%
 \setbox0=\copy#1\setbox1=\vtop{\unvbox 0\setbox2=\lastbox}%Work on a copy so we don't break stuff.
 \trace{D}{pd:\the\dp2, ph=\the\ht2, d:\the\TempDim}%
 % Now ready to (A) remove topskip, later replacing it with baselineskip. (B) append kern if needed.
 \global\setbox#1=\vtop{\unvbox#1\ifdim\dp2=0pt \ifdim\TempDim=0pt \else\kern-\TempDim\fi\fi}
}
\let\lAd@do\relax
\let\log@ut\empty

\def\l@gdims#1{\the\ht#1 + \the\dp#1 x \the\wd#1}
\def\l@gboxdims#1{\edef\lb@tmpnam{\v@lpfx#1\v@lsfx}\x@\let\x@\lb@tmptb@x\csname\lb@tmpnam\endcsname \edef\log@ut{\log@ut\space \lb@tmpnam: \the\ht\lb@tmptb@x +\the\dp\lb@tmptb@x\space x \the\wd\lb@tmptb@x}}
% Log dimensions of all columns
\def\l@gm@dims{\relax\let\lAd@do=\col@do\let\col@do=\l@gboxdims
  \x@\each@col\diglot@list\E
  \let\col@do=\lAd@do
}

\let\@lApfx\relax
\let\@lAsfx\relax
\def\@l@gvals#1{\x@\let\x@\@l\csname \@lApfx #1\@lAsfx\endcsname \ifx\@l\relax \x@\xdef\csname \@lApfx#1\@lAsfx\endcsname{0pt}\edef\tmsg{\tmsg\space #1:undefined}\else\edef\tmsg{\tmsg\space#1: \the\dimexpr \@l\relax}\fi}
\def\l@gvals#1#2{\def\@lApfx{#1}\def\@lAsfx{#2}\let\col@do=\@l@gvals
    \x@\each@col\diglot@list\E
}
\def\joinboxes#1#2#3#4{%Join 2 vtops together and preserve baselineskip%
 \traceNum{d}{joinboxes #1(\l@gdims{#1}) #2(\l@gdims{#2}) called from locn #3, with penalty #4}%
 \ifnum\TRACEcount=\diglotDbgJoinboxes
   \showbox#1\showbox#2
 \fi\relax
 %How do these boxes join?
 \ifdim\ht#1>0pt
   \def\join@a{vbox}%
   \ifdim\ht#2=0pt
     \ifdim\dp#2>0pt
       \def\join@b{vtop}%
     \else
       \def\join@b{void}%
     \fi
    \else
       \def\join@b{vbox}%
    \fi
 \else
   \def\join@a{vtop}%
   \def\join@b{unknown}%
 \fi%
 %\bgroup
 %\ifnum#3=10\showbox#1\fi%
 \ifdim\ht#1=0pt \ifdim\dp#1=0pt \ifdim\wd#1=0pt \setbox0=\box#1\fi\fi\fi%make a 0 size box void
 \ifvoid#1%
   \trace{D}{#1 is void}%
 \else%
   \s@tbaseline{p}{p}%
   \ifdim\ht#1=0pt
     \unvbox#1
     %\showlists
     \dimen4=\lastkern%
     \dimen5=\dimen4
     \unkern
     \setbox0=\lastbox%
     \copy0
     \trace{D}{lk: \the\dimen4, final bit of deconstructed first box: \l@gdims{0}, 2nd box: \l@gdims{#2}}%
     \ifdim\dp0>0pt \ifdim\dimen4=0pt \ifdim\ht0>0pt
         \dimen4=-\dp0
     \fi\fi\fi
     \ifdim\dp0=0pt%
  %     \kern \lastkern
       \ifdim\ht0=0pt \ifdim\dimen4<0pt
          \dimen4=0pt
       \fi\fi
     \else
       \ifdim\dp0>\baselineskip
         \kern -\dp0
         %\else
         %\showbox0
       \fi%
     \fi
     \dimen5=0pt
   \else
     \dimen4=-\dp#1
     \unvbox#1
     \dimen5=\lastkern
     \ifnum\lastpenalty<-10000
       \unpenalty
     \fi
   \fi
   \dimen3=0pt
   %\dimen3=\baselineskip
   %\advance\dimen3 by -\topskip\relax
   \ifVisTrace
     \dimen6=1sp\tmpcount=0
   \fi
   \ifdim\dimen5<10sp \ifdim\dimen5>0sp
      \tmpcount=\dimen5
      \dimen6=\dimen5
      \advance\dimen6 by 1sp\relax
      \dimen4=-\dimen6 
      \dimen3=0pt
      \trace{D}{Re-breaking in the same place as before. Cancelling topskip removal. Indenting VisTrace label by \the\tmpcount}%
   \fi\fi
   \ifvoid#2
     \trace{D}{Box joint is \join@a-\join@b, no skip}%
   \else
     \ifdim\dimen3=0pt \else \kern \dimen3 \fi % Don't add a vskip needlessly, it might be a  break point.
     \trace{D}{Box joint is \join@a-\join@b (bls:\the\baselineskip, ts:\the\topskip -> \ifdim\dimen3=0pt noskip\else skip: \the\dimen3\fi)}%
   \fi
   \kern \dimen4 % kern away old depth.
   \ifVisTrace
     %\hrule\kern -0.4pt
     \hbox to 0pt{\hss\doVisTrace{j}\box0\kern\dimexpr -20pt * \tmpcount\relax}%
     \kern \dimen6
   \fi
 \fi%
 %
 \ifvoid#2\else
   %\ifnum #4=0 \else \penalty#4\fi %put the appropriate penalty back 
   \penalty#4 %put the appropriate penalty back 
   %\setbox0=\copy#2
   %\setbox1=\vsplit0 to \baselineskip
   %\trace{D}{Next box, h:\the\ht1, d:\the\dp1}%
   \unvbox#2 %
 \fi%
 \ifnum\diglotDbgJoinboxes=\TRACEcount
   \showlists
 \fi
}

\def\joinb@xes#1#2{%Called (ONLY) by pagebuilder. Join a vtop/vbox and a vbox/vbox together and preserve baselineskip%
 %\showbox#1\showbox#2%
 \bgroup
  \setbox0=\box#1
  \setbox1=\box#2
  \dimen0=0pt \relax
  \ifdim\ht0>0pt \ifdim\dp0<0.5\baselineskip
    %box0 is not a vtop, it's a vbox, so won't have text hanging below its baseline.
    \advance\dimen0 by -\baselineskip\relax % 
  \fi\fi
  \ifdim\ht1>0pt \ifdim\dp1<0.5\baselineskip
    %box1 is not a vtop, it's a vbox
    \ifdim\dimen0<0pt
      \dimen0=0pt
    \fi
    %I thought there ought to be a \baselineskip here. It doesn't seem to be needed.
    %\advance\dimen0 by \baselineskip
  \fi\fi
  \trace{D}{joinb@xes #1 #2, skip \the\dimen0}%
  \box0
  \ifdim\dimen0=0pt
  \else
    \vskip\dimen0
  \fi
  \box1
 \egroup}


\def\update@cumulative@delta#1{\bgroup
  \dimen0=\dimexpr \csname \v@lpfx#1\v@lsfx\endcsname - \dimen1\relax
  \dimen2=1pt
  \traceNum{dP}{Adding \the\dimen0 \space to cumulativeDelta#1}%
  \divide\dimen0 by \dimen2
  \count255=\dimen0
  \x@\global\x@\advance\x@\csname cumulativeDelta#1\endcsname by \count255\relax
  \egroup
}

\def\set@col@widths@simplecols{%
  \trace{d}{set@col@widths@simplecols}%
  \dimen0=\textwidth
  \def\col@do##1{\advance\count255 by 1}%
  \count255=0
  \x@\each@col\layout@list\E
  \edef\colc@unt{\the\count255}
  \advance\dimen0 by -\numexpr \colc@unt - 1\relax\gutter \relax\advance\dimen0 by -\count255\columnshift\relax
  \def\col@do##1{%
    \ifcsname  Diglot##1Fraction\endcsname
      \csname column##1width\endcsname=\csname Diglot##1Fraction\endcsname\dimen0
      \x@\ifdim \csname column##1width\endcsname<20pt \errmessage{Diglot##1Fraction (\csname Diglot##1Fraction\endcsname) gives \the\csname column##1width\endcsname, which is much too small}\fi
    \else
      \message{Diglot##1 fraction not supplied. assuming value of 1/\colc@unt}%
      \csname column##1width\endcsname=\dimen0 \x@\divide \csname column##1width\endcsname by \colc@unt
    \fi
    \traceNum{dP}{Setting column##1width to \the\csname column##1width\endcsname}}%
  \x@\each@col\layout@list\E
  %\columnLwidth=\DiglotLeftFraction\dimen0
  %\columnRwidth=\DiglotRightFraction\dimen0
}

\def\@do@jointcalc@simplecols#1{%
    % step 0 what maxbaselineskip applies?
    {\edef\tmsg{@cur}\empty\l@gvals{@cur}{ht}\ifcsname @nxtchunkLht\endcsname \edef\tmsg{\tmsg\space @nxtchunk}\l@gvals{@nxtchunk}{ht}\fi%
    \x@\def\x@\tmsg\x@{\tmsg}%
    \trace{dP}{do@joint@calc: \tmsg}
    }%
    \dimen1=0pt
    \def\v@lpfx{b@selineskip}\def\v@lsfx{}%
    \let\col@do=\max@val
    \x@\each@col\cts@list\E % Find biggest baseline skip of those bits of text WHICH ARE ACTIVE. I.e. yes it does need to be here.
    \edef\@maxb@seline{\the\dimen1}%
    % step 1: max height of the last box 
    \def\v@lpfx{#1}\def\v@lsfx{ht}%
    \dimen1=0pt
    \let\col@do=\max@val
    \x@\each@col\diglot@list\E % Find height of lastchunk
    \edef\@maxht{\the\dimen1}%
    \dimen1=0pt
    % step 2: position of the ideal next baseline (below last box)
    \let\col@do=\maxjoint@val
    \x@\each@col\cts@list\E
    \thisjointDelta=0pt %Do we need extra space?
    \ifdim\dimen1>0pt
      \thisjointDelta=\dimen1
      \advance\thisjointDelta by -\@maxht\relax
    %  \advance\thisjointDelta by -\topskip %remove topskip 
      \advance\thisjointDelta by -\@maxb@seline\relax
      \ifdim \thisjointDelta > \@maxb@seline  %sanity check
        \trace{d}{Unacceptable jointDelta (\the\thisjointDelta > \@maxb@seline) reduced to 0pt}%
        \thisjointDelta=0pt
      \fi
    \fi
    \trace{dP}{do@joint@calc(#1) : col:\m@x@at@col\space mh:\@maxht\space mb:\@maxb@seline\space mjv:\the\dimen1 \space jd:\the\thisjointDelta}%
}

\def\@prepare@layout@simplecols{%
    \bgroup
      \trace{d}{@prepare@layout@simplecols \l@gdims{\partial}}%
      % caclulate column deltas.
      \def\v@lpfx{}\def\v@lsfx{ht}\dimen1=0pt%
      \let\col@do\sum@val
      \x@\each@col\cts@list\E
      \divide \dimen1 by \curactivecols % dimen1 is now average of Lht, Rht, heights.
      \let\col@do\update@cumulative@delta % Add (Lht - dimen1) to cumulativeDeltaL
      \x@\each@col\cts@list\E
    \egroup
    %Calculate how much extra space we need:
    \csname @do@jointcalc@\diglotlayout\endcsname{@cur}%
    % Returns the ideal next baseline posltion below previous sync line.
    \trace{dP}{Join delta gives \the\dimen1 -\@maxht -\@maxb@seline = \the\thisjointDelta}%
    \global\chunkDelta=\Rht
    \global\advance\chunkDelta by -\Lht\relax
    \trace{dP}{new chunkDelta: \the\Rht - \the\Lht =  \the\chunkDelta}%
    %save Lht and Rht (as "nxtchunkXht) and reset Xht
    \let\col@do\save@reset@ht
    \x@\each@col\diglot@list\E
    \dimen8=0pt
    \ifdim\thisjointDelta>0pt
      \advance\dimen8 by \thisjointDelta\relax
    \fi
    \def\v@lpfx{}\def\v@lsfx{box}\let\col@do=\max@boxht\dimen1=0pt
    \x@\each@col\diglot@list\E
    \advance\dimen8 by \dimen1\relax
    \let\col@do=\max@boxdp\dimen1=0pt
    \x@\each@col\diglot@list\E
    \dimen9=\dimen1
    % apply columngutterruleskip?
    \diglot@pos@topfalse
    \ifdim\ht\partial=0pt \ifdim\dp\partial=0pt
      \advance\dimen8 by -\ColumnGutterRuleSkip\relax
      \ifdim\ColumnGutterRuleSkip < 0pt
       \ifColumnGutterRule
          \diglot@pos@toptrue
       \fi
      \fi
    \fi\fi
    \trace{d}{simplecols Gutter \the\dimen8 height, \the\dimen9 deep}%
    \dimen7=\dimen8
}

\def\@preswap@simplecols#1{}
\def\@postswap@simplecols#1{}

\def\SetDiglotBGColour#1#2#3{% #1= column, #2= R G B / xRRGGBB  #3 alpha
  \edef\tmp{#3}\ifx\tmp\empty \x@\global\x@\let\csname bg@#1@alpha\endcsname\undefined\else\x@\global\x@\let\csname bg@#1@alpha\endcsname\tmp\fi
  \edef\tmp{#2}\ifx\tmp\empty \x@\global\x@\let\csname bg@#1@col\endcsname\undefined\else
    \x@\checkh@x #2\end\x@\xdef\csname bg@#1@col\endcsname{\rgb@out}\fi
}
  
\def\@@simplecols#1{\hbox to\columnshift{}\ifx\l@stcol\empty\else\unhcopy1 \fi
    \trace{D}{@@simplecols #1}%
    \hbox to \csname column#1width\endcsname{\x@\copy\csname #1box\endcsname
      \hss}\xdef\l@stcol{#1}}
  %
\def\ck@backgrounds#1{%
  \ifcsname bg@#1@col\endcsname\iftemp\else
    \ifcsname bg@#1@alpha\endcsname
      \x@\let\x@\tmp\csname bg@#1@alpha\endcsname
      \ifdim \tmp pt =0pt \else
        \temptrue
      \fi
    \else
      \temptrue
    \fi
  \fi\fi
}
\def\DiglotColourPad{3pt} % How much padding to add for coloured background to diglot columns.

\def\ins@backgrounds#1{%
  \ifx\l@stcol\empty\else\hskip \gutter\fi
  \ifcsname bg@#1@col\endcsname
    {\if P\bg@fillht\dimen1=\ht\partial\relax \advance\dimen1 by \dp\partial\relax \advance \dimen1 0.5\csname onel@neunit\m@x@at@col\endcsname
        \ifdim\dimen1>\textheight \dimen1=\textheight\fi
      \else
        \if A\bg@fillht
          \dimen1=\availht
        \else
          \dimen1=\textheight
        \fi
      \fi
      \dimen2=\DiglotColourPad
      \trace{D}{Colour for #1 is \csname bg@#1@col\endcsname, \the\dimen1, \the\ht\partial, \the\dp\partial, \the\baselineskip}%
      \hbox to 0pt {\f@intthing{\ifcsname bg@#1@alpha\endcsname\csname bg@#1@alpha\endcsname\else 1\fi}{\csname bg@#1@col\endcsname}{\kern-\dimen2\vrule height \dimen1 depth 0pt width \dimexpr 2\dimen2+\csname column#1width\endcsname \relax}\hss}}%
  \else
    \trace{D}{No colour for #1}%
  \fi
  \hskip \csname column#1width\endcsname
  \xdef\l@stcol{#1}%
}

\def\@do@layout@simplecols{%
  \trace{d}{@do@layout@simplecols \l@gdims{\partial}}%
  \let\@d@lsimp@d@=\d@
  \let\@d@lsimpcol@do=\col@do
  \setbox1\hbox{\makediglotgutter{\dimen7}{\dimen8}{\dimen9}}%
  \let\l@stcol\empty
  \let\col@do=\@@simplecols
  % Skip calculations:
  \dimen6=0pt
  \ifdiglot@pos@top % Is this the top of the page? If so, (only) apply skip based on columngutterruleskip (set by @prepare@layout...
    \dimen6=\ColumnGutterRuleSkip
  \else
    \ifdim\thisjointDelta<0pt
      \ifdim\thisjointDelta>-\@maxb@seline %sanity check
        \dimen6=\thisjointDelta
        \trace{dP}{skipping jointDelta: \the\thisjointDelta}%
      \else
        \trace{dP}{Unacceptable negative jointDelta \the\thisjointDelta < -\@maxb@seline}%
      \fi
    \fi
  \fi
  % Normal
  %
  \global\setbox\n@xtpartialNrml\vtop{%
    \ifdim\dimen6=0pt \else
      \vskip\dimen6
    \fi
    \hbox to \textwidth{\ifVisTrace\llap{\copy0}\fi%
      \x@\each@col\layout@list\E
      \vrule height \dimen7 depth \dimen9 width 0pt
    }%
  }%
  \let\l@stcol\empty %Reset this so that @@simplecols behaves properly
  \global\setbox\n@xtpartialRev\vtop{%For the next page, thus no joint delta considerations
    \ifdim\dimen6=0pt \else
      \vskip\dimen6
    \fi
    \hbox to \textwidth{\ifVisTrace\llap{\box0}\fi%
      \x@\each@col\rev@layout@list\E
      \vrule height \dimen7 depth \dimen9 width 0pt
  }}%
  \let\col@do=\@d@lsimpcol@do
  \let\d@=\@d@lsimp@d@
}
\def\@do@cleanup@simplecols{%
  \def\v@lpfx{}\def\v@lsfx{box}%
  \let\col@do=\void@boxes %
  \x@\each@col\diglot@list\E
}

\def\diglot@arrange@cols{% Xht is the sum of Xbox's depth and height (set by after@a@trial
  \traceNum{d}{diglot@arrange@cols chnkDlta:\the\chunkDelta. cp:\the\chunkpenalty, lcp:\the\lastchunkpenalty}%
  \let\ac@d@=\d@
  \let\ac@col@do=\col@do
  \ifVisTrace
    \ifx\b@xtype\vbox %boxtype is set on discovery of whether this is a heading or not
      \doVisTraceT{\ifcsname m@x@at@col\endcsname\m@x@at@col\else L\fi}% sets box0, used @do@layout@... in lines below
    \else
      \doVisTrace{\ifcsname m@x@at@col\endcsname\m@x@at@col\else L\fi}% sets box0, used  @do@layout@... lines below
    \fi
  \fi
  \ifnum \curactivecols>0
    \csname @prepare@layout@\diglotlayout\endcsname
    \csname @setup@layout@\diglotlayout\endcsname
    \csname @do@layout@\diglotlayout\endcsname
    \csname @do@cleanup@\diglotlayout\endcsname
    \ifnum\chunkpenalty>-20000
      \global\lastchunkpenalty=\chunkpenalty
    \else
      \global\lastchunkpenalty=0
    \fi
    \global\chunkpenalty=-20000 %Everything ought to be bigger than this.
 \else
    \traceNum{d}{No content to output}%
  \fi
}

\def\pickn@xtpartial{\trace{D}{pickn@xtpartial \ifdiglotN@rmal Normal\else Reversed\fi}\ifdiglotN@rmal\global\let\n@xtpartial=\n@xtpartialNrml\else\global\let\n@xtpartial=\n@xtpartialRev\fi} % decide which n@xtpartial box to use

\def\voidn@xtpartial{\global\setbox\n@xtpartialRev\box\voidb@x\global\setbox\n@xtpartialNrml\box\voidb@x}% Void the other n@xtpartial box

\def\setdiglotN@rmal{\ifnum \numexpr 1 \ifdiglotInnerOuter \ifodd\pageno\else * -1 \fi\fi \ifdiglotSwap * -1\fi\relax >0 
  \diglotN@rmaltrue \else \diglotN@rmalfalse \fi
}

\def\s@tctslist@simplecols{%
  \curactivecols=0 
  \def\v@lpfx{}\def\v@lsfx{ht}%
  \let\cts@list=\empty
  \x@\let\x@\col@do\csname count@dim@\diglotlayout\endcsname
  \x@\each@col\diglot@list\E
}

%write column start and stop information
\def\@@simple@colstart#1#2{%
    \x@\xdef\csname dc@ref@rgs#2\endcsname{\string\@Poly@colstart{\the\ht#1}{\the\dp#1}{\the\wd#1}}%
    \pdfsavepos
    \x@\write\x@\p@rlocs\x@{\csname dc@ref@rgs#2\endcsname{\the\pdflastxpos}{\the\pdflastypos}{#2}}%
}
\xdef\dc@ref@rgse{\string\@Poly@colstop}%
\def\@@simple@colstop#1{%
    \pdfsavepos
    \write\p@rlocs{\dc@ref@rgse{\the\pdflastxpos}{\the\pdflastypos}{#1}}%
}

\def\@Poly@colstart#1#2#3#4#5#6{\edef\c@rrdstat{#6}\relax
  \x@\let\x@\p@rlinesgone\csname p@rlinesgone-\c@rrdstat\endcsname
  \@@colstart{#1}{#2}{#3}{#4}{#5}%
}
\def\@Poly@colstop#1#2#3{\edef\c@rrdstat{#3}\relax\@@colstop{#1}{#2}}

\def\@prepare@upd@tep@rtial@simplecols{%
  \trace{dP}{columns with contents: \cts@list (\the\curactivecols)}%
  \ifnum\curactivecols>0 
    \temptrue
    \let\col@do=\chk@head %is the relevant item a heading? set tempfalse if not
    \x@\each@col\cts@list\E
    \let\b@xtype\vtop %just used as a flag.
    \iftemp
      \let\b@xtype\vbox
      \trace{D}{Un vtopping headings}%
      \def\col@do##1{\x@\setbox\csname ##1box\endcsname\vbox{\@@simple@colstart{\csname ##1box\endcsname}{##1}\unvbox\csname ##1box\endcsname\@@simple@colstop{##1}}}%
      \x@\each@col\cts@list\E
    \else
      \trace{D}{marking column start and stop}%
      \def\col@do##1{\x@\setbox\csname ##1box\endcsname\vtop{\@@simple@colstart{\csname ##1box\endcsname}{##1}\unvbox\csname ##1box\endcsname\@@simple@colstop{##1}}}%
      \x@\each@col\cts@list\E
    \fi
  \fi
  %\showboxdepth=3 %
  %\showboxbreadth=1000 %
  %\ifnum\pageno=1%
  %\showbox\Lbox%
  %\showbox\Rbox%
  %\fi%
  \edef\t@st{\p@gebotmark}%
  \ifx\t@st\empty%
    \ifuseLeftMarks \let\b@xbotmark\botLmark\fi
    \ifuseRightMarks \let\b@xbotmark\botRmark\fi
    \trace{H}{updp1: Setting p@gebotmark to \b@xbotmark, since it's empty }%
    \xdef\p@gebotmark{\b@xbotmark}%
  \fi%
}


\def\restore@trace@updatepartial{}
\def\upd@tep@rtial{%routine called to add stuff to the partial page.
  \traceNum{d}{upd@tep@rtial \the\outputpenalty (\diglotDbgupdtPtl)}%
  \trace{D}{plp:\the\partialLpenalty, prp:\the\partialRpenalty, cp:\the\chunkpenalty lcp:\the\lastchunkpenalty, lbp:\the\Lboxpenalty, rbp:\the\Rboxpenalty. pf:\ifpagefull true\else false\fi}%
  \ifnum\diglotDbgupdtPtl=\TRACEcount
    \xdef\restore@trace@updatepartial{\global\tracingmacros=\the\tracingmacros \global\tracingassigns=\the\tracingassigns}%
    \global\tracingmacros=1\global\tracingassigns=1  % Conditional on diglotDbgupdtPtl=\TRACEcount
  \else 
    \restore@trace@updatepartial
  \fi
  \csname @start@upd@tep@rtial@\diglotlayout\endcsname % Any setup?
  \csname s@tctslist@\diglotlayout\endcsname % increments curactivecols by each non- value, and sets \cts@list
  \setdiglotN@rmal % Left=left (normal) or not?
  \pickn@xtpartial
  \csname @prepare@upd@tep@rtial@\diglotlayout\endcsname % Sort out headings, etc.
  %
  % Add the contents
  %
  \global\def\n@xtc@mmand{}%
  \message{|}%
  \hsize=\textwidth%
  \trace{d}{Adding old n@xtpartial(\the\ht\n@xtpartial+\the\dp\n@xtpartial) to page}%
  \@add@n@xtpartial
  %
  % Save mark state, note state, etc.
  %
  \let\col@do=\store@marks
  \x@\each@col\diglot@list\E %remember old marks state
  \s@veallnotes{2}% remember old notestate 
  \s@veinserts{chunk}%
  %
  % Save current column contents as n@xtp@rtial
  %
  \IfTr@ce{d}{%
    \let\log@ut\empty\def\v@lpfx{}\def\v@lsfx{box}%
    \l@gm@dims
    \traceNum{d}{Arranging new n@xtpartial: \log@ut. p@gechunkDelta:\the\p@geChunkDelta}%\space Tot:\the\cumulativeDelta%
  }%
  \diglot@arrange@cols
  \TempDim=\dimexpr \ht\n@xtpartial + \dp\n@xtpartial\relax
  \loc@lhtfalse\dglt@calc@vailht
  \edef\v@lpfx{BelowBaseline}\let\v@lsfx\empty
  \dimen1=0pt \let\col@do\max@bbl
  %\tracingassigns=1
  \x@\each@col\diglot@list\E% 
  \advance\availht by -\dimen1
  %\tracingassigns=0
  \ifdim\availht<\@maxb@seline %
    \global\pagefulltrue%
    \trace{D}{Declaring page full}%
  \else%
    \trace{D}{Page not full actually (\the\availht\space left, bls=\the\baselineskip, mbls=\@maxb@seline, mbbl=\the\dimen1) pagefull\ifpagefull true\else false\fi\space endbook\ifendbook true\else false\fi}%
    \ifpagefull\ifendbook\ifendbooknoeject
      \trace{d}{some space and end of a book, cancelling pagefull}%
      \global\pagefullfalse
    \fi\fi\fi
  \fi%
  \ifdim\TempDim>0.1pt
    \global\deadcycles=0 %Reset deadcycles only if there's actual matter being added.
    \global\trialheight=\availht\relax%
    \global\vsize=\trialheight\relax%
  \fi
  \ifpagefull%
    \trace{D}{Page full}%
    \@add@n@xtpartial
    \@writep@ge%
      \let\col@do=\reset@n@xt
      \x@\each@col\diglot@list\E% 
    \global\deadcycles=0 %That counts as an action too.
    \tempfalse
    \let\col@do\check@pen
    \x@\each@col\diglot@list\E% 
    \iftemp
      \trace{d}{pagebreak: not (normally) resetting pagefull. lastpage\iflastpage true\else false\fi, endbook\ifendbook true\else false\fi}%
      \global\pagefulltrue
    \else \global\pagefullfalse\fi
  \else
    %\message{-}%
  \fi%
  \csname end@upd@tep@rtial@\diglotlayout\endcsname % any cleanup?
}


\newif\ifLRf@@tnotes%
\newif\ifNoteGutterRule \NoteGutterRuletrue
\newif\ifFigGutterRule \FigGutterRulefalse
\newif\ifJoinGutterRule \JoinGutterRulefalse
\newcount\MaxPages
\edef\MaxPagesPerChunk{300}
\MaxPages=\MaxPagesPerChunk

\newbox\topchunk
\newbox\botchunk
\newbox\notechunk

\def\try@print@unprintable#1\E{%
  \trace{u}{try@print@unprintable #1}%
  \IfTr@ce{u}{\tracingassigns=1 }% \tracingmacros=1%
  \x@\let\x@\s@mebox\csname #1\endcsname
  \ifx\pagecontents\empty\else
    \ifdim\dimexpr \ht\s@mebox+\dp\s@mebox + \dimen0 > \textheight
      \trace{u}{Printing}%
      \plainoutput
      \let\pagecontents\empty
      \tmpt@ks{}%
      \dimen0=0pt
    \fi
  \fi
  \ifvoid\s@mebox\else
    \advance\dimen0 by \ht\s@mebox\relax
    \advance\dimen0 by \dp\s@mebox\relax
    \ifx\pagecontents\empty
      \def\pagecontents{\ifdiglot
        \setdiglotN@rmal\pickn@xtpartial
        \fi\the\tmpt@ks}%
    \fi
    \x@\tmpt@ks\x@{\the\tmpt@ks\box\csname#1\endcsname}%
    \relax
  \fi
}
\def\DEBUGnotes{0} % Page to show the footnote box on.
\def\diglot@fill@sep@note@box#1{%
  \edef\s@vedbaseline{\the\baselineskip}\edef\s@vedlineskiplimit{\the\lineskiplimit}\let\s@veddstat=\c@rrdstat
  \setc@rdstat{#1}%
  \lineskiplimit=0pt%
  \setLRspecific
  \f@rstnotetrue
  \lastd@pth=0pt
  \global\setbox\csname #1box\endcsname=\vbox{%
     \x@\the\csname diglot#1ho@ks\endcsname
     \let\\=\ins@rtn@tecl@ss \the\n@tecl@sses}%
  \iff@rstnote
      \trace{f}{No footnotes for #1}%
  \else\LRf@@tnotestrue
    \trace{Df}{Notes for #1 \x@\the\x@\ht\csname #1box\endcsname, bls=\the\baselineskip, lsl=\the\lineskiplimit}%
    %\x@\ifdim\x@\ht\csname #1box\endcsname<\AboveNoteSpace
      %\x@\ifdim\x@\ht\csname #1box\endcsname>0pt
        %\x@\showbox\csname #1box\endcsname
      %\fi
    %\fi
  \fi
  \ifnum\DEBUGnotes=\the\pageno \showbox\csname #1box\endcsname \fi
  \setc@rdstat{\s@veddstat}\baselineskip=\s@vedbaseline\relax
  \lineskiplimit=\s@vedlineskiplimit\relax
}

\def\@setup@layout@simplecols{%
  \let\layout@list=\diglot@list % default
  \let\col@do=\mkrev@list
  \xdef\rev@layout@list{}\def\list@type{layout}%
  \x@\each@col\layout@list\E% 
}

\def\@prepare@balnotes@simplecols{%
  \dimen1=0pt
  \let\col@do=\max@boxht\def\v@lpfx{}\def\v@lsfx{box}%
  \x@\each@col\diglot@list\E% 
  \let\col@do=\reb@xht
  \x@\each@col\diglot@list\E% 
  \dimen7=\dimen1
  \dimen1=0pt
  \let\col@do=\max@boxdp
  \x@\each@col\diglot@list\E% 
  \dimen9=\dimen1
  \trace{d}{@prepare@balnotes@simplecols: Gutter \the\dimen8 high, \the\dimen9 deep}%
  \ifJoinGutterRule\else\advance\dimen7 by -\AboveNoteSpace\fi
  \dimen8=\dimen7
}

\def\@do@balnotes@simplecols{%
  \setbox1\hbox{\ifNoteGutterRule\makediglotgutter{\dimen7}{\dimen8}{\dimen9}\else\hskip\gutter\fi}%
  \let\col@do=\@@simplecols\let\l@stcol\empty
  \setbox0=\hbox to \textwidth{%\vllap{\the\ht\Lbox \the\dp\Lbox}%
  \hbox to\columnshift{}%
  \ifdiglotN@rmal%are the sides swapped?
    \x@\each@col\layout@list\E
  \else
    \x@\each@col\rev@layout@list\E
  \fi
  }%
  \global\setbox\partial=\vbox{\unvbox\partial\box0}%
}

\def\@prepare@unbalnotes@simplecols{%
  %Implement meshing algorithm:
  \trace{Df}{Saving fn dimensions}%
  \edef\v@lpfx{@fn}\let\col@do=\save@boxdim %Save footnote @fnXht @fnXdp values
  \x@\each@col\diglot@list\E
  \edef\v@lsfx{ht}%
  \trace{Df}{Finding max \v@lpfx X\v@lsfx}%
  \let\col@do=\max@val\dimen1=0pt
  \x@\each@col\diglot@list\E
  \trace{Df}{=\the\dimen1}%
  \dimen2=\dimen1 %dimen2=note height 
  \dimen8=\dimen1 %dimen8=note height (needed for rule)
  \edef\v@lpfx{@cur}\dimen1=0pt
  \trace{Df}{Finding max \v@lpfx X\v@lsfx}%
  \x@\each@col\diglot@list\E
  \trace{Df}{=\the\dimen1}%
  \advance\dimen2 by \dimen1\relax%dimen2 now contains total natural height of text from last true synch-point and notes.
  \edef\v@lpfxb{@fn}\dimen1=\dimen2
  \trace{Df}{Finding min note sep \v@lpfxb Xht}%
  \let\col@do=\min@note@sep% subtracts \v@lpfxb Xht and \v@lpfx Xht from dimen2, returning the smalles value in dimen1
  \x@\each@col\diglot@list\E
  \trace{Df}{=\the\dimen1}%
  \dimen3=\dimen1
  %rule calcs: is #1 (dimen7) high, #3(dimen9) deep, and fits in a box #2(dimen8 - found earlier)high
  \edef\v@lpfx{@fn}%
  \edef\v@lsfx{dp}\let\col@do=\max@val\dimen1=0pt
  \trace{Df}{Finding max \v@lpfx X\v@lsfx}%
  \x@\each@col\diglot@list\E
  \trace{Df}{=\the\dimen1}%
  \dimen9=\dimen1
  \ifJoinGutterRule\else
    \advance\dimen7 by -\AboveNoteSpace\relax %stop the line a little short
  \fi
  \dimen8=\dimen7
  \trace{d}{ANS: \the\AboveNoteSpace. Gutter \the\dimen7 tall, \the\dimen9 deep}%
}

\def\@do@unbalnotes@simplecols{%
  \traceNum{d}{@do@unbalnotes@simplecols \layout@list}%
  \setbox1\hbox{\ifNoteGutterRule\makediglotgutter{\dimen7}{\dimen8}{\dimen9}\else\hskip\gutter\fi}%
  \let\col@do=\@@simplecols\let\l@stcol\empty
   \setbox\notechunk\hbox to \textwidth{%\vllap{\the\ht\Lbox \the\dp\Lbox}%
    \ifdiglotN@rmal%are the sides swapped?
      \x@\each@col\layout@list\E
    \else%
      \x@\each@col\rev@layout@list\E
    \fi%
  }%
  \trace{f}{Adjusting footnotebox}%
  \advance\dimen3 by \dimen9
  \trace{D}{Raising footnotebox by \the\dimen3 \space note:\l@gdims{\notechunk}, partial:\l@gdims{\partial}}%
  \global\setbox\partial=\vbox{\unvbox\partial\kern -\dimen3\vskip 0.5\AboveNoteSpace plus 1fil \box\notechunk}%
}%

\def\@writep@ge{%
  \trace{d}{@writep@ge \the\pageno (\the\MaxPages)}%
  \ifnum\pageno>\MaxPages
    \errmessage{Pagecount (\the\pageno) has exceeded \MaxPages (\the\MaxPages). This probably means something has gone wrong. (or you should increase MaxPages or MaxPagesPerChunk (\the\MaxPagesPerChunk) for this job)}%
  \fi
  \csname @start@writep@ge@\diglotlayout\endcsname
  \setdiglotN@rmal
  \pickn@xtpartial
  \actually@writetrue
  \csname @prep@writep@ge@\diglotlayout\endcsname
  \csname @do@writep@ge@\diglotlayout\endcsname
  \csname @end@writep@ge@\diglotlayout\endcsname
}

\def\@prep@writep@ge@simplecols{
  \ifdiglotSepNotes%
    \trace{D}{Sep notes}%
    \LRf@@tnotesfalse%
    %Arrange Left and Right footnotes
    \let\col@do=\diglot@fill@sep@note@box
    \x@\each@col\diglot@list\E% 
    \setLRspecific % c@rrdstat is restored by diglot@fill@sep@note@box.
    \ifLRf@@tnotes%
      \ifdiglotBalNotes%
      \trace{f}{Balanced notes}%
        % \kern\lastd@pth % This, if at all valid for anything, is from the last note.
        \trace{f}{Footnotes}%
        \csname @prepare@balnotes@\diglotlayout\endcsname
        \csname @do@balnotes@\diglotlayout\endcsname
      \else %BalNotes
        \trace{f}{unBalanced notes}%
        %curLht and curRht hold the height of the last boxes that joined the
        %page,
        %Need to find out where to put the footnotes, as one of them should
        %be close to its respective text.
        %\tracingmacros=1
          \csname @prepare@unbalnotes@\diglotlayout\endcsname
          \csname @do@unbalnotes@\diglotlayout\endcsname
        %\tracingmacros=0
      \fi %BalNotes
    \else%
      \trace{f}{No footnotes}%
    \fi %LRf@@tnotes
  \else %SepNotes
    \trace{f}{Merged notes}%
  \fi%
}

\newif\ifactually@write
\def\@do@writep@ge@simplecols{
  \trace{d}{do@writep@ge@simplecols \the\pageno (\the\MaxPages) actually@write\ifactually@write true\else false\fi}%
  \IfTr@ce{gI}{%
    \let\d@=\sh@winsertdim\edef\v@lpfx{}\edef\v@lsfx{}\x@\cstackdown\ins@rts\E
  }%
  \global\setbox\partial=\vbox{\unvbox\partial}%
    \traceNum{d}{Forming page}%
  \trace{D}{PFM:\p@gefirstmark\space PBM:\p@gebotmark}%
  \ifnum\TRACEcount=\diglotDbgJoinboxes
    \showbox\partial
    \showthe\everyhbox
    \showthe\leftskip
    \showthe\rightskip
  \fi
  \p@gestarttrue
  \setc@rdstat{L}%%
  \setLRspecific
%
  \ifdim\ht\topleftins>\ht\toprightins%
    \setbox\toprightins=\vbox to \ht\topleftins{\box\toprightins\vss}%
  \else%
    \setbox\topleftins=\vbox to \ht\toprightins{\box\topleftins\vss}%
  \fi%
  \dimen8=\ht\topleftins % heights have been forced to be the same, no check
  \dimen9=\dp\topleftins
  \ifdim \dimen9 <\dp\toprightins \dimen9=\dp\toprightins \fi
  \trace{d}{Top fig Gutter \the\dimen8 hight, \the\dimen9 deep}%
  \dimen7=\dimen9
  \advance\dimen7 by \dimen8\relax
  \setbox\topchunk=\hbox to \textwidth{%\vllap{\the\ht\Lbox \the\dp\Lbox}%
    \hbox to\columnshift{}%
    \ifdiglotN@rmal%Are the sides swapped?
      \hbox to\columnLwidth{\box\topleftins\hss}\ifFigGutterRule\makediglotgutter{\dimen8}{\dimen8}{\dimen9}\else\hskip\gutter\fi %
      \hbox to\columnshift{}%
      \hbox to\columnRwidth{\box\toprightins\hss}%\rlap{\the\ht\Rbox \the\dp\Rbox}%
    \else%
      \hbox to\columnRwidth{\box\toprightins\hss}\ifFigGutterRule\makediglotgutter{\dimen8}{\dimen8}{\dimen9}\else\hskip\gutter\fi %
      \hbox to\columnshift{}%
      \hbox to\columnLwidth{\box\topleftins\hss}%\rlap{\the\ht\Rbox \the\dp\Rbox}%
    \fi%
  }%
%
  \ifdim\ht\bottomleftins>\ht\bottomrightins%
    \setbox\bottomrightins=\vbox to \ht\bottomleftins{\box\bottomrightins\vss}%
  \else%
    \setbox\bottomleftins=\vbox to \ht\bottomrightins{\box\bottomleftins\vss}%
  \fi%
  \dimen8=\ht\bottomleftins
  \ifdim \dimen8 <\ht\bottomrightins \dimen8=\ht\bottomrightins \fi
  \dimen9=\dp\bottomleftins
  \ifdim \dimen9 <\dp\bottomrightins \dimen9=\dp\bottomrightins \fi
  \trace{d}{Bottom Fig Gutter \the\dimen8 hight, \the\dimen9 deep}%
  \dimen7=\dimen9
  \advance\dimen7 by \dimen8\relax
  \ifnum 0> \numexpr  \ifvoid\bottomleftins 0 \else 1 \fi + \ifvoid\bottomrightins 0 \else 1 \fi\relax
    \setbox\botchunk=\hbox to \textwidth{%\vllap{\the\ht\Lbox \the\dp\Lbox}%
      \hbox to\columnshift{}%
      \ifdiglotN@rmal%Are the sides swapped?
        \hbox to\columnLwidth{\box\bottomleftins\hss}\ifFigGutterRule\makediglotgutter{\dimen8}{\dimen8}{\dimen9}\else\hskip\gutter\fi %
        \hbox to\columnshift{}%
        \hbox to\columnRwidth{\box\bottomrightins\hss}%\rlap{\the\ht\Rbox \the\dp\Rbox}%
      \else%
        \hbox to\columnRwidth{\box\bottomrightins\hss}\ifFigGutterRule\makediglotgutter{\dimen8}{\dimen8}{\dimen9}\else\hskip\gutter\fi %
        \hbox to\columnshift{}%
        \hbox to\columnLwidth{\box\bottomleftins\hss}%\rlap{\the\ht\Rbox \the\dp\Rbox}%
      \fi%
    }%
  \else
    \setbox\botchunk\box\voidb@x
  \fi
  \ifdiglotSepNotes%
  \else%
     % RTLness will have been asserted (or not) when the note was defined.
     \setbox\notechunk\vbox{%
       \ifdiglot\RTLfalse\fi
       \def\c@rrdstat{L}%
       \traceNum{d}{Inserting Notes}%
       \f@rstnotetrue%
       \m@kenotebox
       \unvbox2 % defined by m@kenotebox
     }%
  \fi%
%
  \ifunprintable 
    \abortpage
  \else
    \def\pagecontents{%
     \setdiglotN@rmal
     \pickn@xtpartial
     \availht=\textheight
     \ifvoid\topins\else
         \trace{i}{Using topins \the\ht\topins x\the\wd\topins}%
        \advance\availht-\ht\topins \advance\availht-\skip\topins
         \unvbox\topins \vskip\skip\topins \fi%
    %
     \advance\availht-\ht\topchunk\advance\availht-\ht\botchunk
     \ifvoid\bottomins\else % \kern-\dimen0
        \advance\availht-\ht\bottomins \advance\availht-\skip\bottomins
     \fi
     \ifvoid\verybottomins\else % \kern-\dimen0
        \advance\availht-\ht\verybottomins \advance\availht-\skip\verybottomins
     \fi
     %\advance\availht\dp\topchunk\advance\availht\dp\botchunk
     \ifdim\dp\partial<\baselineskip
        \advance\availht\dp\partial
     \fi
     \box\topchunk % Top left/right insert
     \lastd@pth=\dp\partial\relax%
     \tempfalse\let\col@do\ck@backgrounds
     \x@\each@col\diglot@list\E% 
     %\tracingassigns=1
     %\tracingcommands=3
     %\tracingifs=1
     \iftemp
       \trace{d}{Applying colour backgrounds (\ifdiglotN@rmal normal:\layout@list \else reverse:\rev@layout@list\fi)}%
       \ifdiglotSepNotes
         \iftextborder
           \def\bg@fillht{P}% Fill to textheight
         \else
           \def\bg@fillht{A}% Fill to availht
         \fi
       \else
         \def\bg@fillht{P}%
       \fi
       \ifinendbook\def\bg@fillht{P}\fi
       \let\col@do\ins@backgrounds
       \x@\let\x@\tmplist\ifdiglotN@rmal\layout@list \else \rev@layout@list\fi
       \vbox to 0pt{\let\l@stcol\empty%
         \iftextborder\ifdefined\textb@dr@top@pad\vskip\textb@dr@top@pad\fi\fi
         \hbox{\x@\each@col\tmplist\E}%
         \vss}%
     \fi
     \trace{et}{Apply border from writesimplecolumns}%
     \doTextB@rder{\partial}%
     \global\partialfr@medtrue
     \unvbox\partial%
     %\tracingifs=0
     %\tracingcommands=0
     %\tracingassigns=0
     \ifvoid\botchunk\else\box\botchunk\fi
     \ifvoid\bottomins\else%\kern-\lastd@pth \dimen0=0pt 
       \trace{i}{Using bottomins \the\ht\bottomins x\the\wd\bottomins}%
       \vskip\skip\bottomins \unvbox\bottomins \fi%
     \ifdiglotSepNotes%
     \else%
       % RTLness will have been asserted (or not) when the note was defined.
       \ifactually@write\else \vfill\fi
       \iftrue
        \box\notechunk
       \else
         \ifvoid\notechunk\else\box\notechunk\fi
       \fi
     \fi%
     \ifvoid\verybottomins\else % \kern-\dimen0
       \trace{i}{Using verybottomins \the\ht\verybottomins x\the\wd\verybottomins}%
       \lastd@pth=0pt \vskip\skip\verybottomins \hbox{\hbox to \columnshift{}\vbox{\unvbox\verybottomins}}\fi
     }%pagecontents
   \holdinginserts=1
   \trace{D}{PFM:\p@gefirstmark\space PBM:\p@gebotmark\space NPFM:\nextp@gefirstmark}%
   \global\adjustp@ge=0pt
   \ifactually@write \plainoutput\fi%
  \fi
}
\def\abortpage{
    \edef\b@xseq{topins,topchunk,partial,botchunk,bottomins,notechunk,verybottomins,}%
    \dimen0=0pt
    \tmpt@ks{}%
    \let\pagecontents\empty
    \let\d@=\try@print@unprintable
    \x@\cstackdown\b@xseq\E
    \ifx\pagecontents\empty\else
      \trace{u}{Printing final part of page}%
      \plainoutput%
    \fi
    \let\pagecontents\empty
    \global\unprintablefalse
} 
\def\@end@writep@ge@simplecols{%
  \trace{d}{end@writep@ge: resetting things for next page}%
  \resetvsize%
  \global\vsize=\availht
  \global\availhtR=\textheight%
  \global\availhtL=\textheight%
  \global\availht=\textheight%
  \global\chunkDelta=0pt
  \global\pagefullfalse%
  \p@gestartfalse
  \xdef\p@gefirstmark{\nextp@gefirstmark}%
  \xdef\p@gebotmark{}%
  \xdef\nextp@gefirstmark{}%
  \let\col@do=\reset@marks
  \x@\each@col\diglot@list\E% 
  \def\v@lpfx{@cur}%
  \let\col@do=\forget@boxdim
  \x@\each@col\diglot@list\E
  \def\v@lpfx{}\def\v@lsfx{box}%
  \let\col@do=\void@boxes %
  \x@\each@col\diglot@list\E
  \resetc@rdstat%reset the current diglotstatus
  \xdef\firstLmark{}%
  \xdef\botLmark{}%
  \xdef\firstRmark{}%
  \xdef\botRmark{}%
  \@mptyinserts
  \s@veinserts{chunk}%
  \s@veinserts{col}%
  \s@veallnotes{1}%
  \s@veallnotes{2}%
  \resetc@rdstat%reset the current diglotstatus
  \nextshipout
  \trace{oh}{pagehook for page-\the\pageno \ifcsname page-\the\pageno\endcsname exists\else missing\fi}%
  \ifcsname page-\the\pageno\endcsname
    \csname page-\the\pageno\endcsname
  \fi
  %\nonstopmode
  %\showthe\output
  %%somejunk
}

\def\diglotCollect{%
  %This gets called to collect material into the appropriate input queue.
  % assumes: \availht is correct, 
  % Fills: \excessX and \wholeX
  % Empties: \box255
  \traceNum{D}{diglotCollect \c@rrdstat O:\the\outputpenalty, P:\the\savedpenalty, vs:\the\vsize. \ifintrial IN trial\fi}%
  %\ifintrial\showlists\fi
  \ifnum\diglotDbgJoinboxes=\TRACEcount\showbox255\fi
  \x@\let\x@\destb@x\csname excess\c@rrdstat\endcsname
  \ifx\destb@x\relax
    \errmessage{! ERROR! Improper state; '\c@rrdstat' should be 'L' 'R' or some other defined column. Maybe there was output before columns were set up?}%
  \fi
  \ifnum\outputpenalty=-10000 %User-pagebreak
    \x@\global\csname partial\c@rrdstat penalty\endcsname=\outputpenalty% Borrow partialXpenalty
  \fi
  \diglot@any@primary
  \ifnum\outputpenalty=\dgl@tPenLtrialEnd\relax 
    \trace{D}{Why are we in diglotCollect after a trial?}%
  \fi
  % tempoarily split and see if there are marks in this text
  \bgroup
    \setbox0=\copy255 \setbox1=\vsplit0 to \maxdimen
    %\setbox1=\vbox{\unvbox1}%l
    %\trace{D}{ht1:\the\ht1  dp0:\the\dp1}%
  \egroup
  \edef\t@mp{\splitbotmark}%
  \ifx\t@mp\empty\else
    \trace{H}{Found mark \splitbotmark}
    %\ifm@rksonpage\else \fi
    \global\m@rksonpagetrue
%
  \fi
  \makevtop{255}%
  \ifnum\diglotDbgJoinboxes=\TRACEcount\showbox255\fi
  \trace{D}{dp:\the\dp255}%
  \tmpcount=\outputpenalty %
  \ifnum\outputpenalty=10000 % Nothing wrong with breaking here
    \tmpcount=0\relax%
  \fi
  \ifvoid\destb@x
    \global\setbox\destb@x=\vbox{\vskip\baselineDelta\penalty10000\unvbox255}%
    %\global\setbox\destb@x=\vbox{\unvbox255}%
  \else 
    \setbox255=\vbox{\x@\vskip\csname baselineDelta\c@rrdstat\endcsname\penalty10000\unvbox255}%
    \global\setbox\destb@x=\vtop{\joinboxes{\destb@x}{255}{1}{\x@\the\csname partial\c@rrdstat penalty\endcsname}}%
  \fi
  \global\setbox\csname whole\c@rrdstat\endcsname\copy\destb@x % Save the current input box to avoid need to re-attach things to excessX
  \ifnum\tmpcount<-10000 \ifnum\tmpcount>\numexpr \sp@cialpen -1\relax 
    \tmpcount=0
  \fi\fi
  \global\x@\csname partial\c@rrdstat penalty\endcsname=\tmpcount
  \ifnum\outputpenalty=\dgl@tPenColSwap\relax %Got to the end of the \lefttext
    \trace{D}{Reached end of diglotCollect. \ifallNeedEmptying Running trials soon\fi\ifintrial IN trial??\fi}%
    \ifallNeedEmptying
      \global\let\n@xtc@mmand=\diglot@run@trials
      \global\allNeedEmptyingfalse
    \fi
  \fi
  \resetc@rdstat
}


% for 'Mark' activity around n@xtpartial and aborted trials.
\def\reset@marks#1{% Called at page output
  \trace{H}{Resetting first#1mark and friends}%
  \x@\xdef\csname first#1mark\endcsname{}%
  \x@\xdef\csname oldbot#1mark\endcsname{\csname bot#1mark\endcsname}%
  \x@\xdef\csname bot#1mark\endcsname{}%
}
\def\reset@n@xt#1{% Called at page output
  \trace{H}{Resetting n@xtfirst#1mark}%
  \x@\xdef\csname n@xtfirst#1mark\endcsname{}%
}
\def\store@marks#1{%Save the current mark state
  \trace{H}{Storing pre@ptl ...#1 marks}%
  \x@\xdef\csname pre@ptlfirst#1mark\endcsname{\csname first#1mark\endcsname}%
  \x@\xdef\csname pre@ptlbot#1mark\endcsname{\csname bot#1mark\endcsname}%
}

\def\sw@p@marks#1#2{%
  \edef\tmpmark{\csname pre@ptl#1#2mark\endcsname}%
  \x@\xdef\csname pre@ptl#1#2mark\endcsname{\csname old#1#2mark\endcsname}%
  \x@\xdef\csname old#1#2mark\endcsname{\tmpmark}%
}

\def\swap@marks#1{%Swap the two saved states 
  \trace{H}{Swapping pre@ptl ... and old marks}%
  \sw@p@marks{first}{#1}%
  \sw@p@marks{bot}{#1}%
}

%\def\restore@botmark#1{%
  %\x@\xdef\csname bot#1mark\endcsname{\csname pre@ptlbot#1mark\endcsname}%
%} 

\def\restore@oldmarks#1{%Restore saved mark state
  \trace{H}{restoring old marks (#1)}%
  \x@\xdef\csname first#1mark\endcsname{\csname oldfirst#1mark\endcsname}%
  \x@\xdef\csname bot#1mark\endcsname{\csname oldbot#1mark\endcsname}%
}
\def\restore@storedmarks#1{%Restore saved mark state
  \trace{H}{restoring stored marks first:\csname pre@ptlfirst#1mark\endcsname\space bot:\csname pre@ptlbot#1mark\endcsname}%
  \x@\xdef\csname first#1mark\endcsname{\csname pre@ptlfirst#1mark\endcsname}%
  \x@\xdef\csname bot#1mark\endcsname{\csname pre@ptlbot#1mark\endcsname}%
}

\def\reflow@trial#1{%Restore trial contents to excess
  \x@\let\x@\p@rtl\csname partial#1\endcsname
  \x@\let\x@\@xcs\csname excess#1\endcsname
  \ifvoid\p@rtl\else
    \global\setbox\@xcs\vtop{\joinboxes{\p@rtl}{\@xcs}{4}{0}}%
    \let\rdtmp\col@do
    \tempfalse
    \ifx\tri@llist\empty\else
      \edef\test{#1}%
      \let\col@do=\check@dup
      \x@\each@col\tri@llist\E
    \fi
    \let\col@do\rdtmp
    \iftemp\else
      \xdef\tri@llist{\tri@llist#1}% Add this as a trial to run
    \fi
  \fi
}

\def\p@rtialmarks#1{%p@rtial mark.
  \store@marks{#1}%
  \x@\let\x@\test\csname first#1mark\endcsname
  \ifx\test\empty 
    \trace{H}{using n@xtmark: first#1mark(\csname first#1mark\endcsname).->\csname n@xtfirst#1mark\endcsname}%
    \x@\xdef\csname first#1mark\endcsname{\csname n@xtfirst#1mark\endcsname}%
    \global\m@rksonpagetrue
  \else
    \trace{H}{not using n@xtfirst#1mark(\csname n@xtfirst#1mark\endcsname), already set as '\csname first#1mark\endcsname'}%
  \fi
  \trace{H}{bot#1mark(using n@xtmark \csname bot#1mark\endcsname) ->\csname n@xtbot#1mark\endcsname}%
  \x@\xdef\csname bot#1mark\endcsname{\csname n@xtbot#1mark\endcsname}%
}

%%%%%%%%%
% \Xht calculations, for 'snuggling' footnotes and chunks
\def\@curLht{0pt}
\let\@curRdp\@curLht
\let\@curRht\@curLht
\let\@curRdp\@curLht

\def\save@reset@ht#1{%Save the value of \Xht into \@nxtchunkXht, and set it to 0
  \x@\xdef\csname @nxtchunk#1ht\endcsname{\x@\the\csname #1ht\endcsname}%
  \x@\global\x@\csname #1ht\endcsname=0pt
}

\def\save@boxdim#1{%Save the height & depth of Xbox in \v@lpfx#1ht
  \x@\xdef\csname \v@lpfx#1ht\endcsname{\x@\the\x@\ht\csname #1box\endcsname}%
  \x@\xdef\csname \v@lpfx#1dp\endcsname{\x@\the\x@\dp\csname #1box\endcsname}%
} 

\def\forget@boxdim#1{%forget the height & depth of Xbox in \v@lpfx#1ht
  \x@\xdef\csname \v@lpfx#1ht\endcsname{0pt}%
  \x@\xdef\csname \v@lpfx#1dp\endcsname{0pt}%
} 

\def\count@dim@simplecols#1{%Is the dimension non non-zero? Count using curactivecols and add tag to list
  \x@\ifdim \csname \v@lpfx#1\v@lsfx\endcsname=0pt \else
    \advance\curactivecols by 1 % how many columns contain text?
    \edef\cts@list{\cts@list#1}%
  \fi
}
\def\chk@head#1{%Is the relevant item a heading? Set tempfalse if not
  \x@\ifnum\csname #1boxpenalty\endcsname <10000
    \tempfalse
  \fi 
}

\def\check@nxtht#1{%Is the nxtchunk#1 height =0? Set iftemp if yes, unchanged otherwise
  \x@\ifdim\csname @nxtchunk#1ht\endcsname=0pt 
    \diglot@ecolstrue
  \fi
}
\def\check@pen#1{%Is the relevant savedpenalty a pagebreak?
  \trace{d}{saved#1penalty is \csname saved#1penalty\endcsname}%
  \x@\ifnum\csname saved#1penalty\endcsname=-10000
    \temptrue
  \fi
}
\def\set@ht#1{%Set the values of curXht, adding or resetting based on \iftemp  (anything on the page is current by definition)
  % ifdiglot@ecols is set up by check@nxtht
  \def\errt@st{#1}\ifx\errt@st\empty\errmessage{set@ht passed null value}\fi
  \x@\dimen1\x@=\csname @nxtchunk#1ht\endcsname
  \ifdiglot@ecols %one at least is empty
    \ifdim \dimen1 =0pt
      \x@\dimen1\x@=\csname @cur#1ht\endcsname % new height = old height
    \else
      \advance\dimen1 by \m@xht\relax
    \fi
  \fi
  \trace{dP}{set@ht @cur#1ht set to \the\dimen1 \space \ifdiglot@ecols d@ecolstrue m@xht=\m@xht\else d@ecolsfalse\fi}%
  \x@\xdef\csname @cur#1ht\endcsname{\the\dimen1}%
}

\def\mkrev@list#1{\x@\xdef\csname rev@\list@type @list\endcsname{#1\csname rev@\list@type @list\endcsname}}

\def\max@bbl#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \ifx\t@st\empty\else
    \dimen0=\t@st\dimexpr \csname b@selineskip#1\endcsname\relax\relax
    \ifdim\dimen1< \dimen0
      \dimen1=\dimen0
    \fi
  \fi
}
\def\max@val#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \ifx\t@st\relax\else
    \ifdim\dimen1<\t@st
       \edef\m@x@at@col{#1}%
      \dimen1=\t@st
    \fi
  \fi
}
\def\delta@val#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \ifx\t@st\relax
    \trace{dP}{Eh? \v@lpfx#1\v@lsfx undefined}%
  \else
    \x@\xdef\csname\v@lopfx#1\v@losfx\endcsname{\the\dimexpr \dimen1 - \t@st\relax}%
    \trace{dP}{\v@lopfx#1\v@losfx \x@=  \csname \v@lopfx#1\v@losfx\endcsname}%
  \fi
}
%Sum values (for averaging)
\def\sum@val#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \advance\dimen1 by \t@st\relax
}

\def\maxjoint@val#1{\dimen0=\csname \v@lpfx#1\v@lsfx\endcsname
  \advance \dimen0 by \csname b@selineskip#1\endcsname\relax
  \trace{dP}{joint ht for #1 = \the\dimen0}%
  \ifdim\dimen1<\dimen0
    \edef\m@x@at@col{#1}%
    \dimen1=\dimen0
  \fi
}

\def\max@Tinsdim#1{%Save the height & depth of top insert in \v@lpfx#1ht
  \x@\let\x@\tmpins\csname \colinsert@name{\loc@T#1}\endcsname
  \setbox2\vbox{\unvcopy\tmpins}%
  \ifdim\ht2>\ht\tmpins
     \trace{D}{Insert \loc@T#1 was shrunk: \the\ht2 > \the\ht\tmpins}%
     \ht\tmpins=\ht2
  \fi
  \dimen0=\ht2\advance \dimen0 by \dp2 
  \ifdim\dimen1<\dimen0
    \edef\m@x@at@col{#1}%
    \dimen1=\dimen0
  \fi
} 

\def\max@boxsz#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \ifvoid\t@st \else
    \dimen0=\ht\t@st \advance\dimen0 by \dp\t@st\relax
    \ifdim\dimen1<\dimen0
      \edef\m@x@at@col{#1}%
      \dimen1=\dimen0
    \fi
  \fi
}
\def\max@boxht#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \ifvoid\t@st \else
    \dimen0=\ht\t@st
    \ifdim\dimen1<\dimen0
      \edef\m@x@at@col{#1}%
      \dimen1=\dimen0
    \fi
  \fi
}
\def\max@boxdp#1{\x@\let\x@\t@st\csname \v@lpfx#1\v@lsfx\endcsname
  \ifvoid\t@st \else
    \dimen0=\dp\t@st
    \ifdim\dimen1<\dimen0
      \edef\m@x@at@col{#1}%
      \dimen1=\dimen0
    \fi
  \fi
}

% Set boxes to be their natural height, and measure the maximum (into dimen1)
\def\resetb@xht#1{\x@\let\x@\t@mp\csname \v@lpfx#1\v@lsfx\endcsname
  \setbox1=\vbox{\unvcopy\t@mp}%
  \dimen0=\ht1
  \ifdim\dimen0>\ht\t@mp
    \trace{D}{Box \v@lpfx#1\v@lsfx was shrunk: \the\ht1 > \the\ht\topleftins}%
    \ht\t@mp=\dimen0
  \fi
  \ifdim\dimen1<\dimen0
    \edef\m@x@at@col{#1}%
    \dimen1=\dimen0
  \fi
}



% Set boxes to be dimen1 high
\def\reb@xht#1{\x@\let\x@\t@mp\csname \v@lpfx#1\v@lsfx\endcsname
  \ifdim\ht\t@mp=\dimen1 \else
    \setbox\t@mp=\vbox to \dimen1{\box\t@mp\vss}%
  \fi}

\def\void@boxes#1{\x@\global\x@\setbox\csname \v@lpfx#1\v@lsfx\endcsname=\box\voidb@x
 }

\def\max@boxszB#1{\max@boxsz{\if #1L\else #1\fi}} 

\def\min@note@sep#1{%
  \x@\let\x@\t@st\csname \v@lpfx#1ht\endcsname
  \x@\let\x@\t@stb\csname \v@lpfxb#1ht\endcsname
  \dimen0=\dimen2
  \trace{Df}{Notesep: (#1) d2:\the\dimen2\space -\t@st\space -\t@stb}%
  \advance\dimen0 by -\t@st\relax
  \advance\dimen0 by -\t@stb\relax
  \ifdim\dimen1>\dimen0
    \dimen1=\dimen0
  \fi
  \trace{Df}{Notesep for #1 is \the\dimen0, min: \the\dimen1}%
}


\def\each@col#1\E{% General purpose looper
  \edef\ect@st{#1}%
  \ifx\ect@st\empty\else
    \e@ch@col#1\E
  \fi
}

\def\e@ch@col#1#2\E{% General purpose looper, if there is at least one item.
  %\tracingmacros=1 \tracingassigns=1
  \trace{De}{each@col #1 #2}%
  \col@do{#1}%
  \edef\ect@st{#2}%
  \ifx\ect@st\empty %#2 is empty
    \trace{De}{last round}%
    \let\n@xt@col=\cstackrelax
  \else
    \let\n@xt@col=\e@ch@col
  \fi
  \ifnum\TRACEcount=\diglotDbgeachcol
    \tracingmacros=1\tracingassigns=1 %Conditional on TRACEcount=\diglotDbgeachcol
  \fi
  \trace{De}{continuing (\ect@st)}\relax
  \x@\n@xt@col \ect@st \E
}

\def\digl@tcle@rn@tecl@ss#1{% Diglot-loop friendly version of cle@rn@tecl@ss
  \cle@rn@t@cl@ss{\tmpnotecl@ss\if L#1\else #1\fi}%
}

\def\diglotcle@rn@tecl@ss#1{%
  \let\col@do=\digl@tcle@rn@tecl@ss
  \edef\tmpnotecl@ss{#1}%
  \x@\each@col\diglot@list\E
}

\newif\ifnot@empty % Is this chunk empty
\def\@tst@n@xtpartial@simplecols{%
  \ifvoid\n@xtpartial\else
    \temptrue
  \fi
}

\def\@add@n@xtpartial{% Actually make the page-changes
  \traceNum{d}{@add@n@xtpartial [\digl@tc@ntentlist|\digl@tc@ntent@xcs]}%
  \tempfalse
  \csname @tst@n@xtpartial@\diglotlayout\endcsname
  \iftemp
    \csname @add@n@xtpartial@\diglotlayout\endcsname
    \csname @after@add@n@xtpartial@\diglotlayout\endcsname
  \fi
}

\def\@add@n@xtpartial@simplecols{% 
  \traceNum{d}{@add@n@xtpartial@simplecols \the\ht\partial+\the\dp\partial, \the\ht\n@xtpartial+\the\dp\n@xtpartial}%
  \setdiglotN@rmal
  \pickn@xtpartial
  \ifvoid\partial
    \ifVisTrace
      \global\setbox\partial=\vtop{{\baselineskip=0pt \joinb@xes{\partial}{\n@xtpartial}
        %\ifpagefull
          %\vbox to 0pt{\vrule width 2pt height \availht \vss}%
        %\fi
      }}%
    \else
      \global\setbox\partial=\box\n@xtpartial
    \fi
  \else
    \global\setbox\partial=\vtop{{\baselineskip=0pt \joinb@xes{\partial}{\n@xtpartial}
    %\ifVisTrace\ifpagefull
      %\vbox to 0pt{\hbox{\vrule width 2pt height \availht} \vss}%
    %\fi\fi
    }}%
  \fi
  \ifnum\diglotDbgJoinboxes=\TRACEcount
    \showbox\partial
  \fi
  \voidn@xtpartial
}

\def\@after@add@n@xtpartial@simplecols{%
  \trace{d}{@after@add@n@xtpartial@simplecols}%
    \let\ifoldm@rksonpage\ifm@rksonpage
    \let\col@do=\p@rtialmarks
    \x@\each@col\diglot@list\E
    \ifm@rksonpage \ifoldm@rksonpage\else
      \loc@lhtfalse\dglt@calc@vailht
    \fi\fi
    % Column height (depth) calcs:
    \diglot@ecolsfalse
    \trace{Df}{Checking for empty boxes}%
    \let\col@do=\check@nxtht %sets iftemp=true if any box is empty
    \x@\each@col\diglot@list\E
    \ifdiglot@ecols
      \def\v@lpfx{@nxtchunk}\def\v@lsfx{ht}%
      \trace{Df}{Finding max \v@lpfx X\v@lsfx}%
      \let\col@do=\max@val\dimen1=0pt
      \x@\each@col\diglot@list\E
      \edef\m@xht{\the\dimen1}%
    \else
      \edef\m@xht{0pt}%
    \fi
    \trace{Df}{Saving new Xht values}%
    \trace{D}{LBP:\the\Lboxpenalty, RBP:\the\Rboxpenalty,  plp:\the\partialLpenalty, prp:\the\partialRpenalty}%
    \let\col@do=\set@ht %uses iftemp and m@xht
    \x@\each@col\diglot@list\E
    %
    %\global\p@geChunkDelta=\chunkDelta%
}

\def\postponen@xt@partial{%
  \trace{d}{postponen@xtpartial \the\ht\partial+\the\dp\partial, \the\ht\n@xtpartial+\the\dp\n@xtpartial}%
  \global\late@stage@reflowtrue % Need to re-flow all columns.
  \def\col@do##1{\r@storenotes{\@g@tndstat{##1}}{1}}%Restore footnotes on all columns.
  \x@\each@col\diglot@list\E% 
  \let\col@do=\restore@storedmarks
  \x@\each@col\diglot@list\E% 
  \r@storeinserts{chunk}
}

\def\tri@llist{}%Trials to be run.

\def\n@xttrial#1#2\E{%
  \xdef\tri@llist{#2}%
  \trace{D}{n@xttrial #1 (#2)}%
  \setc@rdstat{#1}\setLRspecific
}

\def\ch@ckcontents#1#2\E{%
  %sets various state flags and fills the list of trials 
  %left to run.
  %Assumption: called initially with a list of possibly-containing-stuff
  %columns, and empty \tri@llist.
  \edef\c@rrdstat{#1}%
  \edef\oldavht{\x@\the\csname availht\c@rrdstat\endcsname}%
  \x@\ifvoid\csname \c@rrdstat box\endcsname \else
    \trace{D}{side \c@rrdstat\space has material to put on the page}%
    \global\not@emptytrue
    \loc@lhttrue\dglt@calc@vailht
    \ifnum 1 = \ifboxmoved 1 \else \ifdim \availht<-2pt 1 \else 0 \fi\fi
      \late@stage@reflowtrue
      \xdef\refl@wlist{\refl@wlist\c@rrdstat}%
      \trace{D}{No space (\the\availht) for material (now, was \oldavht) reflow:\refl@wlist}%
    %\else
      %\x@\ifvoid\csname excess\c@rrdstat\endcsname\else
     %  \global\pagefulltrue % If we are here with stuff left to set, then clearly the page has filled up? No, the page-length may have been underestimated.
      %\fi
    \fi
  \fi
  \x@\ifvoid\csname excess\c@rrdstat\endcsname
    \trace{D}{side \c@rrdstat\space is finished for now}%
  \else
    \trace{D}{side \c@rrdstat\space has stuff to typeset}%
    \xdef\tri@llist{\tri@llist#1}% More trials to run 
  \fi
  \ifnum\csname \c@rrdstat boxpenalty\endcsname<-9999
    \trace{d}{side \c@rrdstat\space wants a pagebreak}%
    \global\pagefulltrue
    \x@\gdef\csname saved\c@rrdstat penalty\endcsname{0}%Saved penalty is used now.
    \global\csname \c@rrdstat boxpenalty\endcsname=-10000 %
  \fi
  \edef\n@xtarg{#2}%
  \let\afterch@ckcontents\ch@ckcontents
  \ifx\n@xtarg\empty
    \let\afterch@ckcontents\cstackrelax
  \fi
  \x@\afterch@ckcontents\n@xtarg\E
}

\edef\diglot@list{LR}%
\edef\layout@list{LR}%
\edef\rev@layout@list{RL}%
\edef\digl@tc@ntentlist{}% columns that have *UNPROCESSED* content that has been gathered for the next chunk
\def\digl@txcsL{}% Empty or column ID 
\def\digl@txcsR{}
\def\digl@tc@ntent@xcs{\digl@txcsL\digl@txcsR}% columns that have *SEMI-PROCESSED* content (overflow)


\def\check@and@update{%Checks each column to see if there is stuff to output
  %and calls upd@tep@rtial as appropriate
  %responds to \ifboxmoved and \pagefull, checking the last chunkpenalty
  \trace{d}{check@and@update \the\triall@@pcount \ifboxmoved boxmoved\fi \the\lastchunkpenalty}%
  \not@emptyfalse
  \x@\ch@ckcontents\diglot@list\E%Sets not@empty if there's stuff to output
  \trace{d}{check@and@update reflow:\refl@wlist\space t:\tri@llist}%
  \ifboxmoved
    \IfTr@ce{gI}{%
      \let\d@=\sh@winsertdim\edef\v@lpfx{save}\edef\v@lsfx{chunk}%
       \x@\cstackdown\ins@rts\E
      \let\d@=\sh@winsertdim\edef\v@lpfx{}\edef\v@lsfx{}\x@\cstackdown\ins@rts\E
    }%
    \r@storeinserts{chunk}%
    \trace{d}{Resetting notes: \refl@wlist}%
    \def\col@do##1{\r@storenotes{\@g@tndstat{##1}}{1}}%Restore footnotes on all columns.
    \x@\each@col\refl@wlist\E%
    \ifnum\lastchunkpenalty>9999
      \postponen@xt@partial
      \@writep@ge
      \setdiglotN@rmal
      \pickn@xtpartial
      \@add@n@xtpartial
      \let\col@do=\reset@n@xt
      \x@\each@col\diglot@list\E% 
      \global\lastchunkpenalty=0
    \else
      \ifdim\dimexpr \ht\partial + \dp\partial + \ht\n@xtpartial + \dp\n@xtpartial=0pt
        \message{UNPRINTABLE PAGE CONTENTS! Image too big? Somewhere near \c@rref}%
        \ifunprintable
          \errmessage{Cannot continue}%
          \divide \count0 by 0 
        \else
          \message{Trying to continue by breaking rules}%
        \fi
        \global\unprintabletrue
      \else
        \@add@n@xtpartial
        \@writep@ge
      \fi
      \let\col@do=\reset@n@xt
      \x@\each@col\diglot@list\E% 
    \fi
    \global\boxmovedfalse
  \else
    \ifnot@empty 
      \global\late@stage@reflowfalse
    \else
      \ifx\tri@llist\empty\else
        \ifnum\triall@@pcount>10
          \message{Forcing page break}%
          \global\pagefulltrue
        \fi
      \fi
    \fi
    \upd@tep@rtial
  \fi
}

\newcount\triall@@pcount

\def\diglot@run@trials{% for X as L, R, (eventually others)
  %expects: collected input in partialX, excessX empty
  %Process: cycle through chunks  
  \traceNum{d}{diglot@run@trials (\digl@tc@ntentlist|\digl@tc@ntent@xcs|\tri@llist) sp=\the\savedpenalty}%
  \let\tri@llist\digl@tc@ntentlist%
  %Before running trials, empty(eventually store?) old galleys
  \empty@partials
  \let\tri@llist\digl@tc@ntentlist% Run trials for things that have contents
  \xdef\digl@tc@ntentlist{}%
  \global\late@stage@reflowfalse
  \def\refl@wlist{}% List of columns needing to reflow.
  \ifx\empty\tri@llist\else
    \triall@@pcount=1
    \diglot@run@nxt@trial
  \fi
  \def\v@lpfx{@nxtchunk}\def\v@lsfx{ht}\def\v@lopfx{@}\def\v@losfx{egap}%
  \dimen1=0pt
  \let\col@do=\max@val\dimen1=0pt
  \x@\each@col\diglot@list\E
  \let\col@do=\delta@val
  \x@\each@col\diglot@list\E % Find 'skip' after each chunk
}

\def\empty@partials{%Empty (eventually store?) partialX
  \ifx\tri@llist\empty\else 
    \loop
      \x@\n@xttrial\tri@llist\E
      \trace{D}{Blanking partial\c@rrdstat}%
      \x@\setbox\csname partial\c@rrdstat\endcsname=\box\voidb@x
    \unless\ifx\tri@llist\empty\repeat
  \fi
}

\newif\ifp@rtlset
\def\diglot@run@nxt@trial{%
  \traceNum{d}{diglot@run@nxt@trial}%
  \x@\n@xttrial\tri@llist\E % cuts 1st column off tri@lalist and makes it current.
  \ifx\c@rrdstat\empty %End of the loop.
  \else
    \ifnum 1=\x@\ifvoid\csname excess\c@rrdstat\endcsname \x@\ifvoid\csname partial\c@rrdstat\endcsname 0\else 1\fi\else 1\fi
      \loc@lhttrue\dglt@calc@vailht
      %\ifnum\triall@@pcount=1
        %\showbox\partialL\showbox\excessL
      %\fi
      \global\p@rtlsetfalse
      \run@a@trial
      \relax
    \fi
  \fi
  \relax\relax
}
\def\@diglot@pagebreak{%
  %\emitpartial
  %\setdiglotN@rmal % Left=left (normal) or not?
  %\pickn@xtpartial
  \@add@n@xtpartial
  \@writep@ge
  %\check@and@update
}
\def\after@after@a@trial{%
  \trace{d}{after@after@a@trial iftrialfailed\iftrialfailed true\else false\fi,  tlc=\the\triall@@pcount, pf:\ifpagefull true\else false\fi [\tri@llist|\digl@tc@ntent@xcs]}%
  % Check if the run failed (or didn't even run), and update page if that's 
  % appropriate.
  \iftrialfailed
    \ifnum\triall@@pcount=1
      \global\boxmovedtrue %Only count box as moved if the first chunk doesn't fit. 
    \fi
    \trace{D}{Setting pagefull to true}%
    \global\pagefulltrue
  \else
    \x@\let\x@\tmppen\csname \c@rrdstat boxpenalty\endcsname
    %\tracingassigns=0
    \ifnum \tmppen>\chunkpenalty
      \global\chunkpenalty=\tmppen
    \fi
  \fi
  \ifboxmoved % Breaks things?
    %things gone from the triallist should be reflowed,
    % for other things, partialX still contains the previous galley
    \trace{D}{BOX moved, emptying old partials: \tri@llist}%
    \ifx\empty\triallist\else
      \empty@partials% voids partialX for all X in tri@llist, also sets triallist to empty.
    \fi
  \fi
  %\showlists
  \trace{D}{tri@llist: \tri@llist|\digl@tc@ntent@xcs, tlc=\the\triall@@pcount}%
  \ifx\tri@llist\empty
    \advance\triall@@pcount by 1\relax
    \check@and@update %May trigger a refilling of \tri@llist
    \trace{D}{after check@and@update, tri@llist: \tri@llist, refl@wlist:\refl@wlist, xs:\digl@tc@ntent@xcs, pagefull\ifpagefull true\else false\fi}%
    \ifx\refl@wlist\empty\else
      \trace{d}{Reflowing aborted trials: \refl@wlist}%
      \let\col@do=\reflow@trial
      \x@\each@col\refl@wlist\E%
      \global\let\refl@wlist\empty
    \fi
    \ifx\tri@llist\empty
      \let\n@xt=\relax
    \else
      \let\n@xt=\diglot@run@nxt@trial
    \fi
  \else
    \let\n@xt=\diglot@run@nxt@trial
  \fi
  \n@xt
}   

\def\enddigl@t{%
  \endgraf
  \trace{d}{enddigl@t \the\ht\n@xtpartial+\the\dp\n@xtpartial, \the\ht\partial+\the\dp\partial (\digl@tc@ntentlist|\digl@tc@ntent@xcs)}%
  \ifdiglot\ifx\digl@tc@ntentlist\empty
    \trace{d}{digl@tc@ntentlist empty}%
    \else
      \ifsk@pping \egroup \fi% if we were skipping nonpublishable text, end that mode
      \sk@ppingfalse
      \ifhe@dings\endhe@dings\fi%
      \eject
      \global\allNeedEmptyingtrue
      \diglot@run@trials
      \penalty\dgl@tPenColSwap
      \global\allNeedEmptyingtrue
    \fi
    \x@\ch@ckcontents\diglot@list\E%Sets not@empty if there's stuff to output
    \trace{d}{enddigl@t 2nd run \the\ht\n@xtpartial+\the\dp\n@xtpartial, \the\ht\partial+\the\dp\partial (\digl@tc@ntentlist|\digl@tc@ntent@xcs|\tri@llist)}%
    \diglot@run@trials
    \ifnum\interactionmode=2
      \showbox\n@xtpartialNrml\showbox\n@xtpartialRev
    \fi
    \@add@n@xtpartial
    \trace{d}{After that; \the\ht\partial+\the\dp\partial, \the\ht\n@xtpartial+\the\dp\n@xtpartial}%
    \ifdim \dimexpr \ht\partial+\dp\partial\relax=0pt\else
      \ifversion{2}{%
        \iftextborder\temptrue
        \else 
          \tempfalse\let\col@do\ck@backgrounds
          \x@\each@col\diglot@list\E% 
        \fi
        \iftemp\dimen1=\dp\partial
          \ifdim\dimen1<\baselineskip
            \setbox\partial\vbox{\unvbox\partial\kern\dimen1}%
          \else
            %\setbox\partial\vbox{\unvbox\partial}%
          \fi
        \fi%avoid clashes with textborder and backgrounds
        %\iftextborder
          %\ifpartialfr@med\else
            %\doTextB@rder{\partial}%
            %\global\partialfr@medtrue
          %\fi
        %\fi
        %\ifnum\pageno=117\showbox\partial\fi
        \csname digl@t@endbook@\diglotlayout\endcsname
        \csname @savepartial@\diglotlayout\endcsname
        \trace{d}{Book end: partial \the\ht\partial+\the\dp\partial}%
      }{\@writep@ge
        \let\col@do=\reset@n@xt
        \x@\each@col\diglot@list\E% 
      }%
    \fi
    \trace{d}{Book end: Not writing page}%
    %\pr@sideswitch{end}{L}%
    \let\digl@tc@ntentlist\empty
  \fi
  %FIXME! If \ifendbooknoeject  happens to be true, then what? 
  %Set the 2 columns, put the footnotes up in the air (or not?) and carry on??
}

\def\digl@t@endbook@simplecols{%
  \ifdim\availht > \dimexpr\ht\bookendbox + \dp\bookendbox \relax      
    \setbox\verybottomins\vbox{\box\verybottomins\box\bookendbox}%
  \fi
}

\def\@savepartial@simplecols{%
  \setbox\partial\vbox{\unvbox\partial
    \csname @start@writep@ge@\diglotlayout\endcsname
    \setdiglotN@rmal
    \pickn@xtpartial
    \csname @prep@writep@ge@\diglotlayout\endcsname
    \actually@writefalse
    \csname @do@writep@ge@\diglotlayout\endcsname
    \pagecontents
  }%
}
\def\makediglotgutter#1#2#3{\hbox to \gutter{\hss
%rule is #1 hight, #3 deep, and fits in a box #2 high
  \trace{D}{makediglotgutter \the #1,\the #2,\the #3}%
   \setbox4=\vbox to #2{%
     \dimen4=#2\advance\dimen4 by -#1\relax
     \kern\dimen4
     \hbox to 1pt{\hfil
       \ifColumnGutterRule
        \dimen4=#1\advance \dimen4 by #3\relax
        \vrule height \the\dimen4 width \RuleThickness
       \fi
       \hfil}%\dp5=#3 \box5
      \vss}%
    \dp4=#3
    \box4
  \hss}}

\def\diglotlayout{simplecols}

\def\diglotgr@db@x#1{%
 \ifdiglot\vbox{\gr@db@@x{#1}\penalty \ifnormalhe@dings 10000\else 10\fi}\penalty\ifnormalhe@dings 10000\else 10\fi\else\gr@db@@x{#1}\fi
}
\def\testmarker{\hbox to 0pt{\vrule height 7pt depth 0pt width 0.5pt \kern-0.5pt}\message{_}}

\def\log@cumulative#1{\x@\let\x@\tmp\csname cumulativeDelta#1\endcsname\edef\logt@mp{\logt@mp\space #1:\the\tmp (\the\numexpr \tmp / ( 1+\pageno - \ptxst@rtp@ge)\relax\space pt/pg)} \global\tmp=0\relax}
%\def\log@cumulative#1{:#1:}

\addtoendptxhooks{%
    \bgroup\ifdiglot\ifnum\pageno>0 \relax
    \let\col@do=\log@cumulative 
    \def\logt@mp{}
    \x@\each@col\diglot@list\E
     \message{Column deltas for book: \logt@mp} \fi\fi\egroup \relax
 }%
\addtoendhooks{\ifdiglot\ifvoid\partial\else\@writep@ge\fi\fi}

% The polyglot-style input is almost free. -simplecols layout is what we get with old-style diglot2. 


%%%%%%%% This might one day be moved to polyglot-simplecols.tex
% Below here are pieces of code that extend the basic diglot2 (2 column) layout into more columns.
%
\def\polyglotpages#1{% This is overwritten by the copy in polyglot-simplepages if that's loaded. Just does the basic functionality of setting the column order
  \trace{d}{polyglotpages #1}
  \xdef\diglot@list{#1}% The list of all columns
  \ifx\diglot@list\empty
    \errmessage{polyglotpages called with empty argument. That breaks things.}%
  \fi
  \xdef\layout@list{#1}% List of columns in normal order
  \let\col@do=\mkrev@list
  \def\list@type{layout}%
  \xdef\rev@layout@list{}% mkrev@list will fill this with the columns in reverse order
  \x@\each@col\layout@list\E%
}

\def\newPolyglotCol#1{%
  \ifcsname #1isDiglotColumn\endcsname
    %\message{#1 is already a diglot column. You can only define it as one once!}%
  \else
    \@newPolyglotCol{#1}%
  \fi
}
\def\@newPolyglotCol#1{%
    \message{Defining #1 as an additional polyglot column.}%
    \newcolins@rt{\loc@T#1}% column top insert
    \newcolins@rt{\loc@B#1}% column bottom insert
    \let\old@cts\digl@tc@ntentlist
    \let\digl@tc@ntentlist=\diglot@list
    \add@to@digl@tc@ntentlist{#1}%
    \global\let\diglot@list=\digl@tc@ntentlist
    \global\let\layout@list=\digl@tc@ntentlist % BY default, layout is all columns.
    \let\digl@tc@ntentlist=\old@cts
    %Now make the reversed layout list
    \let\col@do=\mkrev@list\def\list@type{layout}%
    \xdef\rev@layout@list{}
    \x@\each@col\diglot@list\E% 
    {\edef\sfx{#1}\let\wh@t\n@wSpecificDim \pr@cessSpecificDim}
    \x@\let\csname #1isDiglotColumn\endcsname\empty
%    \x@\newb@x\csname #1discards\endcsname
    \x@\newb@x\csname #1box\endcsname
    \x@\newb@x\csname partial#1\endcsname
    \x@\newb@x\csname whole#1\endcsname
    \x@\newb@x\csname excess#1\endcsname
    \x@\newb@x\csname picb@x#1\endcsname
    \x@\newt@ks\csname diglot#1ho@ks\endcsname
    \x@\newc@unt\csname saved#1penalty\endcsname
    \x@\newc@unt\csname partial#1penalty\endcsname
    \x@\newc@unt\csname #1boxpenalty\endcsname
    \x@\newc@unt\csname cumulativeDelta#1\endcsname
    \newm@rknum{#1}%
    \x@\newdim@n\csname column#1width\endcsname
    \x@\newdim@n\csname baselineDelta#1\endcsname
    \x@\newdim@n\csname availht#1\endcsname
    \x@\newdim@n\csname #1ht\endcsname
    \x@\xdef\csname at@ndofthispar#1\endcsname{}%
    \x@\xdef\csname m@rker#1\endcsname{}%
    \x@\xdef\csname digl@txcs#1\endcsname{}%
    \x@\xdef\csname mcstack#1\endcsname{\mcstack@mpty}%
    \newsp@cialpen{dgl@tPen#1trialEnd}%
    \header@defs{#1}% All the possible header contents
    \x@\n@wif\csname ifinp@r-#1\endcsname % Used for parlocs analysis
    \x@\newc@unt\csname p@rlinesgone-#1\endcsname % Used for parlocs analysis
    \x@\newc@unt\csname @numcuts#1\endcsname % Used for parlocs analysis
    \x@\newc@unt\csname curr@djpar#1\endcsname % Used for adjust-lists
    \x@\newc@unt\csname p@rnum#1\endcsname % Used for adjust-lists
    \x@\newc@unt\csname dropped@ther@lines#1\endcsname % Used for parlocs analysis
    \x@\gdef\x@\digl@tc@ntent@xcs\x@{\digl@tc@ntent@xcs\csname digl@txcs#1\endcsname}%
    \initcolumndef@ults{#1}%
%TODO:
%FIXMEs needing for polyglot processing:
% UI!
% The column-delta totals should be per-column, and be summed as cross-column deltas compared to the average.
}

\def\extra@insert@alias#1#2{% Assumption: #1 is already in the form \foo, #2 is in the form \csname something\endcsname
    \x@\x@\x@\gdef\x@\x@\x@\alias@inserts\x@\x@\x@{\x@\alias@inserts\x@\let\x@#1#2}}

\def\newcolins@rt#1{%
  \edef\ins@name{\colinsert@name{#1}}%
  \ifcsname \ins@name\endcsname\else
    \xdef\columnins@rts{\columnins@rts\ins@name,}%
    \x@\newins@rt\csname \ins@name\endcsname
    \x@\global\x@\count\csname \ins@name\endcsname=0
    \x@\global\x@\dimen\csname \ins@name\endcsname=\maxdimen
    \xdef\ins@rts{\columnins@rts\pageins@rts}%
    \x@\m@keinsertsaveboxes \ins@name\E
    \x@\extra@insert@alias\x@{\csname ins-#1\endcsname}{\csname \ins@name\endcsname}%FIXME
  \fi
  \let\ins@name=\undefined
}
\def\SetBelowBaseline#1#2#3{% Column #1 has #2 [dimension] below the baseline (which is  #3) of 
  \r@tio{#2}{#3}\trace{d}{BelowBaseline Calculated for #1 as \@@r@tio}\x@\let\csname BelowBaseline#1\endcsname\@@r@tio}

\x@\let\csname polyglot-simplecols@plugin@loaded\endcsname\empty 
\endinput
