# Percent signs - “comment” and “active” both at once?

I convert documents from Word a lot, and I often forget to escape %, which leads to pieces of text missing. So I would like the following to happen in the main document body:

• escaped \% working as expected;
• single % causing an error;
• double %% behaving like a comment.

Do you think this is possible to do? I think it can be done by making % catcode active and chanking if the next one is % as well based on this changing it to comment for the rest of the line.

Starting point / MWE:

\documentclass{article}

\usepackage{lipsum}

%\usepackage{lipsum} % should cause no error

\begin{document}

Hello!

I use to forget to escape up to 70 % of my percent-signs, which causes missing ends of sentences. So I would like this to cause error.

%% On the other hand, sometimes I really need to make a comment, so I want to use a double-percent-sign for that.

And of course, the 30 \% of escaped percent-signs should work correctly.

\lipsum

\end{document}

-
How would you handle the correct spacing? Even if local typography dictates a normal-width space, I would use at least a non-breaking one (e.g. ~) between numbers and the percent sign. (I consider it a unit-like symbol and would use \,/siunitx, anyway.) Bottom line: I'm voting for regex here. –  Qrrbrbirlbel Oct 20 '12 at 16:16
@Qrrbrbirlbel don't care much about the 3rd line, I know how I want to format the percent-sign. –  tohecz Oct 20 '12 at 16:23
%% as a comment by setting % active wouldn't work: in many situations % is seen when TeX is not expanding macros, even in the document environment: for example when you end a line in a \parbox with what should be a comment. –  egreg Oct 20 '12 at 19:24

I don't know whether this can be done with LuaTeX (maybe yes). But under (pdf)TeX this can't be done in full generality.

First of all let's recall how comments work. TeX reads a line of input and, before starting to transform the characters into tokens, it does some jobs.

1. It throws away the operating system provided end-of-record byte (if any; some old operating systems don't have it) and everything that remains in the line after it.

2. It throws away all spaces that might remain at the end of the record (and tabs, under implementations based on Web2C, which are the most commonly used). This independently of category code, as they have not yet been attached to characters.

3. It adds at the end of the record the current \endlinechar (none if the parameter is negative or beyond the engine dependent maximum value, which is 255 for TeX and pdftex, 0x1FFFFF for XeTeX and LuaTeX).

4. It does what is prescribed by its current state with respect to category code 5 and 10 characters; under normal circumstanes it throws away initial spaces and it possibly inserts a \par token (see the TeXbook or TeX by Topic for details).

5. Now it starts tokenizing and it's here where comments are discarded: a category code 14 character causes TeX to ignore it and everything up to the end of the line, the added \endlinechar included.

One might think to define % as an active character, which looks for a following % and, in this case, inserts a category code 14 character in the input. Maybe doing this only in the document environment, so that comments work as usual in the preamble. This fails in two ways.

1. If TeX is not expanding macros, the %% pair would be recognized too late. For example

\parbox{abc %%
def}


wouldn't work as expected, because the active % wouldn't be expanded when the argument to \parbox is absorbed.

2. Even if one ensures that no %% pair is in the argument to a macro, it's impossible to put a character code 14 character in the replacement text of a macro: no category code 0, 5, 9, 14 and 15 character can reach TeX's "stomach", where macro replacement texts are examined and stored in memory (TeXbook, exercise 7.3).

One might think to overcome this limitation by defining % to look for a following % and, in this case, to issue a macro \gobbletoend defined by something like

\def\gobbletoend%1^^M{}


but, alas, this can't be done for two reasons: ^^M (category code 5) can't reach TeX's stomach and, moreover, TeX wouldn't even see the pair of braces, because, when absorbing that line it would see ^^M which is the ASCII end-of-line and it would throw it away with the rest of the line. So the macro can't have its argument delimited by a category code 5 ^^M, which is something like \obeylines does, but you don't want that every end-of-line that's not preceded by %% has a final \par, so the definition ought to be much more complicated.

A possible way is to do like in the following example:

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\begingroup\lccode~=\%
\lowercase{\endgroup\def~{\new@ifnextchar~\tohecz@comment\%}}
\def\tohecz@comment{\catcode\^^M=3 \tohecz@commentignore}
\begingroup\lccode$=\^^M \lowercase{\endgroup\def\tohecz@commentignore#1$}{\catcode\^^M=5 }
\makeatother

\begin{document}
\catcode\%=\active

abc %% def

abc % def

abc %

def
\end{document}


The Kant paragraph is just to show that paragraphs are correctly terminated; \new@ifnextchar from amsmath is used to avoid gobbling spaces. Recall, however, that %% can't appear in the argument to a command.

-

ConTeXt provides a macro \asciimode (and an environment \startasciimode ... \stopasciimode) which makes all characters except \ and { and } behave as normal characters. Inside this environment % behaves like a normal character, and %% behaves like the comment character.

Note: % and %% work correctly inside arguments to a macro.

\setuppapersize[A7]
\starttext
\rightaligned{\asciimode Hello! %World
%% This is a comment
}

% Normal comment

\asciimode

\rightaligned{Hello! again %World
%% This is a comment
}

I use to forget to escape up to 70 % of my percent-signs, which causes missing
ends of sentences. asciimode simply typesets them corrects. And also typesets
all special characters # & \$ correctly.

%% On the other hand, sometimes I really need to make a comment, so I want to
%% use a double-percent-sign for that.

And of course, the 30 \% of escaped percent-signs should work correctly.

\stoptext


-
Interesting and thanks! However, I'm sticked to LaTeX. Still, is it possible to extract the definition of the macro and use it in LaTeX? –  tohecz Oct 20 '12 at 19:24
FWIW, \asciimode does two things: sets an appropriate catcode table, and hooks into the line reader to set %% as comment. The first is doable in pdftex but the second requires luatex. If you want to implement %% acting as comment in pdftex, you need to set % to be an active character, and check the next token to see if it is % or not. If you are using lualatex, then porting the definition should be simple (but I don't know what interface lualatex provides for hooking into the line reader). –  Aditya Oct 20 '12 at 19:38
@egreg: Yes, \asciimode works correctly inside macros as well. See the edited answer. In fact, \asciimode even works correctly if it is called inside a macro, provided there is a line break before %% is used (\asciimode changes the line-reader, so if the current line has already been read, it will not change it). –  Aditya Oct 20 '12 at 21:23
I'd suggest using regular expressions to find all the instances of a single % that isn't escaped.
If you're using Unix, then grep % doc.tex | grep -v %% | grep -v '\\%'` should do just that. Alternatively, if your text editor can find and replace based on a regex, then you should be able to easily change them all.