% This is file cwebhmac.tex, part of the CWEBx distribution.

% This file can be loaded after cwebxmac.tex, in order to automatically
% insert \specials for use by the xhdvi previewer, or any other HyperTeX
% dvi-file processing tool. Current version is alpha release.

% Author: Marc van Leeuwen
% Last modified: 8 november 1996.

% The following macros are redefined
%   \stsec
%   \note<text><section list>.
%   \finnote<text><section list>.
%   \X<number>:<module name>\X

\ifx\hyperloaded\undefined \let\hyperloaded\relax \else \endinput\fi


% Low level interface to hyperlinks and targets

% \hyperanchor<attributes><anchor text>
% general mechanism to define <achor text> as anchor with <attributes>
\long\def\hyperanchor#1#2{\special{html:<A #1>}{#2}\special{html:</A>}}

% \hyperlink<URL><active text>
% makes <active text> an active link referring to <URL>
\def\hyperlink#1{\hyperanchor{href="#1"}}

% \hypertarget<tag><target text>
% defines a local target for hyperlinks, that can be referenced by <tag>
\def\hypertarget#1{\hyperanchor{name="#1"}}

% \hyperdef<kind><number><target text>
% defines a hypertarget classified by <kind> and sequence <number>
\def\hyperdef#1#2{\hypertarget{#1.#2}}

% \hyperref<assignments><kind><number><active text>
% creates a hyperlink to local target created by \hyperdef<kind><number>
% <assignments> are optional assignments for expansion of <kind> and <number>
{\catcode`\#=12 \gdef\sharp{#}} % to access neutralised '#' character
\def\hyperref#1#2#3%
{{#1\xdef\next{{\sharp#2.#3}}}\expandafter\hyperlink\next}


% High level interface attached to CWEAVE-produced macros (or to those
% accessed by them via the definition of cwebxmac.tex)

% Target attached to beginning of each section. <kind>=sec, <number>=\secno.
\def\stsec
 {\endcodemode\noindent
  \hyperdef{sec}\secno{\let\*=\lapstar\bf\secstar.}\quad
 }
\let\startsection=\stsec % this one is used; provides hook for extra actions

% List of links attached to end of some sections.
\def\note#1#2.%
{\Y\noindent{\hangindent2\indentunit\baselineskip10pt\eightrm
 #1~\hypersecrefs#2, .\par}}

% Same, but for references from the list of module names.
\def\finnote#1#2.{\quad{\eightrm#1~\hypersecrefs#2, .}}

% the following two are auxiliary macros that implement reference lists.

% \hypersecrefs<number>, <number>, ..., <number><ETcode><number>, .
% or \hypersecrefs<number>, .
% make list of hyperlinks to each of then mentioned sections
\def\hypersecrefs#1, #2.%
{\ifx|#2|\def\next{\finalsecrefs#1\ET\ET.#1\ETs\ETs}% final `.' follows below
 \else\hyperref{\let\*=\empty}{sec}{#1}{#1}, \let\next=\hypersecrefs
 \fi\next#2.%
}

% \finalsecref<n><ETcode><m>\ET\ET.<n><ETcode><m>\ETs\ETs.
% or \finalsecref<n>\ET\ET.<n>\ETs\ETs.
\def\finalsecrefs#1\ET#2\ET#3.#4\ETs#5\ETs#6.%
{\ifx|#2#5|\hyperref{\let\*=\empty}{sec}{#1}{#1}% just 1 reference
 \else % <n>\ET<m> or <n>\ETs<m>
    \edef\next{\ifx|#5|#1\else#4\fi}% <n>
    \toks0={\let\*=\empty}%
    \edef\next{{\the\toks0}{sec}{\next}{\next}}%
    \expandafter\hyperref\next% link to sec.<n> with text <n>
    #3#6% one is empty, the other is \ET or \ETs, as appropriate
    \hyperref{\let\*=\empty}{sec}{#2#5}{#2#5}% similar trick, link to sec.<m>
 \fi
}

% we must change \ATP slightly, so that \X can recognise it and avoid a link
\def\ATP{\X\ATP\kern-.5em:Preprocessor directives\X}

\def\X#1:#2\X % module name
{\langle\,${#2\eightrm\enspace\ifx\ATP#1\else\hypersecrefs#1, .\fi}$\,\rangle}

{\catcode`_=12 \gdef\usplain{\def\_{_}}}

\let\plainCident=\Cident

\def\Cident#1{\def\idstart{#1}\futurelet\next\testid}
\let\\=\Cident % cwebx only; a \hbox would prevent us from seeing "subscript"

\def\testid
{\ifx_\next
   \def\next_##1%
    {\hyperref\usplain{id}{\idstart##1}{\plainCident\idstart_{##1}}}%
 \else \hyperref\usplain{id}\idstart{\plainCident\idstart}%
   \let\next=\empty
 \fi\next
}

\def\indextestid
{\ifx_\next
   \def\next_##1%
    {{\usplain\xdef\next{{id}{\idstart##1}}}%
     \expandafter\hyperdef\next{\plainCident\idstart_{##1}}%
    }%
 \else
   {\usplain\xdef\next{{id}{\idstart}}}%
   \expandafter\hyperdef\next{\plainCident\idstart}%
   \let\next=\empty
 \fi\next
}

{\let \inxentry=\relax % remove \outer-ness
 \toks0=\expandafter{\inx \let\testid=\indextestid}\xdef\inx{\the\toks0 }
}

\outer\def\inxentry#1#2, #3.% #1 is `h' or `m' for horiz/math mode
 {\par\hangindent2em\noindent
  \if#1m$#2$\else#2\relax\fi % \relax avoids fatal \next=\fi in \indextestid
  :\kern1em\indexrefs#3, .%
 }

\def\indexrefs#1, #2.%
{\hyperref{\let\*=\empty\def\[##1]{##1}}{sec}{#1}{#1}%
 \ifx|#2|\let\next=\empty\else, \let\next=\indexrefs\fi\next#2.%
}

\def\contentsline#1#2#3#4% #1=depth, #2=title, #3=secno, #4=pageno
 {\line{\hyperref{}{sec}{#3}{\ignorespaces#2}
        \leaders\hbox to .5em{.\hfil}\hfil
        \ \hyperref{}{sec}{#3}{#3 \hbox to3em{\hss#4}}%
       }%
 }
