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:


 /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}}

The following is ignored.

 This stuff should all be ignored.

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

 This should be verbatim.     This should have a large space before it.

And normal text again.

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.

Your code would not respect line breaks in the input and needs a terminating character. Surely it could be refined, but I would hardly consider it more efficient than the traditional methods.

| improve this answer | |
  • 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
  • What I'm saying is that I don't see how it can be as efficient to use TeX's macro processor to do any kind of parsing, compared to simply letting TeX's engine read input characters blindly. – Ryan Reich Oct 26 '11 at 0:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.