# A simple implementation of comment/verbatim: drawbacks?

While considering how to exclude \items in Yossi Farjoun's recently active question onlyitems? How to select specific items from an item list, I thought I would do what I proposed in my first answer: just comment them out. That had a clunky syntax, however, so I did something else.

But I thought of a simple way of doing comments that avoids the clunky syntax and elaborate parsing that the comment environment of the verbatim package goes through: just set all the catcodes to "ignore" (that is, 9). You have to restore them, of course, so this should be done in a group, and since TeX can't see the end of a group when everything is ignored, you have to leave braces intact.

It is a little clunky to set all the catcodes, but since I was using pgfkeys already it was natural to employ its .list handler to do the looping for me. Users of multibyte-character systems might want to change the definition of the utility/change all characters key in the code below:

\documentclass{article}
\usepackage{pgfkeys,pgffor}

\pgfkeys{
/comment/.is family, /comment,
utility/set catcode/.code 2 args = {\catcode#1=#2},
utility/ignore character code/.style = {utility/set catcode = {#1}{9}},
utility/verbatim character code/.style = {utility/set catcode = {#1}{12}},
utility/change all characters/.style = {utility/#1 character code/.list = {0,...,255}},
ignore all characters/.style = {utility/change all characters = ignore},
all characters verbatim/.style = {utility/change all characters = verbatim},
restore braces/.style = {
utility/set catcode = {\{}{1},
utility/set catcode = {\}}{2}
}
}

\def\ignoreallcharacters{\pgfkeys{/comment/.cd, ignore all characters}}
\def\allcharactersverbatim{\pgfkeys{/comment/.cd, all characters verbatim}}
\def\restorebraces{\pgfkeys{/comment/.cd, restore braces}}

\begin{document}
\noindent
The following is ignored.

{
\expandafter\ignoreallcharacters\restorebraces
This stuff should all be ignored.
}

\noindent
This should be printed again.  Now we have verbatim text:

{
\tt
\expandafter\allcharactersverbatim\restorebraces
This should be verbatim.     This should have a large space before it.
}

\noindent
And normal text again.
\end{document}


As a bonus, it's not hard to do the same thing to get verbatim text. A little more work could probably make things look nicer (for example, doing the equivalent of \obeyspaces and \obeylines rather than printing them as "other" characters) but the principle is there.

So, my question: what are the drawbacks of this approach to commented/verbatim input? Even Knuth, in the TeXbook, doesn't suggest doing this. (He does point out that this kind of method will not allow unbalanced braces, but it's not hard to make restore braces turn some other pair of characters into the group delimiters, and then we're looking exactly like what \verb usually does.)

-
You can't use this with an already tokenized input, unless you process it again with \scantokens. – egreg Oct 25 '11 at 22:12
@egreg: You can't use any verbatim environment with already tokenized input unless you reprocess it with \scantokens. – Ryan Reich Oct 25 '11 at 22:14
Using pgf here is a massive overkill, which makes this method quite inefficient. You just need a \loop...\repeat construction. Also, it might be slightly more efficient to give catcode 14 to all characters instead of 9. Presumably, TeX can skip a comment faster than ignored characters, since it doesn't have to check the catcodes of all intermediate characters. – Bruno Le Floch Oct 25 '11 at 23:07

The LaTeX command \verb already implements what you are doing: every special character is assigned category code 12 so that it can be printed, except the delimiter character, which receives category code 2 (end-of-group) to end the scope of those assignments.
It does more: the space character is assigned category 13 and defined as \  (it won't disappear at line breaks) unless \verb* is called. Other characters are activated in order to break ligatures (the backquote for the Spanish ligatures, for instance).
The comment environment is defined by the package verbatim that implements the verbatim environment in a different way than the LaTeX kernel: it assigns catcodes like \verb and it reads the text line by line storing it in a macro that usually typesets its contents, but can be redefined to throw it away (this is what comment does). The special input \end followed by the name of the environment in braces stops processing.
One always needs a terminating character. I said in my question how my code could be refined to use a different one and to obey line breaks. Your first two paragraphs do answer my question as it concerns verbatim printing, but I am confused by your claim that the verbatim package is in any way efficient as a comment environment, since it has to read the characters one-by-one to look for \end (far worse than a terminating character!). Even if you want to save the input, you can just put my two lines of code at the front of a \vbox in a box register. – Ryan Reich Oct 25 '11 at 22:54
The kernel verbatim does this (but using TeX's feature of delimited arguments, which is equivalent to looking for an end-of-group character); the verbatim package versions reads line by line and so it's much more efficient, since the \end{verbatim} must be at the beginning of the line. – egreg Oct 25 '11 at 23:03