该问题是下面链接的两个巧妙而有效的答案的延续,这些答案使用 ocgx2(OCG/OCMG)进行了详细的半交互式测验/MCQ。
(2)ocgx2、xparse、expl3:拆分逗号分隔的 OCMD/OCGs 参数列表以实现引用自动化
我想要处理的下一步是让用户每次单击检查按钮时自动进行三次试验(查看无修饰的结果布局)。在第三步,分配分数。目前,我一方面能够获得带有 OCMD 层的正确/错误测验建议,另一方面能够获得与试验次数相关的一组三个符号(OCG 层)。这个想法是混合这两个方向。
经过多次测试,无论是嵌套环境还是非嵌套环境,我都必须承认我迷失了方向……我当然不了解 OCG/OCMG 的全部功能。因此,这种方法可行吗?直觉上我认为可行,但如果可行,如何解决这个问题?
我也知道 PDF 查看器的局限性:
我确实希望 LaTeX 的新 (2019) OCMD 层可以成为我的朋友......
平均能量损失
\documentclass[10pt]{article}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{xcolor}
\usepackage{fontawesome5}
\usepackage[tikz]{ocgx2}
\usepackage{calc}
\newcounter{quizquestion}
\newcounter{mcqproposal}
\newcounter{mcqquiztotal}
\newcounter{trialnumber}
\newlength{\quizcheckboxwidth}
\NewDocumentEnvironment{quizquestion}{ m m }%
{
\stepcounter{quizquestion}%
\let\mcqproposal\mcqproposalMultiple%
}
{
\mcqcheck{#1}{#2}%
\hspace{0.1\linewidth}%
\mcqresetcheck
}
\NewDocumentCommand{\mcqproposalMultiple}{ m }{%
% Syntax − #1 = proposal/statement
\parbox[t]{16pt}{%
\hspace*{2pt}%
\quizMultipleButton{mcqproposalref.\thequizquestion.\themcqproposal}%
}%
\parbox[t]{\linewidth-16pt}{#1}%
}
\NewDocumentCommand{\quizMultipleButton}{m}{%
% Syntax − #1: choice id for answering proposal
% Action on click: toggle myself (choice layer), hide verification layer
\stepcounter{mcqproposal}%
\stepcounter{mcqquiztotal}%
\setlength{\quizcheckboxwidth}{\widthof{\faIcon[regular]{square}}}%
\makebox[\quizcheckboxwidth][c]{%
\actionsocg{#1}{}{check.\thequizquestion}{\faIcon[regular]{square}}%
}%
\begin{ocg}{#1}{#1}{off}% choice layer
\hspace*{-\quizcheckboxwidth}%
\makebox[\quizcheckboxwidth][c]{\textcolor{green!60!black}{\faCheckSquare}}%
\hspace*{-\quizcheckboxwidth}%
\makebox[\quizcheckboxwidth][c]{\faIcon[regular]{square}}%
\end{ocg}%
}
%%% check button
\NewDocumentCommand{\askreplymcqArgsIdsCheck}{m}{%
mcqproposalref.\thequizquestion.#1%
}
\ExplSyntaxOn
\cs_new_protected:Npn \askreplymcqcheck_process_list:Nn #1 #2
{
% clear the sequence
\seq_clear:N #1
% cycle through the arguments, storing "\mcqArgsIds{<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 { \askreplymcqArgsIdsCheck{##1} }
}
}
\seq_new:N \l_correct_seq
\seq_new:N \l_wrong_seq
\cs_new_protected:Npn \askreplymcq__check:nn #1 #2
{\showocg{check.\thequizquestion}{%
\begin{tikzpicture}
\node[draw] (checkbutton) {\strut Check};%
\end{tikzpicture}%
}
\begin{ocg}{check.\thequizquestion}%
{check.\thequizquestion}{off}% verification layer
\makebox[0pt][l]{%
\begin{ocmd}{\Not{\And{#1,\Not{\Or{#2}}}}}% "wrong" layer (OCMD)
\hspace*{0.25em}%
\raisebox{5pt}{\textcolor{red!60!black}{\faTimes}}%Wrong.
\end{ocmd}%
}%
%\makebox[0pt][l]{%
\begin{ocmd}{\And{#1,\Not{\Or{#2}}}}% "correct" layer (OCMD)
\hspace*{0.25em}%
\raisebox{5pt}{\textcolor{green!60!black}{\faCheck}}%Correct.
\end{ocmd}%
%}
\end{ocg}%
\makebox[0pt][l]{\actionsocg{trialstep1}{}{trialstep2,trialstep3}{\textcolor{black}{\faCircle}}}%
\begin{ocg}{trialstep1}{trialstep1}{off}% choice layer
\makebox[\widthof{\faCircle}]{\textcolor{red}{\faCircle}}%
\stepcounter{trialnumber}\thetrialnumber
\end{ocg}%
\makebox[0pt][l]{\actionsocg{trialstep2}{trialstep1}{trialstep3}{\textcolor{black}{\faCircle}}}%
\begin{ocg}{trialstep2}{trialstep2}{off}% choice layer
\makebox[\widthof{\faCircle}]{\textcolor{red}{\faCircle}}%
\stepcounter{trialnumber}\thetrialnumber
\end{ocg}%
\makebox[0pt][l]{\actionsocg{trialstep3}{trialstep1,trialstep2}{}{\textcolor{black}{\faCircle}}}%
\begin{ocg}{trialstep3}{trialstep3}{off}% choice layer
\makebox[\widthof{\faCircle}]{\textcolor{red}{\faCircle}}%
\stepcounter{trialnumber}\thetrialnumber
\end{ocg}%
}
\cs_generate_variant:Nn \askreplymcq__check:nn {ff}
\NewDocumentCommand{\mcqcheck}{ 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
\askreplymcqcheck_process_list:Nn \l_correct_seq { #1 }% Save OCMD IDs as LaTeX3 seq variable
\askreplymcqcheck_process_list:Nn \l_wrong_seq { #2 }% Save OCMD IDs as LaTeX3 seq variable
\askreplymcq__check:ff { \seq_use:Nn \l_correct_seq {,} } { \seq_use:Nn \l_wrong_seq {,} }
}
\ExplSyntaxOff
%%% reset button
\NewDocumentCommand{\mcqresetcheck}{}{%
\def\ocglistresetcheck{}%
\xdef\ocglistresetcheck{%
\ocglistresetcheck, check.\thequizquestion}%
\foreach \X in {1,...,\value{mcqquiztotal}} {%
\xdef\ocglistresetcheck{\ocglistresetcheck, mcqproposalref.\thequizquestion.\X}%
}%
\hideocg{\ocglistresetcheck}{%
\begin{tikzpicture}
\node[draw] (resetbutton) {\strut Reset};
\end{tikzpicture}%
}%
}
\begin{document}
\begin{quizquestion}{2,4,5}{1,3,6,7,8,9,10,11,12,13}
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.}\\
\mcqproposal{Magenta.}\\
\mcqproposal{Gray.}\\
\mcqproposal{Purple.}\\
\mcqproposal{White.}\\
\mcqproposal{Pink.}\\
\mcqproposal{Maroon.}\\[8pt]
\end{quizquestion}
\end{document}
答案1
以下是一些入门知识。其中还涉及一些 JavaScript。所有逻辑都放在“验证”按钮中,这是唯一一个实现方式与(1)。
可以访问 PDF 中的 OCG,并且可以通过 JavaScript 设置其可见性,如文档所述这里. 通过该animate
包实现了一个简单的指标,显示可用试验的耗尽情况。
\documentclass{article}
\usepackage{ocgx2}
\usepackage{media9} % \mediabutton
\usepackage{animate}
\usepackage{fontawesome5}
\usepackage{wasysym} % \Circle, \CIRCLE
\usepackage{xcolor}
\usepackage{calc} %\widthof{...}
% quiz button
\NewDocumentCommand{\quizButton}{o m m m}{%
% Syntax − #1: optional: radio button group
% #2: button shape: \faCircleThin, \faSquareO
% #3: verification id
% #4: choice id
% action on click: toggle myself (choice layer), hide verifcation layer
\makebox[0pt][l]{\actionsocg{#4}{}{#3}{#2}}%
\begin{ocg}[\IfValueT{#1}{radiobtngrp=#1}]{#4}{#4}{off}% choice layer
\makebox[\widthof{#2}]{\textcolor{green!60!black}{\faCheck}}%
\end{ocg}%
}
% verify button
\NewDocumentCommand{\verifyButton}{m m m}{%
% Syntax − #1: verification id
% #2: list of OCG ids of correct/required answer(s), comma separated
% #3: 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=="#1"&&ocgs[i].state==false&&anim["#1"].frameNum<3){%
ocgs[i].state=true;%
anim["#1"].frameNum++;%
}%
}%
}]{\fbox{\strut Verify}}\space%
\begin{animateinline}[label=#1,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}{#1}{#1}{off}% verification layer
\makebox[0pt][l]{%
\begin{ocmd}{\Not{\And{#2,\Not{\Or{#3}}}}}% "wrong" layer (OCMD)
Wrong.
\end{ocmd}%
}%
\begin{ocmd}{\And{#2,\Not{\Or{#3}}}}% "correct" layer (OCMD)
Correct.
\end{ocmd}%
\end{ocg}%
}
% reset button
\NewDocumentCommand{\resetButton}{m}{%
% Syntax − #1: list of OCG ids, comma separated
\hideocg{#1}{\fbox{\strut Reset}}%
}
\parindent=0pt
\begin{document}
In short, what is the colour of a black cat? One correct answer.\\[8pt]
\quizButton[CatColours]{\faIcon[regular]{circle}}{vrfyCatCol}{red} The colour is obviously red.\\
\quizButton[CatColours]{\faIcon[regular]{circle}}{vrfyCatCol}{green} The colour may be green.\\
\quizButton[CatColours]{\faIcon[regular]{circle}}{vrfyCatCol}{black} The colour is black.\\
\quizButton[CatColours]{\faIcon[regular]{circle}}{vrfyCatCol}{yellow} The colour is undoubtedly yellow.\\[8pt]
\verifyButton{vrfyCatCol}{black}{red,green,yellow}\hspace{0.3\linewidth}
\resetButton{vrfyCatCol,black,red,green,yellow}\\[16pt]
Which are the colour components of an RGB image? Multiple required assertions.\\[8pt]
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{magenta} Magenta.\\
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{green2} Green.\\
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{cyan} Cyan.\\
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{blue} Blue.\\
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{red2} Red.\\
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{black2} Black.\\
\quizButton{\faIcon[regular]{square}}{vrfyRGBCol}{yellow2} Yellow.\\[8pt]
\verifyButton{vrfyRGBCol}{red2,green2,blue}{cyan,magenta,yellow2,black2}\hspace{0.3\linewidth}
\resetButton{vrfyRGBCol,red2,green2,blue,cyan,magenta,yellow2,black2}
\end{document}