%D \module
%D   [       file=m-cweb,
%D        version=1997.01.15,
%D          title=\CONTEXT\ Extra Modules,
%D       subtitle=\CWEB\ Pretty Printing Macros,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D This module has to be redone in the mkiv way and I do that stepwise so the
%D current code is not okay.

% todo:
%
% \deactivateCWEB in output routine
% status info
% linked entries
% parskip en parindent
% breaks and whitespace
% fonts ... now math abuse down here

%D \gdef\CWEBquote#1.{{\em Quote :}\ #1.} % checks the .
%D
%D This module (re)implements the \CWEB\ macros as defined in the file \type
%D {cwebmac.tex}. \CWEB\ uses short, often one character long, names for macros.
%D This is no real problem because no one is supposed to read and understand the
%D files generated by \CWEB. The standard macros are meant for \PLAIN\ \TEX\ users.
%D In \CONTEXT\ and other macro packages however, there is a potential conflict with
%D format specific or user defined commands. Furthermore, the \CWEB\ macros
%D implement their own output routines. When integrating \CWEB\ documents in another
%D environment, the \CWEB\ specific macros have to be made local. The first part of
%D this module is dedicated to this feature.
%D
%D Instead of using \type {\def} and \type {\let} for defining macros, we use:
%D
%D \starttyping
%D \defCEBmacro arguments {meaning}
%D \letCEBmacro arguments {meaning}
%D \stoptyping
%D
%D \CWEB\ files contain implicit calls to macros that generate the table of contents,
%D the lists of sections and the index. Because we want to be much more flexible, we
%D implemented our own alternatives, and therefore have to bypass the original ones.
%D The next macro is used for defining these obsolete \CWEB\ macros. The dummies
%D take care of arguments.
%D
%D \starttyping
%D \defCEBdummy arguments {meaning}
%D \stoptyping
%D
%D The list of \CWEB\ specific macro names is saved in a \TOKENLIST. This serves two
%D purposes. First it enables us to activate the \CWEB\ macros, which are saved
%D under a different name, second it can be used to temporary restore the meanings,
%D for instance when the output routine builds the page.
%D
%D We don't provide specific formatting commands. We just assume \CONTEXT\ being
%D used (so you can use all it provides) and|/|or that specific user macros are
%D implemented somewhere else.

\unprotect

\newtoks\CWEBmacros

%D Activating and deactivating is done by means of:
%D
%D \starttyping
%D \activateCWEB
%D \deactivateCWEB
%D \stoptyping
%D
%D These are implemented as:

\unexpanded\def\activateCWEB
  {\let\doCWEB\activateCWEBmacro
   \the\CWEBmacros}

\unexpanded\def\deactivateCWEB
  {\let\doCWEB\deactivateCWEBmacro
   \the\CWEBmacros}

%D The three definition macros append the name of the macro to the list. The first
%D two macros save the meaning, the last one assigns \type {{}} to the macro and
%D gobbles original meaning.

\installcorenamespace{newCWEB}
\installcorenamespace{oldCWEB}

\unexpanded\def\defCWEBmacro#1%
  {\appendtoks\doCWEB#1\to\CWEBmacros
   \setuvalue{\??newCWEB\string#1}}

\unexpanded\def\letCWEBmacro#1%
  {\appendtoks\doCWEB#1\to\CWEBmacros
   \letvalue{\??newCWEB\string#1}}

\unexpanded\def\defCWEBdummy#1#2#%
  {\appendtoks\doCWEB#1\to\CWEBmacros
   \setuvalue{\??newCWEB\string#1}#2{}%
   \gobbleoneargument}

%D The macro \type {\defCWEBdummy} of course takes care of the argument. This leaves
%D the two (de|)|activating macros:

\unexpanded\def\CWEBmacro#1%
  {\getvalue{\??newCWEB\string#1}}

\unexpanded\def\activateCWEBmacro#1%
  {\letvalue{\??oldCWEB\string#1}=#1%
   \unexpanded\def#1{\CWEBmacro#1}}

\unexpanded\def\deactivateCWEBmacro#1%
  {\expandafter\let\expandafter#1\csname\??oldCWEB\string#1\endcsname}

\protect

%D I did consider loading the \CWEB\ macros using temporary substitutes of \type
%D {\def}, \type {\font}, \type {\newbox} etc. The main problem is that the file
%D contains more than definitions and taking all kind of assignments into account
%D too would not make things easier. So I decided to stick to the method as just
%D described.
%D
%D Now we're ready for the real job. What follows is a partial adaption of the file
%D \type {cwebmac.tex}, version 3.1, dated September 1994 and written by Levy and
%D Knuth. When possible we kept the original meaning, but we've granted ourselves
%D the freedom to reformat the macro's for readibility.
%D
%D We'll only present the macros we actually use. The source however contains the
%D original implementation.
%D
%D The next is based on the standard macros for CWEB listings (in addition to \type
%D {plain.tex}) Version 3.1 --- September 1994.

%D \macros{.}
%D
%D \CWEBquote preserve a way to get the dot accent (all other accents will still
%D work as usual).

\letCWEBmacro\: = \.

%D \macros{CEE,UNIX,TEX,CPLUSPLUS}
%D
%D Next come some logo's. It does not make much sense to use the \CONTEXT\ logo
%D mechanism here, so we simply say:

\defCWEBmacro      \CEE/{{\tx C\spacefactor1000}}
\defCWEBmacro     \UNIX/{{\tx UNIX\spacefactor1000}}
\defCWEBmacro      \TEX/{\TeX}
\defCWEBmacro\CPLUSPLUS/{{\tx C\PP\spacefactor1000}}
\defCWEBmacro       \Cee{\CEE/} % for backward compatibility

%D \macros{\ }
%D
%D Now we come to the real work: the short commands that make up the typography.
%D
%D \CWEBquote italic type for identifiers.

\defCWEBmacro\\#1%
  {\dontleavehmode
   \hbox{\it#1\/\kern.05em}}

%D \macros{\string|}
%D
%D \CWEBquote one letter identifiers look better this way.

\defCWEBmacro\|#1%
  {\dontleavehmode
   \hbox{$#1$}}

%D \macros{\string\&}
%D
%D \CWEBquote boldface type for reserved words.

\defCWEBmacro\&#1%
  {\dontleavehmode
   \hbox{\bf#1\/\kern.05em}}

%D \macros{.}
%D
%D Here we use the previously saved period. This macro takes care of special
%D characters in strings.

\defCWEBmacro\.#1%
  {\dontleavehmode
   \hbox
     {\tttf      % typewriter type for strings
      \let\\=\BS % backslash in a string
      \let\{=\LB % left brace in a string
      \let\}=\RB % right brace in a string
      \let\~=\TL % tilde in a string
      \let\ =\SP % space in a string
      \let\_=\UL % underline in a string
      \let\&=\AM % ampersand in a string
      \let\^=\CF % circumflex in a string
      #1\kern.05em}}

%D \macros{)}
%D
%D Some discretionary hack.

\defCWEBmacro\)%
  {\discretionary{\hbox{\tttf\BS}}{}{}}

%D \macros{AT}
%D
%D \CWEBquote at sign for control text (not needed in versions $>=$ 2.9).

\defCWEBmacro\AT{@}

%D \macros{ATL,postATL,NOATL}
%D
%D A two step macro that handles whatever.

\defCWEBmacro\ATL
  {\par
   \noindent
   \bgroup
   \catcode`\_=12
   \postATL}

\defCWEBmacro\postATL#1 #2 %
  {\bf letter \\{\WORD{\char"#1}} tangles as \tttf \quotation{#2}%
   \egroup
   \par}

\defCWEBmacro\noATL#1 #2 %
  {}

%D \macros{noatl}
%D
%D \CWEBquote suppress output from \type {@l}.

\defCWEBmacro\noatl
  {\let\ATL\noATL}

% \defCWEBmacro\ATH%
%   {\X\kern-.5em:Preprocessor definitions\X}

%D \macros{PB}
%D
%D \CWEBquote hook for program brackets {\tttf\string|...\string|} in \TEX\ part or
%D section name.

\defCWEBmacro\PB
  {\relax}

\letCWEBmacro\AM \letterampersand  % ampersand character in a string
\letCWEBmacro\BS \letterbackslash  % backslash in a string
\letCWEBmacro\LB \letterleftbrace  % left brace in a string
\letCWEBmacro\RB \letterrightbrace % right brace in a string
\letCWEBmacro\TL \lettertilde      % tilde in a string
\letCWEBmacro\UL \letterunderscore % underline character in a string
\letCWEBmacro\CF \letterhat        % circumflex character in a string
\letCWEBmacro\SP \textvisiblespace % (visible) space in a string

%D We're in mathmode, otherwise we could have:
%D
%D \starttyping
%D \defCWEBmacro\PP{\raise.15em\hbox{\tx\textplus \kern-.05em\textplus }}
%D \defCWEBmacro\MM{\raise.15em\hbox{\tx\textminus\kern .10em\textminus}}
%D \defCWEBmacro\MG{\raise.15em\hbox{\rightarrow}}
%D \stoptyping

\defCWEBmacro\PP % symbol for ++
  {\kern.05em
   \raise.1em\hbox{$\scriptstyle+\kern-.1em+$}%
   \kern.05em}

\defCWEBmacro\MM % symbol for --
  {\kern.05em
   \raise.1em\hbox{$\scriptstyle-\kern-.1em-$}%
   \kern.05em}

\defCWEBmacro\MG
  {\kern-.2em
   \lower.3em\hbox{$\rightarrow$}%
   \kern .1em}

\defCWEBmacro\MRL#1%
  {\mathrel{\let\K==#1}}

% \def\MRL  #1{\KK#1}
% \def\KK #1#2{\buildrel\;#1\over{#2}}

\letCWEBmacro\GG   = \gg
\letCWEBmacro\LL   = \ll
\letCWEBmacro\NULL = \Lambda

\letCWEBmacro\AND  = \mathampersand  % bitwise and; also \& (unary operator)

\letCWEBmacro\OR   = \mid                     % bitwise or
\letCWEBmacro\XOR  = \oplus                   % bitwise exclusive or
\defCWEBmacro\CM     {{\sim}}                 % bitwise complement
\defCWEBmacro\MOD    {\mathbin{\tx\%}}
\defCWEBmacro\DC     {\kern.1em{::}\kern.1em} % symbol for ::
\defCWEBmacro\PA     {\mathbin{.*}}           % symbol for .*
\defCWEBmacro\MGA    {\mathbin{\MG*}}         % symbol for ->*
\defCWEBmacro\this   {\&{this}}

\newcount\CWEBind  % current indentation in ems

\defCWEBmacro\1%     indent one more notch
  {\global\advance\CWEBind \plusone
   \hangindent\CWEBind \emwidth}

\defCWEBmacro\2%     indent one less notch
  {\global\advance\CWEBind \minusone}

\defCWEBmacro\3#1%   optional break within a statement
  {\hfil
   \penalty#10\relax
   \hfilneg}

\defCWEBmacro\4%   backspace one notch
  {\hpack to -1em{}}

\defCWEBmacro\5%   optional break
  {\hfil
   \penalty\minusone
   \hfilneg
   \kern2.5em
   \hpack to -2em{}%
   \ignorespaces}

\defCWEBmacro\6%   forced break
   {\ifmmode \else
      \par
      \hangindent\CWEBind em
      \noindent
      \kern\CWEBind em
      \hpack to -2em{}%
      \ignorespaces
    \fi}

\defCWEBmacro\7%   forced break and a little extra space
  {\Y
   \6}

\defCWEBmacro\8%   no indentation
  {\hskip-\CWEBind em
   \hskip 2em}

\defCWEBmacro\9#1%
  {}

\newcount\CWEBgdepth  % depth of current major group, plus one
\newcount\CWEBsecpagedepth

\CWEBsecpagedepth=3   % page breaks will occur for depths -1, 0, and 1

\defCWEBmacro\?%
  {\mathrel?}

\defCWEBmacro\lapstar
  {\rlap{*}}

\defCWEBmacro\defin#1%
  {\global\advance\CWEBind by 2 \1\&{#1 } } % begin `define' or `format'

\defCWEBmacro\B%
 {\rightskip=0pt plus 100pt minus 10pt % go into C mode
  \sfcode`;=3000
  \pretolerance 10000
  \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted)
  \exhyphenpenalty 10000
  \global\CWEBind=2 \1\ \unskip}

\defCWEBmacro\C#1%
  {\5\5\quad$/\ast\,${\ss\detokenize{#1}}$\,\ast/$}

\defCWEBmacro\SHC#1%
  {\5\5\quad$//\,${\ss#1}}

\defCWEBmacro\D% macro definition
  {\defin{\#define}}

\letCWEBmacro\E=\equiv % equivalence sign

% \def\ET% conjunction between two section numbers
%   { and~}
%
% \def\ETs% conjunction between the last two of several section numbers
%   {, and~}

\defCWEBmacro\F% format definition
  {\defin{format}}

\letCWEBmacro\G = \ge % greater than or equal sign

% \H is long Hungarian umlaut accent

\letCWEBmacro\I = \ne % unequal sign

\defCWEBmacro\J% TANGLE's join operation
  {\.{@\&}}

\letCWEBmacro\K = \leftarrow % "honest" alternative to standard assignment operator

% \L is Polish letter suppressed-L
% \O is Scandinavian letter O-with-slash
% \P is paragraph sign

\defCWEBmacro\Q  {\note{This code is cited in section}}  % xref for mention of a section
\defCWEBmacro\Qs {\note{This code is cited in sections}} % xref for mentions of a section

% \S is section sign

\defCWEBmacro\T#1%
  {\dontleavehmode % octal, hex or decimal constant
   \hbox
     {$\def\?{\kern.2em}%
      \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant
      \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
      \let\~=\oct
      \let\^=\hex
      {#1}$}}

\defCWEBmacro\U  {\note{This code is used in section}} % xref for use of a section
\defCWEBmacro\Us {\note{This code is used in sections}} % xref for uses of a section

\letCWEBmacro\R  = \lnot % logical not
\letCWEBmacro\V  = \lor  % logical or
\letCWEBmacro\W  = \land % logical and

\unprotect

\def\theCWEByskip {\blank[\v!small]}
\def\theCWEBvskip {\blank[\v!big]}

\protect

\defCWEBmacro\Y%
  {\par
   \yskip}

\defCWEBmacro\yskip
  {\theCWEByskip}

\letCWEBmacro\Z  = \le
\letCWEBmacro\ZZ = \relax
\letCWEBmacro\*  = *

\defCWEBmacro\oct
  {\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}

\defCWEBmacro\hex
  {\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}}

\defCWEBmacro\vb#1%
  {\dontleavehmode
   \hbox
     {\kern.2em
      \vrule
      \vtop
        {\vbox
           {\hrule
            \hbox{\strut\kern.2em\.{#1}\kern.2em}}
         \hrule}%
      \vrule
      \kern.2em}} % verbatim string

\def\onmaybe
  {\let\ifon=\maybe}

\let\maybe=\iftrue

\newif\ifon

\def\botofcontents
  {\vfill
   \centerline{\covernote}} % this material will end the table of contents page

\def\covernote
  {}

% some leftover

\defCWEBmacro\contentspagenumber{0} % default page number for table of contents

\defCWEBdummy\magnify#1%  magnify the page
  {}

\defCWEBmacro\ch
  {\note{The following sections were changed by the change file:}
   \let\*=\relax}

\defCWEBmacro\consetup#1%
  {\ifcase#1 \bf        % depth -1 (@**)
   \or                  % depth  0 (@*)
   \or       \hskip 2em % depth  1 (@*1)
   \or       \hskip 4em % depth  2 (@*2)
   \or       \hskip 6em % depth  3 (@*3)
   \or       \hskip 8em % depth  4 (@*4)
   \or       \hskip10em % depth  5 (@*5)
   \else     \hskip12em
   \fi}                 % depth  6 or more

\defCWEBdummy \inx    {} % index
\defCWEBdummy \fin    {} % finish
\defCWEBdummy \con    {} % table of contents and finish

\defCWEBdummy \noinx  {} % no indexes or table of contents
\defCWEBdummy \nosecs {} % no index of section names or table of contents
\defCWEBdummy \nocon  {} % no table of contents

\defCWEBmacro\,%
  {\relax
   \ifmmode
     \mskip\thinmuskip
   \else
     \thinspace
   \fi}

\defCWEBdummy\datethis         {} % say `\datethis' in limbo, to get your listing timestamped before section 1
\defCWEBdummy\datecontentspage {} % timestamps the contents page

\defCWEBmacro\TeX
  {{\ifmmode\it\fi
    \dontleavehmode
    \hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}

% alternative implementation

\newif\ifCWEBnotes

\defCWEBmacro\Q   {\CWEBnotesfalse \note{This code is cited in section}}  % xref for mention of a section
\defCWEBmacro\Qs  {\CWEBnotestrue  \note{This code is cited in sections}} % xref for mentions of a section

\defCWEBmacro\U   {\CWEBnotesfalse \note{This code is used in section}}  % xref for use of a section
\defCWEBmacro\Us  {\CWEBnotestrue  \note{This code is used in sections}} % xref for uses of a section

\defCWEBmacro\A   {\CWEBnotesfalse \note{See also section}}  % xref for doubly defined section name
\defCWEBmacro\As  {\CWEBnotestrue  \note{See also sections}} % xref for multiply defined section name

\defCWEBmacro\ET  { and~}  % conjunction between two section numbers
\defCWEBmacro\ETs {, and~} % conjunction between the last two of several section numbers

\def\processCWEBsectionnumber#1%
  {\bgroup
   \def\[##1]{##1}%
   \xdef\CWEBreference{#1}%
   \egroup
   \CWEBcomma{\goto{#1}[web:\CWEBreference]}}

\unexpanded\def\processCWEBsectionnumbers[#1]%
  {\bgroup
   \def\CWEBcomma{\def\CWEBcomma{, }}%
   \processlist(),\processCWEBsectionnumber(#1)%
   \egroup}

\unexpanded\def\processCWEBsectionnotes
  {\catcode`\s=12
   \doprocessCWEBsectionnotes}

\def\doprocessCWEBsectionnote#1\ET#2#3.%
  {\processCWEBsectionnumbers[#1]%
   \if#2s%
     {, and~\goto{##3}[web:#3]}%
   \else
     { and~\goto{##2##3}[web:#2#3]}%
   \fi}%

\unexpanded\def\doprocessCWEBsectionnotes#1.%
  {\ifCWEBnotes
     \doprocessCWEBsectionnote#1.%
   \else
     \goto{#1}[web:#1]%
   \fi
   \afterCWEBnote % inside group!
   \egroup}

\let\afterCWEBnote\relax

\defCWEBmacro\note#1%
  {\bgroup
   \Y\noindent
   \def\afterCWEBnote{\par}%
   \hangindent2em
   %\baselineskip10pt
   \tx#1~\processCWEBsectionnotes}

\unexpanded\def\oldCWEBmacroX#1:#2\X% original
  {\ifmmode
     \gdef\XX{\null$\null}%
   \else
     \glet\XX\empty
   \fi % section name
   \XX$\langle\,${#2\tx\kern.5em#1}$\,\rangle$\XX}

\defCWEBmacro\ATH
  {\oldCWEBmacroX\kern-.5em:Preprocessor definitions\X}

\unexpanded\def\newCWEBmacroX#1:#2\X% original
  {\ifmmode
     \gdef\XX{\null$\null}%
   \else
     \glet\XX\empty
   \fi % section name
   \XX$\langle\,$%
   {#2\tx\kern.5em\processCWEBsectionnumbers[{#1}]}%
   $\,\rangle$\XX}

\defCWEBmacro\X#1:#2\X%
  {\newCWEBmacroX#1:#2\X}

%D The next code is a bit messy because there is skipping over content
%D and we have \type {\fi}'s in the source.

\let\CWEBsecno\empty

\definelist[cweb]

\defCWEBmacro\startsection
  {\rightskip=0pt % get out of C mode (cf. \B)
   \sfcode`;=1500
   \pretolerance 200
   \hyphenpenalty 50
   \exhyphenpenalty 50
   \noindent
   \bgroup
   \let\*=\lapstar
   \gotoCWEBsection{\bf\CWEBsecstar.\quad}[\CWEBsecno]%
   \egroup}

\defCWEBmacro\MN#1%
  {\par % common code for \M, \N
   \begingroup
     \xdef\CWEBsecstar{#1}%
     \let\*=\empty
     \xdef\CWEBsecno{#1}% remove \* from section name
   \endgroup
   \ifx\CWEBsecno\CWEBsecstar
     \onmaybe
   \else
     \ontrue
   \fi}

\defCWEBmacro\M#1%
  {\MN{#1}%
   \ifon
     \vfil
     \penalty-100
     \vfilneg % beginning of section
     \theCWEBvskip
     \startsection
     \pagereference[web:#1]%
     \expanded{\marking[CWEBsectionnumber]{\secno}}%
     \expanded{\marking[CWEBsectiondepth]{\the\CWEBgdepth}}%
     \ignorespaces}

\defCWEBmacro\N#1#2#3.%
  {\CWEBgdepth=#1%
   \MN{#2}% beginning of starred section
   \ifon
     \ifnum#1<\CWEBsecpagedepth
       \page
     \else
       \vfil
       \penalty-100
       \vfilneg
       \theCWEBvskip
     \fi
   \fi
   \writedatatolist[cweb][section=\CWEBsecno,title={#3},depth=#1]%
   \ifon
     \startsection
     \pagereference[web:#2]%
     \marking[CWEBsectiontitle] {#3}%
     \expanded{\marking[CWEBsectionnumber]{\CWEBsecno}}%
     \expanded{\marking[CWEBsectiondepth]{\the\CWEBgdepth}}%
     {\bf#3.\quad}%
     \ignorespaces}

\newif\iflinktoCWEBfile

\def\setCWEBlinkfile#1%
  {\linktoCWEBfiletrue
   \def\otherCWEBfile{#1}}

\unprotect

\unexpanded\def\gotoCWEBsection#1[#2]%
  {\iflinktoCWEBfile
     \bgroup
       \setupinteraction[\c!color=,\c!style=]%
       \let\savedreferenceprefix=\referenceprefix
       \goto{#1}[\otherCWEBfile::\savedreferenceprefix web:#2]%
     \egroup
   \else
     #1%
   \fi}

\protect

\unexpanded\def\ignoreCWEBinput
  {\def\input ##1 {\let\input\normalinput}}

\unexpanded\def\loadCWEBmacros#1%
  {\let\oldN=\N
   \def\N{\bgroup\setbox0=\vbox\bgroup\endinput}%
   \ignoreCWEBinput
   \ReadFile{#1.tex}%
   \egroup\egroup
   \let\N=\oldN}

\unexpanded\def\resetCWEBcontext
  {\catcode`\|=\othercatcode % used in context discretionaries
   \everypar   \emptytoks    % used for context indentation and floats
   \parskip    \zeropoint    % no stretch between cweb paragraphs
   \parindent  \emwidth}     % is related to cweb backspace etc

\unexpanded\def\processCWEBsource #1 %
  {\bgroup
   \resetCWEBcontext
   \activateCWEB
   \ignoreCWEBinput
   \let\end\relax
   \marking[CWEBfilename]{#1}
   \ReadFile{#1.tex}\relax
   \par
   \egroup}

\unexpanded\def\resetCWEBindexentry
  {\xdef\currentCWEBindexentry{}}

\unexpanded\def\showCWEBindexentry#1% can be redefined
  {\theCWEBvskip
   \vskip3\lineheight
   \goodbreak
   \vskip-3\lineheight
   {\pagereference[web:#1]\bf#1}%
   \theCWEBvskip}


    \def\dodofindfirstcharacter#1%
      {\ifx#1\relax
         \let\next=\egroup
       \else
         \handlecase
           {\expandafter\ifnum\expandafter\catcode\expandafter`#1=11
            \def\next##1\relax{\egroup\def\firstcharacter{#1}}%
         \fi}%
       \fi
       \next}

    \def\dofindfirstcharacter#1#2%
      {\def\firstcharacter{}%
       \bgroup
       \defconvertedargument\ascii{#2}%
       \let\next\dodofindfirstcharacter
       \let\handlecase#1%
       \expandafter\next\ascii\relax}

    \def\FINDFIRSTCHARACTER
      {\dofindfirstcharacter\uppercase}



\unexpanded\def\checkCWEBindexentry#1%
  {\bgroup
   \def\\##1{##1}%  a dummy that also removes the {}
   \def\|##1{##1}%  another dummy
   \def\.##1{*##1}% and another (the typewriter one)
   \def\&##1{##1}%  and a last one
   \def\9##1{##1}%  hold this one
   \catcode`*=11
   \expandafter\def\expandafter\entry\expandafter{#1}%
   \defconvertedcommand\ascii\entry
   \expanded{\FINDFIRSTCHARACTER{\ascii}}%
   \doifnot{\currentCWEBindexentry}{\firstcharacter}
     {\doifnot{\firstcharacter}{*} % signal for \firstbunch
        {\global\let\currentCWEBindexentry=\firstcharacter
         \showCWEBindexentry{\currentCWEBindexentry}}}%
   \egroup}

\unexpanded\def\theCWEBbeforeindex {\startcolumns}
\unexpanded\def\theCWEBafterindex  {\stopcolumns}

\unexpanded\def\processCWEBindex #1 %
  {\par
   \bgroup
   \forgetall
   \setupalign[verytolerant,flushleft,nothyphenated]
   \resetCWEBcontext
   \activateCWEB
   \resetCWEBindexentry
   \def\I##1, %
     {\par
      \checkCWEBindexentry{##1}%
      \hangindent2em
      \noindent##1:\kern1em%
      \def\next####1.{\processCWEBsectionnumbers[{####1}]}%
      \next}%
   \def\[##1]%
     {$\underline{##1}$}%
   \let\*=\lapstar
   \marking[CWEBfilename]{#1}
   \marking[CWEBsectiontitle]{index}
   \marking[CWEBsectionnumber]{}
   \marking[CWEBsectiondepth]{}
%    \loadCWEBmacros{#1}
   \theCWEBbeforeindex
   \ReadFile{#1.idx}\relax
   \theCWEBafterindex
   \par
   \egroup}

\unexpanded\def\processCWEBsections #1 %
  {\par
   \bgroup
   \forgetall
   \resetCWEBcontext
   \activateCWEB
 % \loadCWEBmacros{#1}
   \parfillskip = 0pt plus 1fil
   \parindent   = 0pt
   \let\topsecno=\nullsec
   \def\note##1%
     {\quad
      \bgroup
      \tx
      ##1~\processCWEBsectionnotes}
   \def\Q {\CWEBnotesfalse \note{Cited in section}}  % crossref for mention of a section
   \def\Qs{\CWEBnotestrue  \note{Cited in sections}} % crossref for mentions of a section
   \def\U {\CWEBnotesfalse \note{Used in section}}   % crossref for use of a section
   \def\Us{\CWEBnotestrue  \note{Used in sections}}  % crossref for uses of a section
   \def\I {\par\hangindent 2em}%
   \let\*=*
   \marking[CWEBfilename]{#1}
   \marking[CWEBsectiontitle]{sections}
   \marking[CWEBsectionnumber]{}
   \marking[CWEBsectiondepth]{}
%    \loadCWEBmacros{#1}
   \ReadFile{#1.scn}\relax
   \botofcontents
   \par
   \egroup}

\unexpanded\def\processCWEBcontents #1 %
  {\par
   \bgroup
   \forgetall
   \resetCWEBcontext
   \activateCWEB
   \marking[CWEBfilename]{#1}
   \marking[CWEBsectiontitle]{table of contents}
   \marking[CWEBsectionnumber]{}
   \marking[CWEBsectiondepth]{}
   \forgetall
   \placelist[cweb][criterium=all,command=\CWEBlistentry]
   \par
   \egroup}

% {all}
%
% \structurelistuservariable
% \rawstructurelistuservariable
%
% \goto{#3}[web:#3]

\installstructurelistprocessor{cweb}
  {\begingroup
   \advance\leftskip 3em
   \advance\rightskip3em
   \currentlistentrydestinationattribute
   \dontleavehmode
   \llap{\hbox \currentlistentryreferenceattribute{number} to 3em{\structurelistuservariable{section}\hss}}%
   \structurelistuservariable{title}%
   \hfill
   \rlap{\hbox \currentlistentryreferenceattribute{page}   to 3em{\hss\structurelistuservariable{depth}}}%
   \par
   \endgroup}

\endinput
