%% $Id: cwebzw.sty,v 1.2 1993/08/10 14:14:33 schrod Exp $
%%----------------------------------------------------------------------
%% Changed by Joachim Schrod <schrod@iti.informatik.th-darmstadt.de>
%% Original received by mail:
%%	Date:         Thu, 05 Aug 93 12:34:21 MDT
%% 	From: Zdenek Wagner <WAGNER@CSEARN.BITNET>

%% This is file ``cwebzw.sty'' written by Z. Wagner as an extension and
%% correction of ``cweb.sty'' Revision 1.8

%% This file is self-documenting. If you process this file through LaTeX,
%% you will get the documentation. You can use MakeIndex to create an
%% index of macros used. In your cweb documents you can either use it as
%% is or you can remove all comment lines by your editor or the docstrip
%% utility (or a program of your own).

%% See chapter ``Introduction'' for other remarks.

\def\cwebzwrevision{1.8} % Do not remove this line!

% You can remove the next two lines
\ifcat a\noexpand @\let\next\relax\else\def\next{%
  \documentstyle[doc]{article}\MakePercentIgnore}\fi\next

% \EnableCrossrefs
% \CodelineIndex
% \catcode`\_=12
% \DoNotIndex{\cweb,\orig,\p} ^^A doc.sty cannot handle underscore
% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ }
% \DoNotIndex{\@ne,\tw@,\bgroup,\egroup,\endinput,\end,\kern,\hbox,\vbox,\vtop}
% \DoNotIndex{\aftergroup,\arabic,\begin,\protect,\rm,\reset@font,\setbox}
% \DoNotIndex{\show,\typeout,\errhelp,\unskip,\unvbox,\wd,\input,\hskip}
% \DoNotIndex{\ifdim,\ifmmode,\ifnum,\long,\footnotesize,\newbox,\newpage}
% \DoNotIndex{\@ifnextchar,\@ifundefined,\@namedef}
% \DoNotIndex{\advance,\begingroup,\catcode,\closein,\closeout}
% \DoNotIndex{\day,\def,\edef,\else,\empty,\endgroup,\errmessage}
% \DoNotIndex{\expandafter,\fi,\futurelet,\gdef,\global,\if,\ifeof}
% \DoNotIndex{\ifx,\immediate,\let,\loop,\m@ne,\message,\month,\newcount}
% \DoNotIndex{\newif,\newlinechar,\newread,\newtoks,\newwrite}
% \DoNotIndex{\noexpand,\openin,\openout,\par,\read,\relax,\repeat}
% \DoNotIndex{\space,\the,\undefined,\write,\xdef,\year,\z@}
% \advance\textwidth by 40pt
% \def\pcws{{\tt cweb.sty}}
% \def\cws{\protect\pcws}
% \newbox\cwebincr
% \setbox\cwebincr=\hbox{^^A
% \kern .5pt
% \raise .1em\hbox{$\scriptstyle{+}\kern -.1em{+}$}^^A
% \kern .5pt}
% \def\Cpp{C\copy\cwebincr}
% \begin{document}
% \MakeShortVerb\|
% \title{Extension and correction of \cws\ revision~\cwebzwrevision}
% \author{Zden\v{e}k Wagner\\
% $\langle$wagner@csearn.bitnet$\rangle$ or
% $\langle$wagner@earn.cvut.cz$\rangle$}\date{}
% \maketitle\vspace{3ex}

% \tableofcontents\thispagestyle{empty}\newpage

% \section{Introduction}
% The purpose of this file is to add new features to \cws\ and
% correct some bugs. When doing this we intended not to make a faintest
% change into \cws. Therefore some definitions may look strangely
% cumbersome. However, this file should be treated as a test of new
% features and bug fixes which should then be placed in the official
% distribution of \cws\ and in the ideal state this file will one day
% vanish at all.

% {\bf Note by Joachim Schrod}:\quad I have incorporated most error
% repairs and some of the enhancements into \cws{} (Revision~1.12). To
% avoid problems, I deleted all the respective macros from this
% option.  The rest that you see here will not be incorporated (at
% least not as-is) and is therefore provided as a contributed style
% option for those who like it.


% \section{Preliminaries}
% First we make sure that this file is not input twice.
%    \begin{macrocode}
\@ifundefined{\cweb@egroup}{}{\endinput}
%    \end{macrocode}

% Throughout this file we will use tags defined in \cws. Therefore we
% begin the file with identifying itself and displaying the revision of
% \cws\ for which it is written. Afterwards we change catcode of
% underscore in order to have the same conditions as \cws.
%    \begin{macrocode}
\typeout{Extension of cweb style, revision \cwebzwrevision}
\typeout{(if you have an older revision of cweb.sty, please upgrade)}
\catcode`\_=\CatLetter
%    \end{macrocode}

% \section{Extensions}
% \begin{macro}{\C++}
% \begin{macro}{\Cpp}
% \begin{macro}{\CPLUSPLUS/}
% The documentation of \cws\ says that |\C++| may now be used for \Cpp\
% logo. However, |\C++| is not defined in \cws. The conservative users
% of {\tt ccwebmac.tex} designed by Hans--Hermann Bode might be
% accustomed to |\Cpp| while users of {\tt cwebmac.tex} from {\tt CWEB
% 3.0} might like |\CPLUSPLUS/|. Therefore we supply all three tags and
% moreover make them robust so that they can safely be used in moving
% arguments.
%    \begin{macrocode}
\def\p_cpp{C\CwebIncr}
\def\C++{\protect\p_cpp}
\def\Cpp{\protect\p_cpp}
\def\CPLUSPLUS/{\protect\p_cpp}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}

% \section{Improvements}
% \begin{macro}{\CwebScope}
% If your program contains description of member functions as
% |TListBox::|\-|handleEvent|, the documentation part may easily contain
% lots of overfull boxes. Therefore we try to allow the line break after
% the scope operator. We make the change only if it is not typeset in
% the math mode. The following solution is not perfect. The expression
% ``|::close|'' may be incorrectly split after the scope resolution
% operator. To make a robust macro we should probably fiddle with
% |\lastskip| and |\lastpenalty|.
%    \begin{macrocode}
\def\CwebScope{\ifmmode \kern.1em::\kern.1em\else
  \kern.1em::\hskip.1em\fi}
%    \end{macrocode}
% \end{macro}

% \subsection{Index appearance}
% When typesetting two or more columns it is more pleasant if the
% columns are balanced. This may easily be achieved with Frank
% Mittelbach's {\tt multicol.sty}. We try whether the style is
% available.
%    \begin{macrocode}
\newif\ifhave@multicol
\openin\@ne multicol.sty
\ifeof\@ne \else \have@multicoltrue \fi
\closein\@ne \relax
%    \end{macrocode}

% If we found {\tt multicol.sty}, we use it. It might me nice to delay
% this until we know that the index is really requested.
%    \begin{macrocode}
\ifhave@multicol \input{multicol.sty} \fi
%    \end{macrocode}

% \begin{macro}{\CwebIdIndex}
% \begin{macro}{\twocolumn}
% \begin{macro}{\onecolumn}
% We delay the redefinitions of the twocolumn format into the definition
% of |\CwebIdIndex|. If we made the changes globally, we could
% eventually break something in the user's code.

% I dare say that I do not like the page break in between the index and
% the list of refinements so I do not put it into the redefinition of
% |\onecolumn|. Notice also that the new version of |\onecolumn|
% restores everything for the rare case it is needed somewhere later.
%    \begin{macrocode}
\let\orig_CwebIdIndex=\CwebIdIndex
\let\orig_twocolumn=\twocolumn
\let\orig_onecolumn=\onecolumn

\ifhave@multicol
 \def\CwebIdIndex{%
  \def\twocolumn{\newpage
   \@ifnextchar[{\zw@twocol}{\begin{multicols}{2}}}
  \long\def\zw@twocol[##1]{\setbox\cweb_tempbox=\vbox{##1}%
   \begin{multicols}{2}[\unvbox\cweb_tempbox]}
  \def\onecolumn{%
   \let\onecolumn=\orig_onecolumn
   \let\twocolumn=\orig_twocolumn}
  \orig_CwebIdIndex\cweb@restore_end\end{multicols}}
\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}

% \begin{macro}{\cweb@restore_end}
% The index is processed after the user supplied |\end{document}| where
% the |\end| tag has unfortunately been redefined. We would always get a
% \LaTeX\ error informing us about unmatched |\begin| and |\end|.
% Therefore we prepare a macro which will be used inside a group to
% restore temporarily the original meaning of |\end|.
%    \begin{macrocode}
\let\orig_end=\end
\def\cweb@restore_end{\let\end=\orig_end}
%    \end{macrocode}
% \end{macro}

% \section{Crazy inventions}
% As we can see from the documentation of \cws, it can handle two
% versions of \LaTeX. Older versions of \LaTeX\ are unlikely to be used
% and \LaTeX3 will handle |\end|'s in a different way so the following
% invention does not seem useful. I wrote it mainly as an exercise so
% that I could proudly say with the White Knight from Through the
% Looking Glass, ``It's my own invention.''

% \begin{macro}{\cweb@end_tokens}
% When skipping around the |\end{document}| we have to catch the tokens
% which are placed after |\endgroup|. For this purpose we establish a
% new token register.
%    \begin{macrocode}
\newtoks\cweb@end_tokens
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\cweb@report_error}
% Before we start the job of catching tokens we prepare some macros. The
% first of them will display our error message. Though we hope that the
% catching algorithm will work with all \LaTeX's currently available, it
% may according to Murphy's Laws happen that someone's obsolete (or
% brand new) \LaTeX\ will break it. We do not want to bother the user
% with strange error messages. We therefore supply ours. The text is
% taken exactly from \cws. The macro will be issued from inside a group
% therefore we take no care about restoring the original definitions.
%    \begin{macrocode}
\def\cweb@report_error{\let\orig_errmsg=\errmessage
  \def\errmessage##1{%
    \errhelp={^^J%
This style depends on an internal implementation detail of LaTeX.^^J%
Sad to note, this detail has changed; you cannot use the cweb style.^^J%
Please type "i\show\end" now. TeX will spit out a few lines of^^J%
definitions and ask again for input. Type "x" then, this will finish TeX.^^J
Then send the log file to the style's author, Joachim Schrod^^J%
(Email: schrod@iti.informatik.th-darmstadt.de). He will adapt cweb.sty^^J%
to the new LaTeX version.^^J}
   \orig_errmsg{Sorry, you cannot use the cweb style with this LaTeX version}}
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\cweb@catch_tokens}
% We also prepare the macro which will catch the tokens. This is an
% incomplete assignment to the token register. Its function will be
% explained later.
%    \begin{macrocode}
\def\cweb@catch_tokens{\cweb@end_tokens=\bgroup}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\cweb_3_env}
% \begin{macro}{\endcweb_3_env}
% For catching the tokens we will invoke a very special environment with
% the name |cweb_3_env|. \LaTeX\ would complain if the environment were
% undefined. Therefore we place to |\cweb_3_env| everything which is
% needed at the beginning of the catching job and similarly
% |\endcweb_3_env| will contain the trap for the tokens. Notice that we
% have to use |\@namedef| to define tags with such strange names.
%    \begin{macrocode}
\@namedef{cweb_3_env}{\cweb@report_error}
\@namedef{endcweb_3_env}{\aftergroup\cweb@catch_tokens}
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \begin{macro}{\cweb@skip_end}
% Now we can catch the tokens and define |\cweb@skip_end| accordingly.
% First we write it and then explain how it works.
%    \begin{macrocode}
\begin{cweb_3_env}
{\egroup\end{cweb_3_env}}
\expandafter\def\expandafter\cweb@skip_end\the\cweb@end_tokens{\cweb@check_fi}
%    \end{macrocode}
% When we start the environment, \LaTeX\ will invoke our error reporting
% macro. It is invoked inside a group as we have promised. The ending
% command will tell \TeX\ that |\cweb@catch_tokens| should be carried
% out after the end of group. When the group is closed (after some
% checks), the tokens which stem from the expansion of |\end| are not
% executed but stored in our token register. So we have to complete the
% assignment. You might have temptation to just append |\egroup| after
% the statement ending the environment. But beware! This will store
% |\egroup| as the next token in |\cweb@end_tokens|. It will also eat up
% the rest of the file. Fortunately we are redefining \cws\ so that the
% official tags will do the job. We could start catching tokens with
% |\bgroup| which is equivalent to \{ but we must put \} and nothing
% else at the end of the assignment. We solve it by inserting an empty
% group |{\egroup|. This is syntactically correct. In almost all
% contexts \} and |\egroup| are interchangeable. So when \TeX\ scans the
% text, it sees matched braces and when executing the macros it finds
% balanced groups. The definition of |\cweb@skip_end| is now
% straightforward. Isn't it a pretty nonsense code?
% \end{macro}

% \section{Bug corrections}
% \begin{macro}{\egroup_}
% A funny (and instructive) bug invaded into the definition of
% |\CwebNumber|. This tag is defined in \cws\ where underscore is
% recatcoded to letter. Therefore, what would work in a usual \TeX\
% context, does not work here. We correct it by defining |\egroup_|
% which will do the correct things. However, there is one more thing
% which should be mentioned. When using NFSS, |\rm| has no effect in the
% math mode. The easiest safe way for switching to roman alphabet from
% inside math is to use |\hbox|. Placing |\,| as done in \cws\ seems
% unpleasant to my eyes therefore I remove it. Please notice that the
% catcode of underscore is restored to the original value within the
% following definition.

% {\bf Note from Joachim Schrod:}\quad This will not work any more
% since the bug with the underscore has been repaired (one shouldn't
% simply copy plain macros to \LaTeX{} code\,\dots). Nevertheless the
% problem with NFSS remains. But I'm not (yet?)\ convinced that the
% work-around presented here is the adequate solution. So the code is
% here for reference, but it will not be used.

%    \begin{macrocode}
\def\egroup_{\egroup\begingroup
  \catcode`\_=\CatUsCode
  \let\,=\relax
  \def\rm{\reset@font\footnotesize}%
  \cweb@egroup}

\catcode`\_=\CatUsCode
\def\cweb@egroup#1{_{\hbox{#1}}\endgroup}
%    \end{macrocode}
% \end{macro}

% \PrintIndex
% \end{document}
\endinput

