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
(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}
\askreplymcq__verify:nnto see what the arguments are. – user202729 Mar 24 '22 at 16:16\askreplymcq__verify:nndirectly with those arguments, does it work? – user202729 Mar 24 '22 at 16:27\askreplymcq__verify:nn, as you can tell. What makes it different from\mcqcheck? (I assume\mcqcheckdoes work?) – user202729 Mar 24 '22 at 16:33\askreplymcq__verify:nnbut I don't see where. – ejazz Mar 24 '22 at 16:36expl3and also would be grateful if a solution can be found. – ejazz Mar 24 '22 at 16:39askreplymcq__verify:nndifferent frommcqcheckeven though the definition seems to be exactly the same. (it's not about\cs_newversus\NewDocumentCommand) – user202729 Mar 24 '22 at 16:40\mcqcheckmacro does not need this method – ejazz Mar 24 '22 at 16:48\ExplSyntaxOn. – user202729 Mar 24 '22 at 16:57varandiis eliminated, so you can either do the newdocumentcommand then\let \askreplymcq__verify:nn \mcqcheck; or write it likevar~i. – user202729 Mar 24 '22 at 17:59expl3does not care about the spaces. You are right! Thant you very much, that works like a charm! – ejazz Mar 24 '22 at 18:14