%Article 19302 of comp.text.tex: %Path: sifon!newsflash.concordia.ca!utcsri!rpi!batcomputer!munnari.oz.au!metro!grivel!neumann.une.edu.au!zhuhan %From: zhuhan@neumann.une.edu.au (Z Jiang) %Newsgroups: comp.text.tex %Subject: A robust solution? (was:Skipping blocks in a %Message-ID: <2155@grivel.une.edu.au> %Date: 8 Oct 93 00:14:49 GMT %Sender: usenet@grivel.une.edu.au %Organization: University of New England, Armidale, Australia %Lines: 460 %Nntp-Posting-Host: neumann.une.edu.au % %A lot a suggestions have been posted recently for a macro that %comments out blocks of text in TeX or LaTeX or anyTeX. % %I have come up with also one solution. In my opinion. This is quite %robust. The method is that you use % \begincomment{password} % < any text !> % \endcomment %Then will be ignored. If you are careful, then you would %have already asked that what if contains '\endcomment'? %This is then solved by using a nonempty 'password'. In other words, %if the password is nonempty, then the password instead of \endcomment %is used to end the . % %The main idea is that \begincomment{password} sets chars 1-128 to %catcode 11 or so, so that all legal characters are 'letters'. Then %it looks at the token stream to find if there is the 'password'. %If it does find it, then quit the comment. % %Good point: % You can comment out *arbitrarily* number of lines, without hitting % TeX capacity. It also print out the number of lines you skipped. % %Inconvenience: % The potion after \endcomment or 'password' in the line containing % such word is also commented out. So it is best \endcomment takes % up an entire line. However a warning will be issued and the ignored % portion be written into your log file, should you put something other % than spaces after \endcomment on the same line. % %Pitfall: % If you have a single line of text inside your comment, which is itself % more than say 5 pages, then I'm in trouble and you know why. But it is % really most unlikely to happen naturally. % %Others: % The following code is cut off from my style file formlett.sty, which % was written for sending letters to multiple receivers. So for our % limited purpose here, there should be many ways to simplify the code. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 1. COMMENT OUT TEXT % \begincomment{password} \endcomment or password % a. empty password implies \endcomment is the password to leave comment % b. whole line following \endcomment or password is also ignored % % 2. RAWTEXT LISTING % \beginrawlist [...]{password} \endrawlist or password % defaults for [..] supported, last {..} compulsory ({} allowed though) % % \beginrawlist [][][][]% % [][]{} % =\linecount: starts with where it is left % = empty: \endrawlist ends the rawlist, otherwise % ends it % =0: no line numbering % % 3. PRINTFILE verbatim % \printfile [...]{filename} % [...] same as \beginrawlist % %BEGINMACROS % {\catcode`\@=11\relax\wlog{}% \wlog{This is a part of FORMLETT.STY version 1.22 Oct 1993}% \wlog{By Z Jiang, University of New England, Australia}\wlog{}}% % %%% SAVE @'s STATUS \xdef\EntryADDnuM{\the\catcode`\@}\catcode`\@=11\relax % \def\new@measures{% \def\temp@@macro##1##2##3{\expandafter\ifx\csname ##3temp##2##1\endcsname \relax\edef\next{\noexpand\csname new##1\noexpand\endcsname \csname ##3temp##2##1\endcsname}% \else\let\next\relax\fi\next}% \def\temp@macro##1{% \temp@@macro{##1}{@}{}\temp@@macro{##1}{@@}{}\temp@@macro{##1}{@@@}{}}% \temp@macro{count}\temp@macro{toks}\temp@macro{box}\temp@macro{read}% \temp@@macro{if}{@}{if}\temp@@macro{if}{@@}{if}\temp@@macro{if}{@@@}{if}% \def\temp@@macro##1{\expandafter\ifx\csname temp##1dim\endcsname \relax\edef\next{\noexpand\csname newdimen\noexpand\endcsname \csname temp##1dim\endcsname}% \else\let\next\relax\fi\next}% \temp@@macro{@}\temp@@macro{@@}\temp@@macro{@@@}% }% \let\temp@@@macro=\wlog\def\wlog#1{}\new@measures % %%% GENERAL STACK % \def\make@STKcount{\csname newcount\endcsname \STKcount\global\STKcount=0\relax}% \ifx\STKcount\undefined@ \def\next{\make@STKcount}\else\def\next{}\fi \next % ensures stack pointer not flushed if this piece of code % is loaded again % \long\def\push#1{\global\advance\STKcount1\relax \expandafter\gdef\csname STK\the\STKcount\string~\endcsname{#1}}% % \def\popnil{\expandafter\let\expandafter\temp@macro \csname STK\the\STKcount\string~\endcsname \ifnum\STKcount>0\global\expandafter\let \csname STK\the\STKcount\string~\endcsname=\undefined@ \global\advance\STKcount-1% \else \def\temp@macro{}\global\STKcount=0% \fi\relax % \temp@macro for pop }% % \def\pop{\popnil\temp@macro}% % %% GET PARAMETERS % \long\def\get@nepara[#1][#2]{{\def\next@{#2}% \ifx\next@\empty\push{#1}\else\push{#2}\fi}\ag@in}% % \long\def\get@para\left@#1\right@{% \def\check@{% \ifx[\next@ \def\full@####1{\get@nepara[#1]####1}% \else \def\full@{\get@nepara[#1][#1]}\fi \full@}% \futurelet\next@\check@}% % \long\def\do@nepara\left@#1\right@#2\p@r@end{% \gdef\p@r@data{#2}\global\advance\p@r@count1\get@para\left@#1\right@}% % \def\ag@in{\ifx\p@r@data\empty \def\next@{\relax \getp@r@s\run@CMD}\else \def\next@{\expandafter\do@nepara\p@r@data\p@r@end}\fi \next@}% % \def\run@CMD{\csname STK\the\STKcount\string~\endcsname}% % \newcount\p@r@count \long\def\st@ckparas#1\p@r@end{% \global\p@r@count=0\gdef\p@r@data{#1}\ag@in}% % % % PARAMETER ASSIGNMENT % %% \newcount\temp@count \newtoks\p@r@one \newtoks\p@r@two \newtoks\p@r@three \newtoks\p@r@four \newtoks\p@r@five \newtoks\p@r@six \newtoks\p@r@seven \newtoks\p@r@eight \newtoks\p@r@nine \def\getp@r@s{\temp@count=\p@r@count {\loop \ifnum\temp@count>0% \expandafter\let\expandafter \temp@macro\csname STK\the\STKcount\string~\endcsname \ifcase\temp@count \or \global\p@r@one=\expandafter{\temp@macro}% \or \global\p@r@two=\expandafter{\temp@macro}% \or \global\p@r@three=\expandafter{\temp@macro}% \or \global\p@r@four=\expandafter{\temp@macro}% \or \global\p@r@five=\expandafter{\temp@macro}% \or \global\p@r@six=\expandafter{\temp@macro}% \or \global\p@r@seven=\expandafter{\temp@macro}% \or \global\p@r@eight=\expandafter{\temp@macro}% \or \global\p@r@nine=\expandafter{\temp@macro}% \else \errmessage{Parameter capacity exceeded.}% % this should never happen: TeX's max para no. is 9 \fi \global\expandafter\let \csname STK\the\STKcount\string~\endcsname=\undefined@% \global\advance\STKcount-1% \global\advance\temp@count-1\relax \fi \ifnum\temp@count>0% \repeat}}% % \def\clrp@r@s{%GLOBALLY clear \global\p@r@one={}\global\p@r@two={}\global\p@r@three={}% \global\p@r@four={}\global\p@r@five={}\global\p@r@six={}% \global\p@r@seven={}\global\p@r@eight={}\global\p@r@nine={}}% % The above is the minimum for setting default parametrisation % % EXIST FILE ? % \temp@iftrue if the file #1 exist when tested via \existfile{#1}% % \newread\temp@read \def\existfile#1{\temp@iftrue \openin\temp@read=#1\relax \ifeof\temp@read \temp@iffalse \fi \closein\temp@read}% % % a private \l@@p \def\l@@p#1\repe@t{\def\b@dy{#1}\iter@te}% \def\iter@te{\b@dy\let\n@xt=\iter@te \else\let\n@xt=\relax\fi \n@xt}% \let\repe@t=\fi % % % RAW CHARACTERS % \def\raw@chars[#1][#2][#3][#4][#5]{% % #1=11, #2=\`=12, #3=^^I=10, #4=char32=10, #5=^^M=5 \temp@count=0\relax % \l@@p \catcode\temp@count=11\advance\temp@count1\relax % \ifnum\temp@count<128\repe@t % \catcode`\%=#1\catcode`\^=#1\catcode`\_=#1% \catcode`\&=#1\catcode`\$=#1\catcode`\#=#1% \catcode`\{=#1\catcode`\}=#1\catcode`\@=#1% \catcode`\~=#1\catcode`\\=#1% \catcode`\`=#2\catcode`\^^I=#3\catcode`\ =#4% \catcode`\^^M=#5\relax % }% % \chardef\temp@char=`\`\catcode`\`=13\relax \def\rm@ligature{\def`{\null\string`}}% \catcode\temp@char=12\relax % \catcode`\^^I=13\relax\def\set@tab{\def^^I{\ \ \ \ }}\catcode`\^^I=10\relax% \catcode`\^^M=13\relax\def\set@cr{\def^^M{\par}}\catcode`\^^M=5\relax% \catcode`\ =13\relax\def\set@space{\def {\ }}\catcode`\ =10\relax% % % TEST EMPTY LINE % \catcode`\ =13\relax% space active % % Delete leading spaces (catcode=13) % Throw the rest to \temp@macro \long\def\del@truespaces#1#2\s@fetymark{\temp@iffalse% \def\temp@macro{#1}\def\one@space{ }\def\temp@@macro{}% \ifx\temp@macro\one@space% front spaces not allowed \def\temp@macro{#2}% \ifx\temp@macro\empty\temp@iftrue% \else\def\temp@@macro{\del@truespaces#2\s@fetymark}\fi% \fi% \temp@@macro}% % \catcode`\ =10\relax% % % \temp@iftrue if empty line, % \temp@macro holds nonspace part (space catcode=13 or normal) \long\def\is@emptyline#1{\def\one@space{ }% \def\temp@macro{#1}\def\temp@@macro{}\temp@iftrue \ifx\temp@macro\empty \else \ifx\temp@macro\one@space \else \def\temp@@macro{\del@truespaces#1\s@fetymark}% \fi \fi \temp@@macro}% % % TEST STRING % %% \newif\iftemp@if \newtoks\temp@toks % return \iftemp@iftrue if yes, % \first@half,\second@half are global \long\def\test@str#1#2{% \long\def\strip@endmark##1\s@fetymarkI#1\s@fetymark{% \gdef\second@half{##1}}% \long\def\strip@markI##1\s@fetymarkI\s@fetymark{% \gdef\first@half{##1}}% \long\def\p@rse##1#1##2\s@fetymark{% \gdef\first@half{##1}% \gdef\second@half{##2}% \ifx\second@half\empty \strip@markI##1\s@fetymark \temp@iffalse \else \strip@endmark##2\s@fetymark \temp@iftrue \fi}% \temp@toks={#2\s@fetymarkI#1\s@fetymark}% \expandafter\p@rse\the\temp@toks }% % % #1 supposed to a toks register \long\def\test@tokstr#1#2{% #1 =toks \temp@toks={#2}% \edef\temp@macro{\noexpand\test@str{#1}{\the\temp@toks}}% \temp@macro }% % % MAKE ESCAPE CHAR % % \esc@=the character '\' of catcode 11 \newtoks\name@endtoks \newtoks\true@endtoks \catcode`\*=0\relax *catcode`*\=11*relax *gdef*esc@{\}%*name@endtoks={\endrawlist}% *catcode`*\=0*relax \catcode`\*=12\relax % % % FLUSH ZEROS \fillzeros[] % %% \newcount\temp@count \newcount\temp@@count \def\fillzeros[#1]#2{\temp@@count=#2\relax \ifnum\temp@@count<0\temp@@count=-\temp@@count\fi \temp@count=1\relax {\loop\ifnum\temp@@count<10\else \global\divide\temp@@count by 10\global\advance\temp@count by 1\fi \ifnum\temp@@count=10\relax\global\temp@@count=11\relax\fi \ifnum\temp@@count>10\repeat}% \ifnum#2<0\advance\temp@count1\relax-\fi {\loop\ifnum\temp@count<#1\relax0\advance\temp@count1\fi \ifnum\temp@count<#1\repeat}% \temp@@count=#2\relax\ifnum\temp@@count<0\temp@@count=-\temp@@count\fi \the\temp@@count}% % % % BEGINLIST--ENDLIST: activate and % \catcode`\^^M=13% \newcount\linecount\global\linecount=1% {\obeyspaces\gdef {\ }}% % % \name@endtoks: token to end the list % \true@endtoks: tokens to be executed at the end % \name@endtoks and \true@endtoks must be defined on entry % \no@emptylinefalse: the first or the last line empty % \newif\ifno@emptyline % iftemp@if \newif\ifprint@file \global\print@filefalse % \def\begin@list[#1][#2][#3][#4][#5][#6]{% \global\linecount=#1\catcode`\^^M=13\no@emptylinetrue % \ifprint@file \def^^M{\put@linenumber}\else\def^^M{\par}\fi % \def\put@linenumber{\par\noindent\hbox to #5{}% \rlap{\hskip-1em\hskip#6% \ifnum#3>0\relax\hbox to0em{\hss#4\fillzeros[#3]\linecount~~}\fi}% \global\advance\linecount#2\relax}% \def\out@aline{% \ifno@emptyline % \expandafter\is@emptyline\expandafter{\first@half}% \ifprint@file \temp@@iffalse \else\temp@@iftrue \fi % \else \temp@iffalse \temp@@iftrue % \fi \no@emptylinefalse% \iftemp@if \else % \iftemp@@if \put@linenumber \fi % \first@half \par % extra \par is absorbed, put here for last line \fi }% \def\readyt@quit{\no@emptylinetrue% \temp@toks=\expandafter{\first@half}% \temp@@toks=\expandafter{\second@half}% \edef\first@half{\the\temp@toks\the\temp@@toks}\out@aline % \edef\temp@macro{\the\true@endtoks}% \temp@macro % \second@half removed }% \def\moret@get{\out@aline\get@phys@line}% \long\def\get@phys@line##1^^M{% \test@tokstr{\the\name@endtoks}{##1}% \iftemp@if \let\temp@macro=\readyt@quit \else \let\temp@macro=\moret@get % \fi % \temp@macro }% \catcode`\ =13\relax\get@phys@line% }% % \def\endlist{\catcode`\^^M=13% \catcode`\ =10\let^^M=\par\catcode`\^^M=5}% \def\beginlist[#1][#2][#3][#4][#5][#6]{% \name@endtoks={\endlist}\true@endtoks={\endlist}% \begin@list[#1][#2][#3][#4][#5][#6]}% % \catcode`\^^M=5\relax% % % \def\endrawlist{\endgroup}% \def\begin@@rawlist[#1][#2][#3][#4][#5][#6]#7{\begingroup \def\temp@macro{#7}% #7=token to end the list \ifx\temp@macro\empty \name@endtoks=\expandafter{\esc@ endrawlist}% \else \name@endtoks={#7}% \fi \true@endtoks={\endlist\endrawlist}% \rm@ligature\set@tab\set@cr\set@space \raw@chars[11][13][13][13][13]% \begin@list[#1][#2][#3][#4][#5][#6]}% % \def\begin@rawlist[#1][#2][#3][#4][#5][#6]#{% \begin@@rawlist[#1][#2][#3][#4][#5][#6]}% % \def\beginrawlist{\push{% \edef\next@@{\noexpand\begin@rawlist [\the\p@r@one][\the\p@r@two][\the\p@r@three][\the\p@r@four]% [\the\p@r@five][\the\p@r@six]}% \popnil\clrp@r@s\next@@}% end of push \font\tiny@rm=cmr5% \edef\temp@macro{% \noexpand\left@\the\linecount\noexpand\right@ \noexpand\left@1\noexpand\right@ \noexpand\left@0\noexpand\right@ \noexpand\left@\noexpand\tiny@rm\noexpand\right@ \noexpand\left@0pt\noexpand\right@ \noexpand\left@0pt\noexpand\right@}% \expandafter\st@ckparas\temp@macro\p@r@end}% % % % \catcode`\^^M=13\relax % \def\print@@file[#1][#2][#3][#4][#5][#6]#7{% \temp@toks={\bgroup\print@filetrue % \beginrawlist[#1][#2][#3][#4][#5][#6]{}}% \existfile{#7}% \iftemp@if % \edef\temp@macro##1{\the\temp@toks % \noexpand\input##1\leavevmode % \setbox\temp@box=\lastbox\esc@ endrawlist^^M% \global\advance\linecount-1\relax\egroup}% \else \def\temp@macro##1{\message{(File #7 not found)}}% \fi % \temp@macro{#7}}% \catcode`\^^M=5\relax % % \def\print@file[#1][#2][#3][#4][#5][#6]#{% \print@@file[#1][#2][#3][#4][#5][#6]}% % \def\printfile{\push{% \edef\next@@{\noexpand\print@file [\the\p@r@one][\the\p@r@two][\the\p@r@three][\the\p@r@four]% [\the\p@r@five][\the\p@r@six]}% \popnil\clrp@r@s\next@@}% end of push \font\tiny@rm=cmr5% \edef\temp@macro{% \noexpand\left@\the\linecount\noexpand\right@ \noexpand\left@1\noexpand\right@ \noexpand\left@6\noexpand\right@ \noexpand\left@\noexpand\tiny@rm\noexpand\right@ \noexpand\left@46pt\noexpand\right@ \noexpand\left@-10pt\noexpand\right@}% \expandafter\st@ckparas\temp@macro\p@r@end}% % \catcode`\^^M=13% \def\begin@@comment{\let\par\relax % \catcode`\^^M=13\message{< Comment}% \temp@count=0\temp@@count=0\relax% \long\def\get@phys@line##1^^M{% \ifnum\temp@@count<500\advance\temp@@count1\else \message{\the\temp@count}\temp@@count=1\fi\relax \global\advance\temp@count1\relax \test@tokstr{\the\name@endtoks}{##1}% \iftemp@if % \def\temp@macro{\message{\the\temp@count\space lines}% \expandafter\is@emptyline\expandafter{\second@half}% \iftemp@if\message{>}\else % \message{| WARNING >}% \wlog{(Ignored on comment line: \second@half)}% \fi \the\true@endtoks }% \else \let\temp@macro=\get@phys@line % \fi \temp@macro }% \catcode`\ =13\relax\get@phys@line}% % \def\end@comment{\catcode`\^^M=13\catcode`\ =10\def^^M{\par}\catcode`\^^M=5}% \catcode`\^^M=5\relax% % \def\endcomment{\endgroup}% \read@buffline\temp@macro \def\begin@comment#1{\begingroup\nullfont \tolerance=10000 \hbadness=10000 \vbadness=10000 \hfuzz=\maxdimen \vfuzz=\maxdimen \def\temp@macro{#1}% #1=token to end the list \ifx\temp@macro\empty \name@endtoks=\expandafter{\esc@ endcomment}% \else \name@endtoks={#1}% \fi \true@endtoks={\end@comment\endcomment}% \rm@ligature\set@tab\set@cr\set@space \raw@chars[11][13][13][13][13]\begin@@comment}% % \def\begincomment#{\begin@comment}% % \let\wlog\temp@@@macro\let\temp@@@macro\undefined@ % \catcode`\@=\EntryADDnuM\relax % %ENDMACROS