6

I am designing question papers comprising of multiple choice questions. The answers are to be marked by blackening the appropriate answers (more than one may be correct) in an answer sheet. In my latex file I indicate the correct choices by a \correct tag which prints a bullet in that option. This scheme is controlled by a commented line

%\renewcommand{\correct}{} % comment out for printing the solution

If the above is commented, only then the solutions are indicated in the output PDF file. If uncommented, it prints a valid question paper instead.

I want the same scheme to automatically mark the corresponding option in the answersheet as a semi-opaque black filled circle. However I have no idea how to mark the correct options as the darkened circle. Any help would be appreciated.

Please see the MWE here --

\documentclass[11pt]{article}
\usepackage{tasks,pgffor,tikz,xsim,multicol}

\settasks{
    counter-format = (tsk[a]),
    label-format = \itshape,
    item-indent = 0em, 
    label-offset=.6em, 
    label-align=right, 
    before-skip = 0pt, 
    after-item-skip=0pt
}

\newcommand\encircle[1]{%
    \tikz[baseline=(X.base)] 
    \node (X) [draw, shape=circle, inner sep=-1pt] {\strut #1};
}

% mcqoptions environment is seemingly dummy only in this MWE. In actual document it does a lot more. 
\newenvironment{mcqoptions}{
    \tasks(4)
}{
    \endtasks
}

\setlength{\columnseprule}{0.4pt}
\newcommand{\correct}{$\bullet$}

\newcommand{\answerspace}[1]{%
    \foreach \x in {1,...,#1} {%
        \noindent\hspace*{2em}\llap{[\textbf{\x}]} \encircle{$a$}\,\encircle{$b$}\,\encircle{$c$}\,\encircle{$d$}\hfill\newline%
    }%
}

% If the following line is not commented out, mark all correct answers by blackening the corresponding circle.
%\renewcommand{\correct}{} % comment out for printing the solution

\begin{document}
    One or more options of the following questions may be correct.
    \begin{multicols}{2}    
        \begin{exercise}
            Why o why
            \begin{mcqoptions}
                \task \correct $ \frac{e+2}{e} $ \task $ \frac{e-2}{e} $ \task $ \frac{2}{e} $ \task $ \frac{2-e}{e} $
            \end{mcqoptions}
        \end{exercise}

        \begin{exercise}
            For a reaction in an aqueous medium at a given pH of volume 
            \begin{mcqoptions}
                \task q \task \correct w \task e    \task \correct r
            \end{mcqoptions}
        \end{exercise}

        \begin{exercise}
            $\frac{\tan x-\log(1+x)+x^2}{x^2} =$
            \begin{mcqoptions}
                \task \correct 3/2 \task \correct 1/2 \task 5/2 \task 1 
            \end{mcqoptions}
        \end{exercise}

        \begin{exercise}
            How much heat is gained by the environment in the process? 
            \begin{mcqoptions}
                \task 1170 \task 5080 \task 2350 \task \correct 3690
            \end{mcqoptions}
        \end{exercise}
    \end{multicols} 
    \vspace{.5cm}
    \hrule
    \vspace{.1cm}
    \textbf{Mark your answers below}
    \vspace{.1cm}
    \hrule
    \begin{multicols}{2}
        \answerspace{4}
    \end{multicols}
\end{document}

An image -- MWE image

4

The tasks package uses LaTeX3/expl3 so the only way to get hold of the task number is to use expl3. [OK, you could use expl3 only to extract the task number, which is stored as \g__tasks_int, and then use "plain latex" but if you start using expl3 you might as well continue using expl3.]

In the MWE below I have added some code to the \correct macro so that whenever it is used to mark an answer as correct the task number is added to an expl3 sequence for the current question (the name of the sequence is of the form g_correct_#1_seq where #1 is \theexercise). Later, in the \answerspace macro, we check to see if the current option is "marked" as correct by checking for membership of this sequence and then adding fill=blue!10 to the node if this option is correct. As a consequence, with the code below, the answer section of the MWE looks like:

enter image description here

Here is the code:

\documentclass[11pt]{article}
\usepackage{tasks,pgffor,tikz,xsim,multicol}
\usepackage{etoolbox}
\settasks{
    counter-format = (tsk[a]),
    label-format = \itshape,
    item-indent = 0em,
    label-offset=.6em,
    label-align=right,
    before-skip = 0pt,
    after-item-skip=0pt
}

\newcommand\encircle[2][]{% optional argument allows for fill
    \tikz[baseline=(X.base)]
    \node (X) [draw, shape=circle, inner sep=-1pt, #1] {\strut$#2$};
}

% mcqoptions environment is seemingly dummy only in this MWE. 
% In actual document it does a lot more.
\newenvironment{mcqoptions}{
    \tasks(4)
}{
    \endtasks
}

\setlength{\columnseprule}{0.4pt}
  \newif\ifcorrecting
  \correctingtrue% comment out to not print solutions
  \ExplSyntaxOn
  \newcommand{\correct}{%
    $\bullet$%
    \ifcorrecting%
      \l_add_to_sequence {\theexercise} {\int_use:N \g__tasks_int}%
    \fi%
  }

\newcommand{\answerspace}[1]{%
    \foreach \x in {1,...,#1} {%
        \noindent\hspace*{2em}\llap{[\textbf{\x}]}\space
        \foreach \y in {1,2,3,4} {% answers are stored as integers
          \l_encircle {\x} {\y}\,% circle the node, possibly with fill
        }\hfill\newline%
    }%
}

% add #2 to the sequence g_correct_#1_seq, creating it if it does not exist
\cs_new_protected:Npn \l_add_to_sequence #1#2 {
  \seq_if_exist:cF {g_correct_#1_seq} {\seq_new:c {g_correct_#1_seq} }
  \seq_gput_right:cx {g_correct_#1_seq} {#2}
}
% test if correct and then draw the node using \encircle
\cs_new_protected:Npn \l_encircle #1#2 {
   \seq_if_in:coTF {g_correct_#1_seq} {#2}
       { \encircle[fill=blue!10]{\int_to_alph:n{#2}} }
       { \encircle{ \int_to_alph:n{#2}} }
}
\ExplSyntaxOff

% If the following line is not commented out, mark all correct answers by blackening the corresponding circle.

\begin{document}
    One or more options of the following questions may be correct.
    \begin{multicols}{2}
        \begin{exercise}
            Why o why
            \begin{mcqoptions}
                \task \correct $ \frac{e+2}{e} $ \task $ \frac{e-2}{e} $ \task $ \frac{2}{e} $ \task $ \frac{2-e}{e} $
            \end{mcqoptions}
        \end{exercise}

        \begin{exercise}
            For a reaction in an aqueous medium at a given pH of volume
            \begin{mcqoptions}
                \task q \task \correct w \task e    \task \correct r
            \end{mcqoptions}
        \end{exercise}

        \begin{exercise}
            $\frac{\tan x-\log(1+x)+x^2}{x^2} =$
            \begin{mcqoptions}
                \task \correct 3/2 \task \correct 1/2 \task 5/2 \task 1
            \end{mcqoptions}
        \end{exercise}

        \begin{exercise}
            How much heat is gained by the environment in the process?
            \begin{mcqoptions}
                \task 1170 \task 5080 \task 2350 \task \correct 3690
            \end{mcqoptions}
        \end{exercise}
    \end{multicols}
    \vspace{.5cm}
    \hrule
    \vspace{.1cm}
    \textbf{Mark your answers below}
    \vspace{.1cm}
    \hrule
    \begin{multicols}{2}
        \answerspace{4}
    \end{multicols}
\end{document}

Note that I have used fill=blue~10 to mark correct answers as fill=black is too dark. This is done using standard tikz, so it can be easily changed to suit your needs.

The code above can almost certainly be made more efficient. As far as I can see the only way to create a sequence with a dynamic name, such as the sequences \g_correct_1_seq, \g_correct_2_seq, ... above, is to do this in two steps. This is partly why I have separate functions \cs_new_protected:Npn and \cs_new_protected:Npn.

Note that have added \newif\ifcorrecting so that you can add/remove the shading of the answers by adding \correctingtrue and \correctingfalse, respectively.

Finally, I should say that the double underline means that \g__tasks_int is a "protected" variable in the code for the tasks package, which means that it may change in future releases so that we should not really use it. This said, I don't see any other choice since we need to access the value of this counter and, as far as I could tell, the package does not provide a hook.

6
  • Thanks a lot. I had already picked up LuaLaTeX manuals and thought about a dirty scheme of implementing it. Your suggestion is better for cross-platform availability. However your code does not compile well. I have modified the code and used a dirty arrayjob hack to convert numbers to letters as well.
    – magguu
    Dec 23 '17 at 3:17
  • @magguu Please edit the modified, non-working code into your question instead of editing this answer. This space is only meant for answers to the question.
    – Troy
    Dec 23 '17 at 4:06
  • @Troy the code in the question works well. The intent of the question is to add new desired functionality. This answer adds that functionality but the included code didnt compile (I have TeXlive-2017). I made some minor modifications to it so that it works. That is the code I added as my edit. I did not provide any original answer.
    – magguu
    Dec 23 '17 at 4:12
  • 1
    @magguu Sorry, there was an extra { somewhere. I have just taken this out and changed the output so that letters are printed for the tasks.
    – user30471
    Dec 23 '17 at 19:33
  • 1
    @magguu The expl3 code is incredibly powerful and versatile but it is also full of so many idiosyncratic commands that one somehow just has to find and then remember... I learned about \int_to_alph:n only when I tried to fix my solution to fully answer your question:)
    – user30471
    Dec 24 '17 at 14:40

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.