1

This question is a following of the two clever and efficient answers linked below to elaborate semi-interactive quizzes/MCQ with ocgx2 (OCG/OCMG).

(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

The next step I want to deal with is to allow automatically three trials to the user each time he/she click on the check button (see the layout of the result without cosmetics). At the third step, the points are assigned. For the moment being, I am able to on one hand, have the correct/wrong quiz proposals with the OCMD layers, and on the other hand, a set of three symbols related to the trial number (OCG layers). The idea is to mix the two orientations.

After many tests, with nested or not environments, I must admit that I am lost... I certainly don't understand everything about the power of OCG/OCMG. Therefore, is this approach feasible? Intuitively I think so but if yes, how to solve such an issue?

I am also aware of the PDF viewers limitations:

(3) Tikz & OCG: make button cycling through different layers

I do hope that the new (2019) OCMD layers for LaTeX could be a friend...

enter image description here

MWE

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

ejazz
  • 1,047
  • This is, I am afraid, the point where JavaScript would need to come into play. – AlexG Mar 07 '21 at 15:40
  • But let me think about it first, may need some time... – AlexG Mar 07 '21 at 15:47
  • Your recent, unfortunately deleted question was in fact a good starting point! I very much liked the idea of using animate to implement a trials indicator such that I am exploiting it here ;-). – AlexG Mar 19 '22 at 21:23
  • @AlexG I thought that my other question was too long and not relevant, so I deleted it not to add noise for other users.;-) – ejazz Mar 20 '22 at 09:00

1 Answers1

4

Here is something to get you started. A little JavaScript is involved too. All logic is put into the "Verify" button, which is the only element whose implementation differs from (1).

OCGs in a PDF can be accessed and their visibility be set by JavaScript as documented here. A simple indicator showing the depletion of available trials is implemented by means of the animate package.

enter image description here

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

AlexG
  • 54,894