# How can I redefine a command to omit the material on the line that starts with the command?

I have designed a quiz with hundreds of questions and answers in a list. The answer to a given question is on the line immediately below it, but not all questions have answers provided. The LaTeX code for a shorter version of the quiz appears below.

\documentclass{article}

\newcommand{\qsn}{\item[$\bullet$] \normalfont}
\newcommand{\ans}{\item[$\circ$] \bfseries}
%\newcommand{\ans}{%} % this doesn't work

\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}


Now I would like to prepare a second version of the quiz, but with the answers omitted (just in the final PDF document, not in the LaTeX file). Is there a quick way of doing this by redefining only \ans? My initial thought was to redefine \ans by \newcommand{\ans}{%}, but of course that won't work. I've looked at packages like comment and versions, but they all seem to require either braces or a \begin/\end pair around the material to be omitted. I also want to be able to go back and forth easily between versions of the quiz by just using the appropriate definition for \ans (i.e., by putting a % in front of the definition I don't want to use).

Thanks.

• See tex.stackexchange.com/a/10454/2388. With the code provided there you can use replace your \newcommand\ans.. with \newlinecommand{\ans}{} May 27, 2015 at 7:26
• Thanks to everyone who responded. All solutions did the trick. I didn't expect so many different approaches to the problem. I think I'll go with Mr. Carlisle's, as it seems to be the shortest. May 27, 2015 at 22:40

You can define \ans to put its text into a temporary unused box, terminated by either \end or \qsn. The main restriction here is that if you have a nested environment inside the answer you must surround it by {...} so that the first top level \end that is seen is the \end{list}

\documentclass{article}

\newcommand{\qsn}{\item[$\bullet$] \normalfont}

%\newcommand{\ans}{\item[$\circ$] \bfseries}
%\newcommand{\ans}{%} % this doesn't work
\newcommand\ans{\setbox0\vbox\bgroup%
\def\qsn{\egroup\qsn}%
\def\end{\egroup\end}}

\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}


Define \ans as a command that looks for the next end of line (but you have better to be sure that your answers are just one liners).

\documentclass{article}

\newcommand{\qsn}{\item[$\bullet$]}

\newcommand\ans{\begingroup\catcode\^^M=12 \xans}
{\catcode\^^M=12 %
\gdef\xans#1^^M{\ifshowanswers\item[$\circ$]\bfseries #1\fi\endgroup}%
}

\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}


This is the output if the line \showanswerstrue is commented out:

If you can't guarantee that the answers are on one line, something more complex must be used and it's necessary to change your \begin{list} into something else.

\documentclass{article}
\usepackage{xparse,l3regex,environ}

\newcommand{\qsn}{\item[$\bullet$]\normalfont}
\newcommand{\ans}{\item[$\circ$]\bfseries}
\newcommand{\questionterminator}{}

\ExplSyntaxOn
\NewEnviron{questions}
{
\begin{list}{$\bullet$}{}
\BODY
\else
\tl_put_right:Nn \BODY { \questionterminator }
\regex_replace_all:nnN { \c{ans}.*?(\c{qsn}|\c{questionterminator}) } { \1 } \BODY
\BODY
\fi
\end{list}
}
\ExplSyntaxOff

\begin{document}
\begin{questions}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{questions}
\end{document}


The outputs are exactly the same.

IMP Note: As correctly pointed out by @egreg, this method DOES NOT omit the answers, instead it prints them in the same line as that of the question. The only way to make it work, is to NOT USE the modified \ans command and use the \hashed{} command directly to hide the answers, as shown by the updated code. However, the O.P.'s request was for a simple switch between "answers" and "no-answers" in the output PDF; where, this particular solution fails!

Simply use the \hashed{} command to omit the desired text from your PDF!

\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
\newcommand{\ans}{\item[$\circ$] \bfseries} % -- v1 : prints answers
\newcommand{\hashed}[2]{#2} % -- hashes out the selected text: \hashed{I want to hide!}
%\newcommand{\ans}{\hashed{\item[$\circ$] \bfseries}} % -- v2 : USELESS!
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
%\ans Green, red, and white.
\hashed{\ans Green, red, and white.}
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
%\ans Nine.
\hashed{\ans Nine.}
\end{list}
\end{document}

\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
\newcommand{\ans}{\item[$\circ$] \bfseries} % -- v1 : prints answers
\newcommand{\hashed}[2]{#2} % -- hashes out the selected text: \hashed{I want to hide!}
%\newcommand{\ans}{\hashed{\item[$\circ$] \bfseries}} % -- v2 : USELESS!
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
%\hashed{\ans Green, red, and white.}
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
%\hashed{\ans Nine.}
\end{list}
\end{document}

• Sorry, but this code prints the answers on the same line, next to the question and does not produce the image you show. May 27, 2015 at 7:07
• @egreg I am not sure how you arrived at that conclusion. But, I have appended my answer to show that the answers are not printed on the same line with my code. In fact, the result is exactly the same as that of your or David Carlisle 's solution. All you have to do is switch-off the modified command and switch-on the original command to show answers and vice-a-versa to hide them, using my code. How the two of us can get different results using the same code? I am baffled!
– Amar
May 27, 2015 at 12:21
• Here's the picture of what I get with the “don't show answers” code i.stack.imgur.com/FMn6q.png May 27, 2015 at 13:38
• @egreg You are absolutely correct! It was my mistake, I had cropped the image before posting here! I am adding the correction to my answer. However, is there a way to make \hashed behave?
– Amar
May 27, 2015 at 14:50
• In retrospect, a -10 for my own answer. :(
– Amar
Sep 29, 2016 at 9:00

If the answer is limited by the end of line and there are no two liners, then it's a job for package eolgrab (the first example of egreg's answer shows the manual way).

\documentclass{article}
\usepackage{eolgrab}

\newcommand{\qsn}{\item[$\bullet$] \normalfont}
%\newcommand{\ans}{\item[$\circ$] \bfseries}

\makeatletter
\newcommand{\ans}{\eolgrab{\@gobble}}
\makeatother

\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}


Remarks:

\@gobble is a LaTeX kernel macro, which just discards its argument. Also a new macro can be defined to avoid \makeatother and \makeatletter:

\newcommand{\ans}{\eolgrab{\GobbleOne}}
\newcommand{\GobbleOne}[1]{}


If an answer can have several lines and is then limited by either the next \qsn or \end of the end of list, then the following can be used:

\documentclass{article}
\usepackage{eolgrab}

\newcommand{\qsn}{\item[$\bullet$] \normalfont}
%\newcommand{\ans}{\item[$\circ$] \bfseries}

\makeatletter
\newcommand{\ans}{\eolgrab{\@ans}}
\newcommand*{\@ans}[1]{%
\@ifnextchar\qsn{}{%
\@ifnextchar\end{}{\ans}%
}%
}
\makeatother

\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green,
red,
and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}


Remarks:

\@ifnextchar is a LaTeX kernel macro, which checks the next token (space tokens are silently removed). Usually it is used to detect [ of an optional argument, but it can be used for other tokens as well.