3

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}{} – Ulrike Fischer May 27 '15 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. – smith May 27 '15 at 22:40
2

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}

enter image description here

\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} 
|improve this answer|||||
1

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$]}

\newif\ifshowanswers
\newcommand\ans{\begingroup\catcode`\^^M=12 \xans}
{\catcode`\^^M=12 %
 \gdef\xans#1^^M{\ifshowanswers\item[$\circ$]\bfseries #1\fi\endgroup}%
}
\showanswerstrue % comment to turn off showing the answers

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

enter image description here

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

enter image description here

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$}{}
  \ifshowanswers
    \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

\newif\ifshowanswers
%\showanswerstrue % comment to turn off showing the answers

\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.

|improve this answer|||||
1

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!

MWE for omitting answers (Updated):

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

Result with answers omitted (Updated):

enter image description here

MWE for displaying answers (Updated):

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

Result with answers displayed (Updated):

enter image description here

|improve this answer|||||
  • 3
    Sorry, but this code prints the answers on the same line, next to the question and does not produce the image you show. – egreg May 27 '15 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 '15 at 12:21
  • Here's the picture of what I get with the “don't show answers” code i.stack.imgur.com/FMn6q.png – egreg May 27 '15 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 '15 at 14:50
  • In retrospect, a -10 for my own answer. :( – Amar Sep 29 '16 at 9:00
1

One-line answers

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}

Result

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]{}

Answers with several lines

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.

|improve this answer|||||

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.