% Copyright 2012-2024, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% SPLinT is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see .
\def\yyuniontag{\auxunionctl}
\defp\xrefunionctl{}% sequence to activate/deactivate/take other action for
% xref set of macros
\defc\xrefunionctl{%
\restorecslist{aux:global:xrefs}\xrefunion
}
\savecs{aux:global:activate}\xrefunionctl
\defc\xrefunionctl{%
\restorecslist{aux:global:xrefs:neutral}\xrefunion
}
\savecs{aux:global:deactivate}\xrefunionctl
\defc\xrefunionctl{% this command should not make any page material contributions
\message{xrefs...}%
}
\savecs{aux:global:preend}\xrefunionctl
\defc\xrefunionctl{% writing a header, etc.
\message{xrefs...}%
\toksa\expandafter{\xrefunion}%
\immediate\write\auxstream{\harmlesscomment\the\toksa}%
}
\savecs{aux:global:prestart}\xrefunionctl
\yyuniondeclare\xrefunion{aux:global:xrefs}
\defp\MNM#1#2#3#4{}
\defp\XXX#1#2#3{}
\defp\BBB#1#2#3#4{}
\defp\SSS{}
\toyyunion{aux:global:xrefs:neutral}
% end global stream union macros for cross referencing
\def\stseclap{\rightskip=0pt % get out of C mode (cf. \B)
\sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
\noindent{\let\*=\empty\llap{\tentitle\setsafesecno{\secno}\quad}}% push it to the margins
\putxref{\MNM}{}{}.% generate a location reference for noweb cross referencing style
\ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
\let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
\else
\ifpdf
\smash{\raise\baselineskip
\hbox to0pt{%
\let\*=\empty\special{%
pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]%
}%
}%
}%
\fi
\fi
}
\ifx\customchapterstyle\UNDEFINED
\def\customchapterstyle{0}
\fi
\ifx\customsubchapterstyle\UNDEFINED
\let\customsubchapterstyle\empty
\fi
\def\stsecchap#1#2{\rightskip=0pt % get out of C mode (cf. \B)
\sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
%
\ifnum#1>\z@ % the `level' if this section is below that of a chapter
\noindent{\let\*=\empty\llap{\tentitle
\setsafesecno{\secno}\quad}}{\stsecchapttl{#1}#2\stsecchapterminator{#1}}% push it to the margins
\putxref{\MNM}{\customsubchapterstyle}{}.% generate a location reference for noweb cross referencing style
\stsecchapseparator{#1}%
\else
\setchaptertitle{\secno}{#2}%
\putxref{\MNM}{\customchapterstyle}{}.% generate a chapter location reference for noweb cross referencing style
\fi
%
\ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
\let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
\else\ifpdf\smash{\raise\baselineskip\hbox to0pt{%
\let\*=\empty\special{%
pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi}
\def\stsecchapterminator#1{} % for deeply nested sections one may put a dot at the end
\def\stsecchapseparator#1{%
\smallskip
\noindent
}
\def\stsecchapttl#1{\ttl}
\def\setchaptertitle#1#2{%
\global\chapterheadtrue
\null
{\ninepoint\tempda=\baselineskip
\multiply\tempda by 17
\vskip\tempda plus\baselineskip minus 2pt
}%
\vbox to 0pt{%
\vss
\tabskip=0pt plus 1 fil
\halign to\hsize{%
\hfil##\tabskip=0pt\cr
\hugetitle\setsafechapno{#1}\cr
\noalign{\vskip 1pc}%
\midtitle#2\cr
}%
}%
\prevdepth=0pt
\bigskip
\noindent%{\let\*=\empty\llap{\tentitle\setsafesecno{\secno}\quad}}%
}
\let\startsection\stseclap
\expandafter\def\expandafter\oldB\expandafter{\oldB\global\csectionstarttrue\putxref{\BBB}{}{}.}
% the command that writes references to the reference stream (file):
% \{page}{section}{param1}{param2}
%
\def\putxref#1#2.{% it is important that #2 contains at least two braced groups (as in {}{})
% otherwise the parameter scanning mechanism will strip the outside braces
\ifxreflocal
{\edef\next{\write\auxstream{\nx\nx\nx#1{\nx\the\nx\pageno}{\secno}#2\harmlesscomment}}\next}%
\fi
}
\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi %$% section name
\XX$\langle\,${\let\I=\ne#2\eightrm\kern.5em
\ifacro{\pdfnote#1.}\else#1\fi}$\,\rangle$\putpathindex{\secno}{#1}\XX\putxrefx{#1}{#2}}
\def\putxrefx#1#2{%
\ifxreflocal
{\def\sname{#2}%
\def\stripprefix##1>{ }%
\let\*\empty
\edef\next{\write\auxstream{\nx\nx\nx\XXX{\nx\the\nx\pageno}{\secno}{#1}\harmlesscomment
\expandafter\stripprefix\meaning\sname}}\next}%
\fi
}
\newif\ifcsectionstart % does this section name appear at the beginning of a \Cee\ section?
\def\putpathindex#1#2{%
\ifcsectionstart
\global\csectionstartfalse\strut
\vadjust{%
\setbox0=\hbox{\strut}%
\kern-\dp0
\vbox to 0pt{
\vss
\hbox to\pagewidth{%
\hfil\rlap{%
\let\*\empty
\kern1em \setpathlinks{#1}{#2}%
}%
}%
}%
\setbox0=\hbox{\strut}%
\kern\dp0
}%
\fi
}
\def\setpathlinks#1#2{%
\expandafter\ifx\csname xchain[#1][#2]down\endcsname\relax
\expandafter\ifx\csname xchain[#1][#2]up\endcsname\relax
\else
\setuplink{#1}{#2}{\hfil##\hfil}%
\fi
\else
\expandafter\ifx\csname xchain[#1][#2]up\endcsname\relax
\setdownlink{#1}{#2}{\hfil##\hfil}%
\else
\setuplink{#1}{#2}{##\hfil}
\setdownlink{#1}{#2}{\hfil##}%
\fi
\fi
}
\def\setdownlink#1#2#3{%
{\setbox0\vtop{
\sevenpoint\halign{#3\cr
\setsafesecorchapno{\csname xchain[#1][#2]down\endcsname}\cr
\relax\ifacro
\pdflink{\csname xchain[#1][#2]down\endcsname}{\raise3.5pt\hbox{$\scriptscriptstyle\bigtriangledown$}}%
\else
\raise3.5pt\hbox{$\scriptscriptstyle\bigtriangledown$}%
\fi
\cr
}
}%
\dp0=0pt \box0}%
}
\def\setuplink#1#2#3{%
{\setbox0\vbox{
\sevenpoint\halign{#3\cr
\relax\ifacro
\pdflink{\csname xchain[#1][#2]up\endcsname}{\lower1.3pt\hbox{$\scriptscriptstyle\bigtriangleup$}}%
\else
\lower1.3pt\hbox{$\scriptscriptstyle\bigtriangleup$}%
\fi
\cr
\setsafesecorchapno{\csname xchain[#1][#2]up\endcsname}\cr
}
}%
\box0}%
}
% modify \makenote (used by \pdfnote) to use \noweb\ style references.
\def\makenote{%
\addtokens\toksB{\noexpand\pdflink{\the\toksC}{\setsafesecorchapno{\the\toksC}}}%
\toksC={}\global\countC=0
}
% redefine \pdflink; N.B.: the semantics of this command sequence have changed, since now
% #2 is not ignored (as it would have been if using pdftex); instead it becomes a typesetting
% template for the link
\ifpdftex
\ifx\pdfannotlink\undefined\let\pdfannotlink\pdfstartlink\fi% for pdfTeX 0.14
\def\pdflink#1#2{\hbox{\pdfannotlink height\ht\strutbox depth\dp\strutbox
attr{/Border [0 0 0]} goto num #1 \BlueGreen #2\Black\pdfendlink}}
\else\def\pdflink#1#2{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#2}%
\special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
depth \thedepth << /Type /Annot /Subtype /Link
/Border [0 0 0] /A << /S /GoTo /D (\romannumeral#1) >> >>}\box0\relax}\fi
% while typesetting the table of contents, show the actual section numbers
% TODO: introduce section accounting for book style typesetting.
\def\contentsline#1#2#3#4#5{\ifnum#2=0 \smallbreak\fi
\line{\consetup{#2}#1
\rm\leaders\hbox to .5em{.\hfil}\hfil
\ \ifacro\pdflink{#3}{#3}\else#3\fi\hbox to3em{\hss#4}}}
\newif\ifxreflocal % are we generating references in noweb style (as page no., position pairs)?
\newif\ifcsecactive
\defc\BBB#1#2#3#4{% #1 is the page number
% #2 is the section number
% #3, #4 are reserved
\csecactivetrue
}
\def\lxrcurrentpage{-1}
\newcount\lxrcurrentindex
\newcount\chaptercount
\lxrcurrentindex=\z@
% the command that processes the reference stream by setting
% chapter numbers, etc. based on the section number (which is
% unique across all sections); see also \BBB\ above
\defc\MNM#1#2#3#4{% #1 is the page number
% #2 is the section number
% #3 is the chapter flag or empty
% #4 is a possible custom reference
\ifnum#1=\lxrcurrentpage
\else
\lxrcurrentindex=\z@
\def\lxrcurrentpage{#1}%
\fi
{%
\tomodalpha\lxrcurrentindex\next
\def\nnext{\expandafter\noexpand\csname lxref[#2]\endcsname}%
\yystringempty{#3}{%
\let\nnnext\empty
\toksa{\advance\lxrcurrentindex\@ne}%
}{%
\ifnum#3=\z@
\toksa{\advance\chaptercount\@ne}%
\def\nnnext{\the\chaptercount}%
\else
\processcustomchapterref{#3}{#4}{\nnnext}%
\fi
}%
\edef\next{\def\nnext{{#1}{\next}{\nnnext}{#3}}\the\toksa}%
\expandafter
}\next
}
\def\xref@nowebsection#1{% translate the \CWEB\ section number into a \noweb\ reference
\expandafter\xr@f@nowebsection\romannumeral-1\csname lxref[#1]\endcsname.%
}
\def\xr@f@nowebsection#1#2#3#4.{%
{#1}{#2}%
}
\def\xref@chapter#1{% translate the \CWEB\ section number into a chapter number
\expandafter\xr@f@chapter\romannumeral-1\csname lxref[#1]\endcsname.%
}
\def\xr@f@chapter#1#2#3#4.{%
\yystringempty{#3}{{000}}{%
{#3}%
}%
}
\def\xref@sectionorchapter#1{% translate the \CWEB\ section number into a chapter number
% if the section begins a chapter or a \noweb\ section reference otherwise
\expandafter\xr@f@sectionorchapter\romannumeral-1\csname lxref[#1]\endcsname.%
}
\ifx\customchlabel\UNDEFINED
\def\customchlabel#1#2#3#4{%
ch#3%
}
\fi
\def\xr@f@sectionorchapter#1#2#3#4.{%
\yystringempty{#3}{{#1}{#1#2}}{%
{#1}{\customchlabel{#1}{#2}{#3}{#4}}%
}%
}
\def\setsafesecno#1{% extract the noweb style section reference from the \CWEB\ section index
% used to typeset marginal section references
\expandafter\ifx\csname lxref[#1]\endcsname\relax
#1%
\else
\expandafter\lmarginref\romannumeral-1\xref@nowebsection{#1}%
\fi
}
\def\lmarginref#1#2{{\sscmd\rm#1}\rlap{\sscmd\rm#2}\ }
\def\setsafesecorchapno#1{% if the section begins a chapter, extract the chapter reference,
% otherwise, extract the \noweb\ style reference
\expandafter\ifx\csname lxref[#1]\endcsname\relax
#1%
\else
\expandafter\eatone\romannumeral-1\xref@sectionorchapter{#1}%
\fi
}
\def\setsafechapno#1{% extract the chapter index
% used to typeset chapter headers
\expandafter\ifx\csname lxref[#1]\endcsname\relax
#1%
\else
\xref@chapter{#1}%
\fi
}
\def\tomodalpha#1#2{%
\tempca=#1
\let#2\empty
\bloop
\tempcb=\tempca
\divide\tempca by 26
\tempcc=\tempca
\multiply\tempcc by 26
\advance\tempcb by -\tempcc
\advance\tempcb by `\a
\uccode`\.=\tempcb
\uppercase{\edef#2{.#2}}%
\advance\tempca\m@ne
\ifnum\tempca<\z@
\else
\repeat
}
\defc\XXX#1#2#3{%
\ifcsecactive % previous command was \BBB (produced by the \B macro)
% \expandafter\def\csname lxref[][]\endcsname{}%
\csecactivefalse
\fi
}
% the next command takes advantage of the format for section references
% in the list of all sections: instead of a specific section number that
% points to the section where the given chunk of code started, the
% references contain ordered lists of all the section numbers that
% constitute the contents of the named section;
% this command should be placed in the main .w file before the list
% of all sections is included but after all the regular section references.
\def\lxrefseparator{%
\write\auxstream{\nx\SSS}%
}
% forming chain references to be used for navigation through a given named section
\defc\SSS{\let\XXX\xxxchain} % reference separator
\def\xxxchain#1#2#3{%
\xxxch@in{}{}#3, .%
}
\newif\iftracenowebchains
\def\xxxch@in#1#2#3, #4.{% #1 is the chain head
% #2 is the chain previous
% #3 is the chain next
% #4 is the remaining chain
\yystringempty{#1}{% start the chain
\yystringempty{#3}{%
\errmessage{The reference chain (#3) is malformed.}%
}{%
\xxxch@in{#3}{}#4, .%
}%
}{%
\yystringempty{#2}{% potentially the second link
\yystringempty{#3}{% this is a one link chain
}{% this is a second link
\expandafter\def\csname xchain[#1][#1]down\endcsname{#3}%
\expandafter\def\csname xchain[#3][#1]up\endcsname{#1}%
\iftracenowebchains\message{s(#1.->#3 #3->#1.)}\fi
\xxxch@in{#1}{#3}#4, .%
}%
}{% this is the middle or the end of the chain
\yystringempty{#3}{% this is the end of the chain
}{%
\expandafter\def\csname xchain[#3][#1]up\endcsname{#2}%
\expandafter\def\csname xchain[#2][#1]down\endcsname{#3}%
\iftracenowebchains\message{m(#1)(#2->#3 #3->#2)}\fi
\xxxch@in{#1}{#3}#4, .%
}%
}%
}%
}
% replace the default reference setting macros in gindex.sty;
% typeset references so that, for example, \(77){8, 9} becomes
% \(\compoundlink{77}{8c}), \(\pagelink{9}) provided section 77
% is section 8c by noweb's reckoning.
\def\consumeonexref#1#2{% #1 is the accumulated references
% #2 is the section number
\expandafter\ifx\csname lxref[#2]\endcsname\relax
\errmessage{Section #2 does not have a local index.}%
\else
\yybreak{\expandafter\c@nsumeonexref\romannumeral-1\xref@sectionorchapter{#2}{#2}{#1}}%
\yycontinue
}
\def\c@nsumeonexref#1#2#3#4#5{% #1 is the page number of the beginning of the section
% #2 is the (\noweb) section or chapter reference where the term appears
% #3 is the (\CWEB) section number there the term appears
% #4 is the accumulated references
% #5 is a list of pages where this term appears
\c@nsume@nexref{#1}{#2}{#3}{#4}{}#5, \end
}
\def\c@nsume@nexref#1#2#3#4#5#6, {% #1 is the page number of the beginning of the section
% #2 is the (\noweb) section or chapter reference where the term appears
% #3 is the (\CWEB) section number where the term appears
% #4 is a total list of processed references
% #5 is a local list of processed references
% #6 is a page number from the list
\ifnum#1=#6 % the term appears on the same page where the section begins
\yybreak{\c@nsume@nexr@f{#1}{#2}{#3}#4{#5}{\compoundlink{#3}{#2}}}%
\else
\yybreak{\c@nsume@nexr@f{#1}{#2}{#3}#4{#5}{\pagelink{#6}}}%
\yycontinue
}
\def\c@nsume@nexr@f#1#2#3#4#5#6#7#8{%
\c@nsume@n@xr@f{#1}{#2}{#3}{{#4}{#5}{#6}}{#7, #5#8#4}%
}
\def\c@nsume@n@xr@f#1#2#3#4#5#6\end{% no more page numbers
\yystringempty{#6}{%
\attachlocallist{#1}{#2}{#3}#4{#5}%
}{%
\c@nsume@nexref{#1}{#2}{#3}{#4}{#5}#6\end
}%
}
\def\attachlocallist#1#2#3#4#5#6#7{%
\grabfinexrefs{#6#7}%
}
\toyyunion{aux:global:xrefs}