3

I'd like to define a macro that can be used to toggle comments on/off for specific combinations of lines; however, I'm not sure how one can bind % to a macro's output. Is this possible?

e.g. I'd like to define \tlc (temporary line comment) something like \newcommand{\tlc}{%} such that

line 1
\tlc line 2
\tlc line 3
line 4
line 5
\tlc line 6

would comment out lines 2, 3 and 6 and that redefining the macro to something like \newcommand{\tlc}{} would print all the lines.

2
  • 1
    Short answer: no.
    – egreg
    Jan 31 '21 at 17:06
  • You can hide/show comments in another ways (withiut using %, e.g. here).
    – Fran
    Jan 31 '21 at 17:34
6

Sometimes I toggle like this between commenting and not commenting:

\documentclass{article}

\begin{document}

\catcode`\^^A=14 % catcode 14 = comment
% now stuff behind ^^A is comment:
line 1
^^Aline 2
^^Aline 3
line 4
line 5
^^Aline 6
^^A\csname @firstofone\endcsname{%
^^A  Line7%
^^A}%

\catcode`\^^A=9 % catcode 9 = ignore
% now stuff behind ^^A is processed:
line 1
^^Aline 2
^^Aline 3
line 4
line 5
^^Aline 6
^^A\csname @firstofone\endcsname{%
^^A  Line7%
^^A}%

\end{document}

^^A is TeX's ^^-notation for denoting the SOH-character which has code-point-number 1 in the TeX-engine's internal character representation-scheme, which with traditional TeX is ASCII and with LuaTeX and XeTeX is unicode.

You can use any character not in use within the code where toggling commenting/not commenting is needed. When you do so, don't forget to reset the character's category code to its usual value before resorting to using it in its usual way, e.g.,

\documentclass{article}

\begin{document}

\catcode`\X=14 % catcode 14 = comment
% now stuff behind X is comment:
line 1
Xline 2
Xline 3
line 4
line 5
Xline 6
X\csname @firstofone\endcsname{%
X  Line7%
X}%

\catcode`\X=9 % catcode 9 = ignore
% now stuff behind X is processed:
line 1
Xline 2
Xline 3
line 4
line 5
Xline 6
X\csname @firstofone\endcsname{%
X  Line7%
X}%

% Make sure the catcode of X is reset to its usual value
% before resorting to using X as letter.
\catcode`\X=11

\end{document}


With a hypothetical macro \tlc or with the environments provided by the package comment the stuff commented out needs to be processed for dropping it.

With the approach of toggling commenting/not commenting via toggling catcodes the stuff commented out is not tokenized/processed at all.
Therefore with the latter approach brace-balancing does not matter.
And the latter approach can also be used for commenting out snippets of code that belong to the ⟨definition text⟩ of a macro.

I.e., this does !!!not!!! work:

\documentclass{article}
\usepackage{comment}
%\includecomment{mycomment}
\excludecomment{mycomment}

\newcommand\mymacro{%
  This in any case is part of the definition text.
  \begin{mycomment}
  This is part of the definition text only if mycomment is included.
  \end{mycomment}
}%
[...]
\begin{document}
[...]
\end{document}

This does work:

\documentclass{article}
%\catcode`\^^A=9
\catcode`\^^A=14

\newcommand\mymacro{%
  This in any case is part of the definition text.
  ^^AThis is part of the definition text only if SOH has catcode 9.
}%
[...]
\begin{document}
[...]
\end{document}
2
  • Which is similar to what the doc package does for .dtx files.
    – egreg
    Jan 31 '21 at 22:24
  • @egreg Somewhere in the code for doc or docstrip SOH/^^A is used as comment-character. Iirc with doc % is for comments as usual. With docstrip everything is read/tokenized/processed - lines beginning with % are evaluated for detecting tags and copying to files that are generated. Feb 1 '21 at 10:03
5

I don't see any way to use % specifically, but you can get the output you're looking for by defining \tlc to take whatever is between \tlc and the end of the line, and just don't do anything with it. Here's a complete example, where the definition of \tlc is based on @egreg's answer here.

\documentclass{article}
\def\tlc{\begingroup\catcode`\^^M=12 \xtlc}
{\catcode`\^^M=12 %
    \gdef\xtlc#1^^M{\endgroup}%
}
%\newcommand*{\tlc}{}
\begin{document}
line 1
\tlc line 2
\tlc line 3
line 4
line 5
\tlc line 6
\end{document}

This outputs

If you remove the definition of \tlc and replace it with the commented line \newcommand*{\tlc}{}, then the output is the following.

That being said, I would not recommend to do that: usually defining exotic commands like this requires to really know what you're doing. I'm not sure of everything that can go wrong with this specific command, but for example if you put a lone { (as @frougon suggested) on a line beginning with \tlc, an error will be raised. I would not be surprised by other unexpected behaviors, especially considering @egreg's comment above.

I would tend to use a more standard syntax. For example, you could define \tlc to have one mandatory argument, and either print it or not depending on whether you want the commented lines. Something like

\newcommand*{\tlc}[1]{#1}

or

\newcommand*{\tlc}[1]{}

You could also use the comment package, which provides an environment where the content is commented out.

3
  • 4
    +1 because it's interesting, but try replacing \tlc line 2 with \tlc line 2{ for instance. :)
    – frougon
    Jan 31 '21 at 17:57
  • @frougon Thanks for the example! I will add it to the answer.
    – Vincent
    Jan 31 '21 at 18:10
  • 1
    The TeX rule behind my example is that a macro argument must be brace-balanced. So, your \tlc will fail with any line that is not balanced with respect to character tokens with category codes 1 and 2 (I suppose some brace hacks could be used...).
    – frougon
    Jan 31 '21 at 18:27

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.