I am setting up some practice tests for an aptitude exam my son will undertake for entry to university. Many example questions are available. Hard copy books publish the questions at the front of the book and the answers at the back. Flipping pages is not conducive to understanding the question and its solution. It also makes practice under timed conditions difficult.
I'm close to setting up an e-book for practicing the test. The e-book uses Optional Content Groups (OCG) created with the hyperref
and ocgx2
packages. However, I have not been able to link the choice of the correct multiple choice answer with displaying the solution. A MWE setup is as follows.
Two questions (Q1 and Q2) are set out in relation to a passage of text. Each question has five, multiple choice answers. There is a single solution for each question. The content for each passage, the questions, multiple choice answers and solution combination is loaded from an external file (DB.csv) using datatools
and are set out on the page in a tcolorbox
raster. The multiple choice answers are associated with radio buttons that toggle whether a particular answer choice is correct or incorrect. A separate box adjacent to the choices can be toggled to show the solution.
Currently, the solution is toggled separately from the responses to multiple choice answers. I am trying to get the solution to toggle on when the correct multiple choice answer is given. For example, the correct answer to question 1 is D. When the radio button for choice D is pressed, I want the solution to show in the adjacent box.
Thus, my question is: How do I link clicking on one ocg (a multiple choice answer) to show a separate ocg (the solution), when that link is subject to a conditional test (it is the correct answer).
This is an annotated picture of the output from the MWE
This is the MWE:
% Adapted from https://tex.stackexchange.com/questions/286280/textfield-and-animateinline
\PassOptionsToPackage{table,x11names,dvipsnames,svgnames}{xcolor}
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{datatool}
\usepackage{enumitem}
\usepackage{fancyhdr}
\usepackage{filecontents}
\usepackage[a3paper,portrait,left=2cm,right=2cm,top=2cm,bottom=2cm,headheight=30pt]{geometry}
\usepackage{graphics} % \resizebox
\usepackage{ifthen}
\usepackage{ocgx2}
\usepackage[most]{tcolorbox}
\usepackage{xcolor}
\usepackage{hyperref} % \TextField etc.
\hypersetup{
hyperindex=true,
colorlinks=true,
breaklinks=true,
urlcolor= purple,
linkcolor={red!50!black},
citecolor={blue!50!black},
urlcolor={blue!80!black},
linktocpage,
bookmarks=true,
pdftoolbar=true,
pdfmenubar=true,
bookmarksopen=true,
pdftitle={LNAT},
pdfauthor={},
pdfsubject={LNAT},
}
\begin{filecontents*}{DB.csv}
Passage,AQuestion,AChoice1,AChoice2,AChoice3,AChoice4,AChoice5,AAnswer,ASolution,BQuestion,BChoice1,BChoice2,BChoice3,BChoice4,BChoice5,BAnswer,BSolution
"Old MacDonald had a farm. On that farm he had cows, horses, goats and sheep.",How many ruminants did McDonald have on his farm?,0,1,2,3,4,4,"Ruminants have a special stomach for fermentation of plant-based food. A horse is not a ruminant.",How many ungulates did McDonald have on his farm?,0,1,2,3,4,5,"Ungulates are hoofed animals. All McDonald's animals have hooves."
\end{filecontents*}
\newcounter{P}
\setcounter{P}{0}
\newcounter{Q}
\setcounter{Q}{0}
\setlist{label*=\Alph*.,noitemsep,leftmargin=0.9cm}
\setlength\parindent{0pt}
\makeatletter
% patch hyperref's Form producing commands to make them layer-aware
\let\PDFFormRadioOrig\PDFForm@Radio
\def\PDFForm@Radio{\PDFFormRadioOrig\ocgxii@insert@OC}
\makeatother
%alternative check box command for layer switching
\newcommand\layerCheckBox[3]{%
% #1: layer name (as shown in Layers tab),
% #2: layer id,
% #3: initial visibility
\raisebox{-0.6ex}{\resizebox{3ex}{!}{%
\makebox[0pt][l]{\showocg{#2}{$\circ$}}%
\begin{ocg}{#1}{#2}{#3}$\bullet$\end{ocg}%
}%
\hspace{0.1cm}
}}
% This is setting up the header
\chead{}
\cfoot{}
\fancypagestyle{myheader}{
\fancyhead[L]{Passage \arabic{P}}
\fancyhead[R]{\thepage{}}
\renewcommand{\headrulewidth}{0.0pt}
\renewcommand{\headrule}{\hbox to\headwidth{\color{blue}\leaders\hrule height \headrulewidth\hfill}}
}
\pagestyle{myheader}
% Load database
\DTLloaddb{DB}{DB.csv}
\begin{document}
% For each record (line) in database
% Assign field values by name to macros
%\DTLsetseparator{|}
\DTLforeach{DB}{%
\passage=Passage,
\Aquestion=AQuestion,
\Achoicea=AChoice1,
\Achoiceb=AChoice2,
\Achoicec=AChoice3,
\Achoiced=AChoice4,
\Achoicee=AChoice5,
\Aanswer=AAnswer,
\Asolution=ASolution,
\Bquestion=BQuestion,
\Bchoicea=BChoice1,
\Bchoiceb=BChoice2,
\Bchoicec=BChoice3,
\Bchoiced=BChoice4,
\Bchoicee=BChoice5,
\Banswer=BAnswer,
\Bsolution=BSolution%
}{%
\stepcounter{P}
\begin{tcboxeditemize}
[raster rows=5,raster columns=5,raster height=\textheight-2cm,arc=6pt,
raster every box/.style={colframe=red!50!black,colback=red!10!white,coltitle=white,fonttitle=\large\bfseries}] % raster options
%
{colframe=CornflowerBlue!50!white,colback=CornflowerBlue!10!white,arc=6pt} % outer tcolorbox options
\tcbitem[raster multicolumn=2,raster multirow=5,colframe=green!50!black,colback=white,raster height=\tcbtextheight,colbacktitle=white,coltitle=black,title=Passage \arabic{P}]
\passage
%
\tcbitem[raster multicolumn=2,raster multirow=5,blankest,raster height=\tcbtextheight]
%
\begin{tcbitemize}[raster rows=5,raster columns=2,raster height=\tcbtextheight,colbacktitle=white]
% Question 1
\stepcounter{Q}
\tcbitem[raster multicolumn=2,colframe=blue!50!white,colback=white,coltitle=black,fonttitle=\large\bfseries,title=\arabic{Q}. \Aquestion]
\begin{enumerate}
% Question 1 - Choice A
\item [\layerCheckBox{Q\arabic{Q}A}{\arabic{Q}A}{off} A.] \Achoicea \par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}A}{\arabic{Q}A}{off}%
\ifthenelse{\Aanswer=1}{Correct}{Incorrect}
\end{ocg}%
% Question 1 - Choice B
\item [\layerCheckBox{Q\arabic{Q}B}{\arabic{Q}B}{off} B.] \Achoiceb \par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}B}{\arabic{Q}B}{off}%
\ifthenelse{\Aanswer=2}{Correct}{Incorrect}
\end{ocg}%
% Question 1 - Choice C
\item [\layerCheckBox{Q\arabic{Q}C}{\arabic{Q}C}{off} C.] \Achoicec \par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}C}{\arabic{Q}C}{off}%
\ifthenelse{\Aanswer=3}{Correct}{Incorrect}
\end{ocg}%
% Question 1 - Choice D
\item [\layerCheckBox{Q\arabic{Q}D}{\arabic{Q}D}{off} D.] \Achoiced \par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}D}{\arabic{Q}D}{off}%
\ifthenelse{\Aanswer=4}{Correct}{Incorrect}
\end{ocg}%
% Question 1 - Choice E
\item [\layerCheckBox{Q\arabic{Q}E}{\arabic{Q}E}{off} E.] \Achoicee \par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}E}{\arabic{Q}E}{off}%
\ifthenelse{\Aanswer=5}{Correct}{Incorrect}
\end{ocg}%
\end{enumerate}
% Question 2
\stepcounter{Q}
\tcbitem[raster multicolumn=2,colframe=blue!50!white,colback=white,coltitle=black,fonttitle=\large\bfseries,title=\arabic{Q}. \Bquestion]
\begin{enumerate}
% Question 2 - Choice A
\item [\layerCheckBox{Q\arabic{Q}A}{\arabic{Q}A}{off} A.] \Bchoicea\par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}A}{\arabic{Q}A}{off}%
\ifthenelse{\Banswer=1}{Correct}{Incorrect}
\end{ocg}%
% Question 2 - Choice B
\item [\layerCheckBox{Q\arabic{Q}B}{\arabic{Q}B}{off} B.] \Bchoiceb\par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}B}{\arabic{Q}B}{off}%
\ifthenelse{\Banswer=2}{Correct}{Incorrect}
\end{ocg}%
% Question 2 - Choice C
\item [\layerCheckBox{Q\arabic{Q}C}{\arabic{Q}C}{off} C.] \Bchoicec\par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}C}{\arabic{Q}C}{off}%
\ifthenelse{\Banswer=3}{Correct}{Incorrect}
\end{ocg}%
% Question 2 - Choice D
\item [\layerCheckBox{Q\arabic{Q}D}{\arabic{Q}D}{off} D.] \Bchoiced\par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}D}{\arabic{Q}D}{off}%
\ifthenelse{\Banswer=4}{Correct}{Incorrect}
\end{ocg}%
% Question 2 - Choice E
\item [\layerCheckBox{Q\arabic{Q}E}{\arabic{Q}E}{off} E.] \Bchoicee\par
\begin{ocg}[radiobtngrp=Choices]{Q\arabic{Q}E}{\arabic{Q}E}{off}%
\ifthenelse{\Banswer=5}{Correct}{Incorrect}
\end{ocg}%
\end{enumerate}
\end{tcbitemize}
\tcbitem[raster multicolumn=1,raster multirow=5,blankest,raster height=\tcbtextheight]
% These are the solutions
\begin{tcbitemize}[raster rows=5,raster columns=1,raster height=\tcbtextheight]
% Solution to question 1
\tcbitem[colframe=blue!50!white,colback=white]
\hspace{-0.6cm} \layerCheckBox{S\arabic{Q}A}{S\arabic{Q}A}{off}
\begin{ocg}[radiobtngrp=Choices]{S\arabic{Q}A}{S\arabic{Q}A}{off}%
\Asolution
\end{ocg}
% Solution to question 2
\tcbitem[colframe=blue!50!white,colback=white]
\hspace{-0.6cm} \layerCheckBox{S\arabic{Q}B}{S\arabic{Q}B}{off}
\begin{ocg}[radiobtngrp=Choices]{S\arabic{Q}B}{S\arabic{Q}B}{off}%
\Bsolution
\end{ocg}
\end{tcbitemize}
\end{tcboxeditemize}
\clearpage
\stepcounter{P}
}
\end{document}