% 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}