%:skip
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Part of the ptx2pdf macro package for formatting USFM text
% copyright (c) 2022 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.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% General purpose "book ch:V" parser.
\def\@p@rseref#1{%
  \edef\tmpa{#1}%
  \edef\tmp{\x@\zap@space#1 \empty}%
  \ifx\tmp\tmpa
    \let\p@rsedV\relax%
    \trace{T}{Unparsable reference "#1"}%
  \else
    \x@\@@p@rserefC#1::\END % First try CH:V
    \ifx\p@rsedV\relax\x@\@@p@rserefD#1..\END\fi % if that fails, then try CH.V
    \trace{T}{Parsed reference as '\p@rsedID' '\p@rsedC':'\p@rsedV'}%
  \fi
}

\def\@@p@rserefC#1 #2:#3:#4\END{%
  \def\tmp{#3}\ifx\tmp\empty\let\p@rsedV\relax\else
    \let\p@rsedV\tmp\edef\p@rsedID{#1}\edef\p@rsedC{#2}%
  \fi
}
\def\@@p@rserefD#1 #2.#3.#4\END{%
  \def\tmp{#3}\ifx\tmp\empty\let\p@rsedV\relax\else
    \let\p@rsedV\tmp\edef\p@rsedID{#1}\edef\p@rsedC{#2}%
  \fi
}


% scantokens triggers eof, and might be used to pull in code that makes other scantokens calls.
% Therefore it should be wrapped in these: 
\newcount\s@vedeofdepth
\def\p@sheof{\advance\s@vedeofdepth by 1 \x@\def\csname eofsave\the\s@vedeofdepth\x@\endcsname\x@{\the\everyeof}\everyeof{}}
\def\p@peof{\x@\x@\x@\everyeof\x@\x@\x@{\csname eofsave\the\s@vedeofdepth\endcsname}\x@\let\csname eofsave\the\s@vedeofdepth\endcsname\undefined\advance\s@vedeofdepth by -1 }% 1st expansion makes the csname into a macro name, second gets its contents
% Utility macros for rotation, etc.
\def\geom@xform@u{{1}{0}{0}{1}} % Normal
\def\geom@xform@d{{-1}{0}{0}{-1}} %Rotate 180 / Flip both
\def\geom@xform@l{{0}{-1}{1}{0}} % Rotate +90
\def\geom@xform@r{{0}{1}{-1}{0}} % Rotate -90
\def\geom@xform@h{{-1}{0}{0}{1}} % Flip Horizontally 
\def\geom@xform@v{{1}{0}{0}{-1}} % Flip vertically
\def\geom@xform@L{{0}{-1}{-1}{0}} % Rotate +90 and Flip vertically
\def\geom@xform@R{{0}{1}{1}{0}} % Rotate -90 and Flip vertically


\def\setgeomtransform#1{%
  \x@\let\x@\geom@xform\csname geom@xform@#1\endcsname
  \ifx\geom@xform\relax
    \let\geom@xform\geom@xform@u
  \fi
  \x@\s@tgeomtransform@m\geom@xform % Calculate pdf@aa, etc.
} 

\def\s@tgeomtransform@m#1#2#3#4{%
  \def\pdf@aa{#1}\def\pdf@ab{#2}\def\pdf@ba{#3}\def\pdf@bb{#4}%
}

\setgeomtransform{u}

\def\@pprox#1#2#3{% #1 = number #2 =  significant 3-bits. #3 = where to save the value.
  \bgroup \dimen0=#1 \count255=0
    \loop \unless\ifdim \dimen0=0pt 
      \divide \dimen0 by 8
      \advance \count255 by 1
      \repeat
    %\message{Removing #1 has \the\count255 significant 3-bits}%
    \advance \count255 by -#2
    \dimen0=#1 \tmpcount=0
    \loop \ifnum\count255>0
      \divide \dimen0 by 8
      \advance \count255 by -1
      \advance \tmpcount by 1 \relax
      %\message{After removing \the\tmpcount  digits from #1: \the\dimen0}%
      \repeat
    \loop \ifnum\tmpcount>0
      \multiply \dimen0 by 8
      \advance \tmpcount by -1
      \repeat
    \xdef#3{\the\dimen0}%
    %\message{#1 to #2 significant 3-bits is #3}%
  \egroup
}
    
\long\def\addto@macro#1#2{%
    \x@\x@\x@\def\x@\x@\x@#1\x@\x@\x@{\x@#1#2}}%

\def\stripqu@te#1{\x@\@stripqu@te #1""\E\relax}
\def\@stripqu@te #1"#2"#3\E{\def\@@result{#2}\ifx\@@result\empty\def\@@result{#1}\fi}

\def\ch@cktypecs#1{% Check type of named control sequence
 \ifcsname \m@rker\endcsname
   \ifcsname stylet@pe-#1\endcsname
     \global\let\ch@ck@result=\dt@marker % More detail from interrogating the stylet@pe
   \else
     \x@\ch@cktype\x@{\csname \m@rker\endcsname}%
   \fi
 \else
   \global\let\ch@ck@result\dt@undefined
 \fi
}
\def\ch@cktype#1{% Check type of giVEN WOTsit
  \bgroup\edef\tmp{\meaning#1}%
  \ifx\tmp\dt@undefined \global\let\ch@ck@result\dt@macro
  \else
    \x@\x@\x@\ch@ktypeA\x@\tmp\dt@macro\ENDIT
  \fi
  \egroup \tracingassigns=0
}
\x@\def\x@\ch@ktypeA\x@#\x@1\dt@macro#2\ENDIT{%
  \def\tmpB{#2}\ifx\tmpB\empty 
    \global\let\ch@ck@result\oth@r% Some kind of primitive.
  \else 
    \global\let\ch@ck@result\dt@macro % Some kind of macro
  \fi
}

\def\r@tio#1#2{{% find the fractional ratio #1/#2, trying to get to the limit of TeX's fixed-point maths. Assumption is that both values are "reasonable" font/line/page dimenstions.
  \dimen1=#1 \dimen2=1pt \count255=16384 % maxdimen=16384pt-1sp. 
  \loop
    \ifdim \dimen1>\dimen2
      \divide\count255 by 2
      \multiply\dimen2 by 2
      \repeat
  \ifdim\dimen1=\dimen2 % can't sensibly do >=, so check the = case here.
    \multiply\dimen2 by 2
    \divide\count255 by 2
  \fi
  \multiply\dimen1 by \count255 % left-shift numerator as much as possible.
  \dimen3=#2
  \count255=\dimen2 
  \divide\count255 by 32768 %dimen2 is an integer number of pt. 1pt=65536sp => 65536 when put into a count.
  \dimen4=1pt
  \divide\dimen4 by \count255 \relax
  %\message{\the\dimen3, \the\dimen4, \the\numexpr\dimen3/\dimen4\relax}%
  \ifnum 1 = \ifdim \dimen3> 4pt 1 \else \ifdim \dimen3 >4092\dimen4 1 \else 0 \fi\fi % ensure there'll be a reasnonable number left after shifting
    %\message{strategy1}
    \divide\dimen3 by \count255 %right-shifting the denominator saves multiplying the result later. Both lose accuracy.
    \divide\dimen1 by \dimen3 
    \multiply\dimen1 by 2% Scale to factor 1 = 1pt. 
  \else
    %\message{strategy2}
    \divide\dimen1 by \dimen3 
    \multiply\count255 by 2
    \multiply\dimen1 by \count255
  \fi
  \xdef\@@r@tio{\strip@pt{\dimen1}}%
}}

\def\decod@lastnode#1{\ifnum #1<0 none\else \ifcase #1
    char%0
\or hlist\or vlist\or rule\or ins\or mark%5
\or adjust\or lig\or disc\or whatsit\or math%10
\or glue\or  kern\or penalty\or unset\or mathmode%15
\else UNK\fi\fi}

%Defined penalties
\xdef\sp@cialpen{-10001}
\def\newsp@cialpen#1{%define a new special penalty {#1}  which gets set as the next special penalty number (assuming all special penalties are registered with this function.
  {\count255=\numexpr \sp@cialpen-1\relax
  \x@\xdef\x@\sp@cialpen{\the\count255}%
  \message{Special penalty #1 is \sp@cialpen}%
  \x@\xdef\csname #1\endcsname{\sp@cialpen}
  \x@\xdef\csname d@code:\sp@cialpen\endcsname{#1}}%
}

% Some special penalty values
\x@\xdef\csname d@code:-101\endcsname{layoutswap}
\x@\xdef\csname d@code:-10000\endcsname{eject}
\x@\xdef\csname d@code:-20000\endcsname{supereject}
\x@\xdef\csname d@code:0\endcsname{ - }

% Custom marks
\xdef\m@rksm@x{0}
\newtoks\usedm@rks
\def\newm@rknum#1{%define a new m@rknum#1 which gets set as the next unused marks  register (assuming all marksN are registered with this function.
  {\count255=\numexpr \m@rksm@x+1\relax%
  \x@\xdef\x@\m@rksm@x{\the\count255}%
  \x@\xdef\csname m@rknum#1\endcsname{\m@rksm@x}}% Don't change this witout a lot of search and replace!
  \trace{ma}{newm@rknum #1 -> \m@rksm@x}%
}
\def\addnewm@rk#1{\x@\usedm@rks\x@{\the\usedm@rks \\{#1}}\trace{ma}{addnewm@rk #1 - usedm@rks=\the\usedm@rks}}
\def\getm@rknum#1{%retrieve or get a new m@rknum#1
  \x@\let\x@\m@rknum\csname m@rknum#1\endcsname%
  \ifx\m@rknum\relax%
    \newm@rknum{#1}\let\m@rknum\m@rksm@x%
  \fi%
  \trace{ma}{getm@rknum #1 -> \m@rknum}%
}

\def\savem@rks{%
 % \ifnum\pageno=33 \showthe\usedm@rks\fi
  \let\\=\relax\trace{ma}{Saving marks: \the\usedm@rks}\let\\=\save@m@rk \the\usedm@rks}
\def\save@m@rk#1{\getm@rknum{#1}\x@\xdef\csname customtopmark-#1\endcsname{\firstmarks\m@rknum}\x@\xdef\csname custombotmark-#1\endcsname{\botmarks\m@rknum}\trace{ma}{top=\csname customtopmark-#1\endcsname, bot=\csname custombotmark-#1\endcsname}}
\def\unsavem@rks{\trace{ma}{Unsaving marks: \the\usedm@rks}\let\\=\unsave@m@rk \the\usedm@rks}
\def\unsave@m@rk#1{\getm@rknum{#1}\ifcsname customtopmark-#1\endcsname\marks\m@rknum{\csname customtopmark-#1\endcsname}\else\trace{ma}{-skipping customtopmark-#1 (undefined)-}\fi\ifcsname custombotmark-#1\endcsname\marks\m@rknum{\csname custombotmark-#1\endcsname}\fi}


