ocgx2,expl3:拆分以逗号分隔的 OCMD/OCG 参数列表以实现引用自动化(bis)

ocgx2,expl3:拆分以逗号分隔的 OCMD/OCG 参数列表以实现引用自动化(bis)

感谢@AlexG 和@Marcel Kruger,可以使用下面不同的链接来详细说明 MCQ。

(1)ocgx2:使用 OCG 验证和重置多项选择题

(2)ocgx2、xparse、expl3:拆分逗号分隔的 OCMD/OCGs 参数列表以实现引用自动化

(3)ocgx2:最多可自动进行三次选择题

这给出了实际上下文,但问题在于拆分参数列表,以便自动执行上述第三个链接的 ID 和引用。对于前两个链接,它工作正常。

从下面的 MWE 来看,“手动”方法(必须输入所有 ID(\mcqcheck宏和Check按钮))按预期工作,而“自动”方法(\mcqverify)失败。

我不理解这种行为,因为参数的拆分和重建在\mcqverify命令内部是有效的。我犯了什么错误?

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

相关内容