% \iffalse BEGIN xcomment.doc
%%
\def\fileversion{1.2}
\def\filedate{93/02/12}
%%
%% Style option `xcomment' for use with LaTeX v2.09.
%% This is a style for comment and "inverse" comment environments.
%%
%% COPYRIGHT 1992, 1993 by Timothy Van Zandt, tvz@Princeton.EDU
%%
%% Input file:                  xcomment.sty.
%% Documented code:             xcomment.doc.
%% For printing documentation:  xcomment.tex.
%%
%% You may find xcomment.doc and xcomment.tex appended to xcomment.sty.
%%
%% Copying of part or all of any file in the xcomment.sty package
%% is allowed under the following conditions only:
%% (1) You may freely distribute unchanged copies of the files. Please
%%     include the documentation when you do so.
%% (2) You may modify a renamed copy of any file, but only for personal
%%     use or use within an organization.
%% (3) You may copy fragments from the files, for personal use or for use
%%     in a macro package for distribution, as long as credit is given
%%     where credit is due.
%%
%% You are NOT ALLOWED to take money for the distribution or use of
%% these files or modified versions or fragments thereof, except for
%% a nominal charge for copying etc.
%%
%  \fi
% \CheckSum{470}
% \CharacterTable
% {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%  Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%  Digits        \0\1\2\3\4\5\6\7\8\9
%  Exclamation   \!     Double quote  \"     Hash (number) \#
%  Dollar        \$     Percent       \%     Ampersand     \&
%  Acute accent  \'     Left paren    \(     Right paren   \)
%  Asterisk      \*     Plus          \+     Comma         \,
%  Minus         \-     Point         \.     Solidus       \/
%  Colon         \:     Semicolon     \;     Less than     \<
%  Equals        \=     Greater than  \>     Question mark \?
%  Commercial at \@     Left bracket  \[     Backslash     \\
%  Right bracket \]     Circumflex    \^     Underscore    \_
%  Grave accent  \`     Left brace    \{     Vertical bar  \|
%  Right brace   \}     Tilde         \~}
%
% \StopEventually{}
%
% \section{The implementation}
%
% The code is an adaption of code in verbatim.sty, and in fact the latter's
% structure has been preserved when possible. On the one hand, the code is
% simpler than in verbatim.sty because we throw away text from the input file
% rather than typeset it verbatim. On the other hand, it is more involved
% because we have to check for more possible endings to the |xcomment| than in
% verbatim.sty and we have to preserve the input that follows the |\begin|ning
% of an included environment on the same line.
%
% As in verbatim.sty and the |\comment\endcomment| commands in \AmSTeX, the
% basic strategy is to change the category codes so that control sequences and
% other troublesome special characters are neutralized, and then to scan for
% the strings that mark the end of the comment. This would be a 3-liner in
% |awk|, but this is \TeX, and the amount of code required to do the scanning
% increases rapidly as we allow for a greater variety of ending strings.
%
% We begin by ensuring that file is not read in twice, and then we identify
% the file on the VDU and the transcript file.
%    \begin{macrocode}
\@ifundefined{xcomment@@@}{}{\endinput}
\typeout{Style-Option: `xcomment' v\fileversion \space <\filedate> (tvz) }
%    \end{macrocode}
%
%
% \subsection{User commands}
%
% \begin{macro}{\xcomment}
% \begin{macro}{\newxcomment}
% The main toplevel macro is |\@xcomment|, which is defined in the next
% section. It works like |\xcomment| as described above, except that it has as
% a first argument an {\em environment} so that it stops when it encounters
% |\end{|{\em environment}|}|. |\newxcomment| then has a simple definition,
% and |\xcomment| is defined using the |\newxcomment| command.
%    \begin{macrocode}
\def\newxcomment{\@ifnextchar [{\@newxcommentwitharg}%
  {\@newxcomment}}
\def\@newxcomment#1{%
  \expandafter\def\csname #1\endcsname##1{\@xcomment{#1}{##1}}}%
\def\@newxcommentwitharg[#1]#2{%
  \expandafter\def\csname #2\endcsname{\@xcomment{#2}{#1}}}
\newxcomment{xcomment}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\envirsep}
% \begin{macro}{\rescanfile}
% \begin{macro}{\norescanfile}
% |\envirsep| is inserted between the environments that are typeset, and is
% set to |\par| by default. |\rescanfile| is the name of the temporary file
% used for rescanning, and is set to |\jobname.tmp| by default.
%    \begin{macrocode}
\def\envirsep{\par}
\def\rescanfile#1{\def\@rescanfile{#1}}
\rescanfile{\jobname.tmp}
\def\norescanfile{\let\@rescanfile\relax}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\nofloat}
% |\nofloat| disables floating, and |\vfill| is inserted forcefully on each
% side of each float. The macro is just a hack, and is mainly for printing
% only floats. It may not work well even for that. |\envirsep| is still
% inserted between floats, and if it is set to |\vspace{}|, the added space is
% inserted only between floats on the same page, given the user some control
% over spacing.
%    \begin{macrocode}
\def\@nofloat#1{\hrule height\z@\nobreak\vfill\vbox\bgroup\def\@captype{#1}}
\def\end@nofloat{\egroup\nobreak\vfill\nobreak\hrule height\z@\medbreak}
\def\nofloat#1{\@for\@tempa:=#1\do{\@namedef{#1}{\@nofloat{#1}}%
  \@namedef{end#1}{\end@nofloat}}}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Preliminaries}
%
%
% \begin{macro}{\xc@makeother}
% |\xc@makeother| takes as argument a character and changes
% its category code to $12$ (other) if its category code is originally 0, 1, 2
% or 6. We do not have to change as many catcodes as in verbatim.sty, because
% the input is either thrown away or rescanned. The fewer codes we change the
% better.
%    \begin{macrocode}
\def\xc@makeother#1{%
  \ifnum\the\catcode`#1=0\catcode`#112%
  \else \ifnum\the\catcode`#1=1\catcode`#112%
    \else \ifnum\the\catcode`#1=2\catcode`#112%
      \else \ifnum\the\catcode`#1=6\catcode`#112%
  \fi\fi\fi\fi\relax}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\rescan}
% This macro changes the category codes of a token list that is already in
% \TeX's stomach. The code is a modification of a |\retokenize| macro by
% Raymond Chen.
%    \begin{macrocode}
\newwrite\tokout
\newread\tokin
%    \end{macrocode}
% The argument of |\rescan| is a token list register, say, |\mytoks|.
% |\mytoks| presumably contains a string from the input file, sent to |\TeX|'s
% stomach as a stream of tokens. |\rescan| gives |\mytoks| the token list that
% would have arisen if |\TeX| had had the current catcodes in effect when it
% read the input string, with the following exceptions:
% \begin{itemize}
% \item The token list must have balanced braces under the new catcodes.
% \item Parameter tokens in the original list are written twice, and so mess
% things up.
% \item Some characters with catcode 10 (space) under the old catcodes are
% lost, and all that remain are treated as character 32 (\verb*+ +) under the
% new catcodes, whatever this character's new catcode is.
% \item Escape characters under the old catcodes are treated as escape
% characters even if their catcodes have changed. (This can be fixed by
% setting |\escapchar| during the write to the escape character under the old
% catcodes, assuming there was only one and it is known)
% \item Leading spaces under the new catcodes are not ignored, which is wrong
% if and only if the string started at the beginning of a line and the space
% characters were not spaces under the old catcodes.
% \end{itemize}
% Only the balanced braces exception is a problem in this application, but the
% other exceptions are pointed out since such a rescanning macro has other
% applications.
%    \begin{macrocode}
\def\rescan#1{%
%    \end{macrocode}
% First we check if |\rescanfile|, which contains the name of the temporary
% file to be used, has a special meaning. If |\relax|, do nothing. If empty,
% empty the token register.
%    \begin{macrocode}
  \ifx\@rescanfile\relax\else
    \ifx\@rescanfile\@empty #1{}\else
%    \end{macrocode}
% Put the list of tokens in braces and write them to the temporary file.%
% \begin{macrocode}
      \immediate\openout\tokout=\@rescanfile
      \immediate\write\tokout{{\the#1}\relax}%
      \immediate\closeout\tokout
%    \end{macrocode}
% Read the contents of the file |\@tempd|.
%    \begin{macrocode}
      \openin\tokin=\@rescanfile
      \read\tokin to\@tempd
      \closein\tokin
%    \end{macrocode}
% Suppose |#1| is |\mytok|, and \meta{token list} is the list of tokens with
% the current catcodes. Then the next line expands to |\mytok{|\meta{token
% list}|}\relax|.
%    \begin{macrocode}
      \expandafter#1\@tempd%
  \fi\fi}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Toplevel macros}
%
% \begin{macro}{\@xcomment}
% |\@xcomment| checks whether it was invoked before |\begin{document}| and
% outside of an environment. If so, it modifies |\begin{document}| to invoke
% |\@xcomment| with the same arguments. Otherwise, it processes its arguments
% and goes into ``comment'' mode by invoking |\xc@begin|.
%    \begin{macrocode}
\def\@xcomment#1#2{%
  \ifx\@preamblecmds\@notprerr
    \def\xc@csname{#1}%
    \edef\xc@envirlist{#2}%
    \ifx\xc@envirlist\@empty \@bsphack \else
      \begingroup
%    \end{macrocode}
% |\@envirsep| is what is actually placed before each environment. Initially,
% it is empty because nothing should precede the first environment that is
% typeset.
%    \begin{macrocode}
      \def\@envirsep{}%
%    \end{macrocode}
% |\do@end| is appended to the meaning of |\end|, and it is initially set to
% |\xc@begin|. This means that the |\end| of an included environment switches
% us back into ``comment'' mode, as desired. The |\end| of nested environments
% should have their usual meaning, however. Therefore, |\do@begin| is
% prepended to the definition of |\begin|, and it sets |\do@end| to |\relax|.
% Included environment are begun with |\normal@begin| because we only want to
% reset |\do@end| for nested environements. The group begun above keeps the
% |\end| of the |xcomment| environment from be being affected by these
% changes.
%    \begin{macrocode}
      \@ifundefined{normal@begin}{\let\normal@begin\begin}{}%
      \@ifundefined{normal@end}{\let\normal@end\end}{}%
      \def\begin##1{\do@begin{##1}\normal@begin{##1}}%
      \def\end##1{\normal@end{##1}\do@end}%
      \def\do@begin##1{\@ifundefined{##1}{}{\def\do@end{}}}%
      \let\do@end\xc@begin
    \fi
    \let\next\xc@begin
  \else
    \expandafter\@temptokena\expandafter{\document\@xcomment{@@@}{#2}}%
    \edef\document{\the\@temptokena}%
    \let\next\relax
  \fi
  \next}
\def\end@xcomment{\ifx\xc@envirlist\@empty \@esphack \else \endgroup \fi}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xc@begin}
% |\xc@begin| starts up ``comment'' mode by changing the category codes and
% invoking |\xcomment@|. The |\begingroup| keeps these catcode changes local.
%    \begin{macrocode}
\def\xc@begin{%
  \begingroup
    \let\do\xc@makeother
    \dospecials
    \ifx\xcommentchar\@empty\else
      \expandafter\catcode\expandafter`\xcommentchar=14
    \fi
    \catcode`\^^M\active
    \xcomment@}
\def\xcommentchar{\%}
%    \end{macrocode}
% \end{macro}
%
%
%
% \subsection{The main loop}
%
%
% Since the code in the main loop uses literal |\|, |{|, |}|, |%| and newline
% characters, we represent them with |!|, |[|, |]| |"| and |~| by setting the
% corresponding lccodes to the correponding character but with catcode 12, and
% then changing the code to lowercase before executing the macro definitions.
% These catcode changes are kept local, and the macros must therefore be
% defined globally.
%    \begin{macrocode}
\begingroup
\catcode`\!=12
\catcode`\[=12
\catcode`\]=12
\catcode`\"=12
\lccode`\!=`\\
\lccode`\[=`\{
\lccode`\]=`\}
\lccode`\"=`\%
\catcode`\~=\active
\lccode`\~=`\^^M
\lowercase{
%    \end{macrocode}
%
% \begin{macro}{\xcomment@}
% The three macros |\xcomment@|, |\xcomment@@|, and |\xcomment@@@| form the
% main loop when in ``comment'' mode. |\xcomment@| reads a line of input.
% |\xcomment@@| searches for the first occurence of a backslash.
% |\xcomment@@@| checks what the next character is, and depending an the
% answer various macros are invoked to see if one of the termination strings
% has been found.
%
% |\xcomment@| takes the line it has read, puts |\@nnil| |\| and |\@nil| as
% delimiters at the end, and then calls |\xcomment@@|.
%    \begin{macrocode}
  \gdef\xcomment@#1~{\xcomment@@#1\@nnil!\@nil}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xcomment@@}
% |\xcomment@@| takes everything up to the next occurrence of |\| as its
% argument and throws it away together with the |\|. Then |\xcomment@@@| reads
% the next token on the line, including the delimiters added by |\xcomment@|.
%    \begin{macrocode}
  \gdef\xcomment@@#1!{\xcomment@@@}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xcomment@@@}
% |\xcomment@@@| checks for key strings.
%    \begin{macrocode}
  \gdef\xcomment@@@#1\@nil{%
    \def\@tempa{#1}%
    \ifx\@tempa\@empty
      \let\next\xcomment@
    \else
      \def\next{\xcomment@@#1\@nil}%
      \@testtrue
      \xc@checkbegin#1\relax begin[]\relax\relax
      \if@test
        \xc@checkend#1\relax end[]\relax\relax
        \if@test
          \xc@checkinput#1\relax input[]\relax\relax
          \if@test
            \xc@checkinclude#1\relax include[]\relax\relax
            \if@test
              \xc@checkendinput#1\relax endinputss\relax\relax
    \fi\fi\fi\fi\fi
    \next}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xc@checkbegin}
% \begin{macro}{\xc@checkend}
% Check for |\begin| and |\end|.
%    \begin{macrocode}
  \gdef\xc@checkbegin#1begin[#2]#3\relax#4\relax{%
    \def\@tempa{#1}%
    \ifx\@tempa\@empty
      \def\@tempa{#2}%
      \@for\@tempb:=\xc@envirlist\do{%
        \ifx\@tempa\@tempb\def\next{\xc@end{#2}#3\@nil}\fi}%
    \fi}
  \gdef\xc@checkend#1end[#2]#3\relax#4\relax{%
    \def\@tempa{#1}%
    \ifx\@tempa\@empty
      \@testfalse
      \def\@tempa{#2}\def\@tempb{document}%
      \ifx\@tempa\@tempb
        \def\next{\endgroup\end@xcomment\end{document}}%
      \else
        \ifx\@tempa\xc@csname
          \def\next{\end@@xcomment{#2}#3\@nil}%
    \fi\fi\fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\xc@checkinput}
% \begin{macro}{\xc@checkendinput}
% Check for |\input| and |\endinput|.
%    \begin{macrocode}
  \gdef\xc@checkinput#1input[#2]#3\relax#4\relax{%
    \def\@tempa{#1}%
    \ifx\@tempa\@empty
      \def\next{\expandafter\xcomment@\@@input #2 \xcomment@@#3\@nil}%
      \@testfalse
    \fi}
  \gdef\xc@checkendinput#1endinput#2#3\relax#4\relax{%
    \def\@tempa{#1}%
    \ifx\@tempa\@empty\ifcat\noexpand#2a\relax\else
      \let\next\endinput
    \fi\fi}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\xc@checkinclude}
% Check for |\input| and |\endinput|.
%    \begin{macrocode}
  \gdef\xc@checkinclude#1include[#2]#3\relax#4\relax{%
    \def\@tempa{#1}%
    \ifx\@tempa\@empty
      \def\next{%
        \global\let\xc@savedinput\@@input
        \def\@@input{%
          \global\let\@@input\xc@savedinput
          \expandafter\xcomment@\@@input}%
        \include{#2}%
        \global\let\@@input\xc@savedinput
        \xcomment@@#3\@nil}%
      \@testfalse
    \fi}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\end@@xcomment}
% When exiting the |xcomment| environment, we only have to be careful to
% rescan the line. Note that if get this far, all three delimiters appended to
% the current line are intact. We append a space before rescanning, because of
% a \meta{return} that was stripped by |\xcomment@|.
%    \begin{macrocode}
  \gdef\end@@xcomment#1#2\@nnil!\@nil{%
    \endgroup
    \toks@{#2 }\rescan{\toks@}%
    \edef\next{\noexpand\end@xcomment\noexpand\end{#1}\the\toks@}%
    \next}%
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\xc@end}
% When exiting ``comment'' mode to typeset an included environment, we have to
% get rid of the delimiters added to the current line. The |\endgroup| ends
% the scope of the catcodes changes. The first time an environment is typeset,
% |\@envirsep| is null. Thereafter,
% it is set to |\envirsep|.
%    \begin{macrocode}
  \gdef\xc@end#1#2\@nnil!\@nil{%
    \endgroup
    \@envirsep \let\@envirsep\envirsep
    \toks@{#2 }\rescan{\toks@}%
    \edef\next{\noexpand\normal@begin{#1}\the\toks@}%
    \next}%
%    \end{macrocode}
% \end{macro}
%
%
% Now we end the lowercase command and the group that were used to insert
% literal |\|, |{| and |}| characters in the code.
%    \begin{macrocode}
  }%  END OF LOWERCASE
\endgroup
%    \end{macrocode}
%
% \Finale
%
\endinput
% END xcomment.doc
