0

Thanks to @AlexG and @Marcel Kruger, elaborating MCQs can be done with the different links below.

(1) ocgx2: verify and reset of Multiple Choice Questions with OCGs

(2) ocgx2, xparse, expl3: splitting comma separated OCMD/OCGs lists of arguments for references automation

(3) ocgx2: Multiple Choice Questions up to three automatic trials

This gives the actual context, but the issue deals with splitting the arguments lists in order to automate the Ids and references for the third link above. For the two first links, it works fine.

From the MWE below, the "manual" method where one has to type in all the Ids (\mcqcheck macro and Check button) works as expecting and the "automatic" method (\mcqverify) fails.

I don't understand this behaviour because the spliting of arguments then their rebuilt are effective inside the \mcqverify command. What is the mistake I make?

\documentclass{article}

\usepackage[tikz]{ocgx2} \usepackage{media9} % \mediabutton \usepackage{animate}

\usepackage{fontawesome5} \usepackage{wasysym} % \Circle, \CIRCLE \usepackage{calc} % \widthof{...}

\newcounter{quiz}% \newcounter{quizquestion}[quiz]

\newcounter{mcqproposal}[quizquestion]% Proposal IDs counter to choose within a quiz question \newcounter{mcqquiztotal}[quizquestion]% Total proposals counter within a quiz question

\newlength{\quizcheckboxwidth}

% quiz statement \NewDocumentCommand{\mcqproposal}{m}{% % Syntax − #1 = proposal/statement text \stepcounter{mcqproposal} \stepcounter{mcqquiztotal}% % action on click: toggle myself (choice layer), hide verifcation layer \setlength{\quizcheckboxwidth}{\widthof{\faIcon[regular]{square}}}% \makebox[\quizcheckboxwidth][c]{% \actionsocg{mcqproposalref.\thequiz.\thequizquestion.\themcqproposal}% {}{verify.\thequiz.\thequizquestion}{\faIcon[regular]{square}}% }% \begin{ocg}{mcqproposalref.\thequiz.\thequizquestion.\themcqproposal}% {mcqproposalref.\thequiz.\thequizquestion.\themcqproposal}{off}% choice layer \hspace{-\quizcheckboxwidth}% \makebox[\quizcheckboxwidth][c]{\textcolor{green!60!black}{\faCheckSquare}}% \end{ocg}% \parbox[t]{\linewidth}{\hspace{6pt}#1}% }

% reset button \NewDocumentCommand{\mcqreset}{}{% \def\ocglistreset{}% \xdef\ocglistreset{% \ocglistreset\space verify.\thequiz.\thequizquestion}% \foreach \X in {1,...,\value{mcqquiztotal}} {% \xdef\ocglistreset{\ocglistreset\space mcqproposalref.\thequiz.\thequizquestion.\X}% }% %\ocglistreset \hideocg{\ocglistreset}{\fbox{\strut Reset}}% }

\ExplSyntaxOn

\NewDocumentCommand{\askreplymcqArgsIds}{m}{% % Syntax − #1: proposal/statement number within a question mcqproposalref.\thequiz.\thequizquestion.#1% }

\NewDocumentCommand{\mcqverify}{ m m }{% % Syntax − #1: list of OCG ids of correct/required answer(s), comma separated % #2: list of OCG ids of wrong answer(s), comma separated \askreplymcq_process_list:Nn \l_correct_seq { #1 }% Save OCMD IDs as LaTeX3 seq variable \askreplymcq_process_list:Nn \l_wrong_seq { #2 }% Save OCMD IDs as LaTeX3 seq variable \askreplymcq__verify:ff { \seq_use:Nn \l_correct_seq {,} } { \seq_use:Nn \l_wrong_seq {,} } }

\cs_new_protected:Npn \askreplymcq_process_list:Nn #1 #2 { % clear the sequence \seq_clear:N #1 % cycle through the arguments, storing "\askreplymcqArgsIds{<arg>}" in the sequence \clist_map_inline:nn { #2 } { % Here :Nx instead of :Nn ensures that \askreplymcqArgsIds % is actually evaluated instead of passed as-is \seq_put_right:Nx #1 { \askreplymcqArgsIds{##1} } } }

\seq_new:N \l_correct_seq \seq_new:N \l_wrong_seq

\cs_new_protected:Npn \askreplymcq__verify:nn #1 #2 {% \mediabutton[jsaction={% var ocgs=this.getOCGs(this.pageNum);% for(var i=0;i<ocgs.length;i++){% if(ocgs[i].name=="verify.\thequiz.\thequizquestion"% &&ocgs[i].state==false% &&anim["verify.\thequiz.\thequizquestion"].frameNum<3){% ocgs[i].state=true;% anim["verify.\thequiz.\thequizquestion"].frameNum++;% }% }% }]{\fbox{\strut Verify}}\space% \begin{animateinline}[label=verify.\thequiz.\thequizquestion,nomouse,step]{1} \strut\Circle\ \Circle\ \Circle \newframe \strut\CIRCLE\ \Circle\ \Circle \newframe \strut\CIRCLE\ \CIRCLE\ \Circle \newframe \strut\CIRCLE\ \CIRCLE\ \CIRCLE \end{animateinline}\quad% \begin{ocg}{verify.\thequiz.\thequizquestion}% {verify.\thequiz.\thequizquestion}{off}% verification layer \makebox[0pt][l]{% \begin{ocmd}{\Not{\And{#1,\Not{\Or{#2}}}}}% "wrong" layer (OCMD) Wrong% \end{ocmd}% }% \begin{ocmd}{\And{#1,\Not{\Or{#2}}}}% "correct" layer (OCMD) Correct% \end{ocmd}% \end{ocg}% }

\cs_generate_variant:Nn \askreplymcq__verify:nn {ff}

\ExplSyntaxOff

\NewDocumentCommand{\mcqcheck}{m m}{% % Syntax − #1: list of OCG ids of correct answer(s), comma separated % #2: list of OCG ids of wrong answer(s), comma separated \mediabutton[jsaction={% var ocgs=this.getOCGs(this.pageNum);% for(var i=0;i<ocgs.length;i++){% if(ocgs[i].name=="verify.\thequiz.\thequizquestion" &&ocgs[i].state==false &&anim["verify.\thequiz.\thequizquestion"].frameNum<3){% ocgs[i].state=true;% anim["verify.\thequiz.\thequizquestion"].frameNum++;% }% }% }]{% \fbox{\strut Check}}\space% \begin{animateinline}[label=verify.\thequiz.\thequizquestion,nomouse,step]{1} \strut\Circle\ \Circle\ \Circle \newframe \strut\CIRCLE\ \Circle\ \Circle \newframe \strut\CIRCLE\ \CIRCLE\ \Circle \newframe \strut\CIRCLE\ \CIRCLE\ \CIRCLE \end{animateinline}\quad% \begin{ocg}{verify.\thequiz.\thequizquestion}% {verify.\thequiz.\thequizquestion}{off}% verification layer \makebox[0pt][l]{% \begin{ocmd}{\Not{\And{#1,\Not{\Or{#2}}}}}% "wrong" layer (OCMD) Wrong. \end{ocmd}% }%
\begin{ocmd}{\And{#1,\Not{\Or{#2}}}}% "correct" layer (OCMD) Correct. \end{ocmd}% \end{ocg}%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\parindent=0pt \begin{document}

\stepcounter{quiz} \stepcounter{quizquestion}

Which are the colour components of an RGB image? Multiple required assertions.\[8pt] \mcqproposal{Magenta.} \mcqproposal{Green.} \mcqproposal{Cyan.} \mcqproposal{Blue.} \mcqproposal{Red.} \mcqproposal{Black.} \mcqproposal{Yellow.}\[8pt]

\mcqcheck{mcqproposalref.\thequiz.\thequizquestion.2,mcqproposalref.\thequiz.\thequizquestion.4,mcqproposalref.\thequiz.\thequizquestion.5}{mcqproposalref.\thequiz.\thequizquestion.1,mcqproposalref.\thequiz.\thequizquestion.3,mcqproposalref.\thequiz.\thequizquestion.6,mcqproposalref.\thequiz.\thequizquestion.7}% % \mcqverify{2,4,5}{1,3,6,7} \hspace{0.1\linewidth} \mcqreset

\end{document}

ejazz
  • 1,047
  • Try to print out the content of the argument at the start of \askreplymcq__verify:nn to see what the arguments are. – user202729 Mar 24 '22 at 16:16
  • I have tried that. The arguments are correct: mcqproposalref.\thequiz.\thequizquestion.\themcqproposal. – ejazz Mar 24 '22 at 16:26
  • If you call \askreplymcq__verify:nn directly with those arguments, does it work? – user202729 Mar 24 '22 at 16:27
  • ? what does that mean? – user202729 Mar 24 '22 at 16:31
  • Okay, so the problem is likely in the definition of \askreplymcq__verify:nn, as you can tell. What makes it different from \mcqcheck? (I assume \mcqcheck does work?) – user202729 Mar 24 '22 at 16:33
  • If I call \mcqverify{mcqproposlref....} it compiles but not gives correct results as expected. – ejazz Mar 24 '22 at 16:34
  • By the way, do you want some guide to learn expl3, or just want someone to give you a macro that works? – user202729 Mar 24 '22 at 16:35
  • yes the issue seems to be in \askreplymcq__verify:nn but I don't see where. – ejazz Mar 24 '22 at 16:36
  • I'am trying to anderstand expl3 and also would be grateful if a solution can be found. – ejazz Mar 24 '22 at 16:39
  • Okay, think about how is askreplymcq__verify:nn different from mcqcheck even though the definition seems to be exactly the same. (it's not about \cs_new versus \NewDocumentCommand) – user202729 Mar 24 '22 at 16:40
  • That's why I don't understand: their definition are the same. – ejazz Mar 24 '22 at 16:42
  • Okay, you see one is defined within expl syntax region, the other is not. What does it mean? – user202729 Mar 24 '22 at 16:44
  • It's in order to split and rebuilt easily the lists of arguments the \mcqcheck macro does not need this method – ejazz Mar 24 '22 at 16:48
  • I don't think you understood it correctly, Read the documentation of \ExplSyntaxOn. – user202729 Mar 24 '22 at 16:57
  • OK thank you for the advice. – ejazz Mar 24 '22 at 17:00
  • 1
    Anyway, I think one of the issue is that the space between e.g. var and i is eliminated, so you can either do the newdocumentcommand then \let \askreplymcq__verify:nn \mcqcheck; or write it like var~i. – user202729 Mar 24 '22 at 17:59
  • How silly I am! I forgot that expl3 does not care about the spaces. You are right! Thant you very much, that works like a charm! – ejazz Mar 24 '22 at 18:14

0 Answers0