编辑:最初的问题不明确,表达方式不当,发布得太早,而且太冗长。经过一段时间的休息和深入研究,我现在几乎可以自己回答基本问题了。
总体介绍和期望保持不变,并为想要解决类似问题的人解释所采用的解决方案。现在的问题只涉及如何在已经激活“验证”按钮时“重置”测验。
目的是在 PDF 手册中显示交互式多项选择题或测验 (MCQ)。使用的工具是:hyperref
、、ocgx2
和Linux 上的 TeXLive 软件包tikz
以及tcolorbox
Evince/Atril PDF 查看器(Okular 不支持 OCG)。结果是使用 LuaLaTeX 引擎获得的(pdfLaTeX 应该可以使用)。
目标是显示如下面的第一个链接所示的测验(第一步不使用数据库:测验及其解决方案将在tcolorbox
包功能的帮助下进一步记录),但同时也能够模仿 MOOC 平台的布局(例如法国平台:有趣的 MOOC也就是说,一方面,显示测验及其建议(使用 相当简单ocgx2
);另一方面,将解决方案的显示委托给一些可点击的按钮,以便检查、重置和对答案进行解释(并在进一步的工作中保存分数)。
单一解决方案和多个解决方案的 MCQ 都需要这种一般行为。
使用 OCG 的单一解决方案 MCQ 的第一种方法如下:
(1)使用可选内容组 (OCG) 的解决方案链接的多项选择题
其他有用的 OCG 入门链接是 AlexG 对以下问题的回答:
(3)OCGX 和 hyperref:重叠链接的可见性和可点击性
关键点还在于考虑总检察长对这个问题的回答:
(4)创建大量复选框以使用tikzpicture
环境制作可见/不可见的箭头
借用上面第四个链接中的代码,可以非常直接地为单解和多解 MCQ 添加一个有效的“重置”按钮。顺便说一句,还可以毫不费力地为多解测验添加一个“全选”按钮。
单击“验证”按钮后,也可以显示所选结果(正确或不正确)。对于单解 MCQ,这是直接完成的,这要感谢 AG 在上面第四个链接中的回答。就多解 MCQ 而言,所提出的解决方案既不优雅也不聪明(仍然存在一些误解):我们的技能有限,当然有人可以改进这个解决方案。尽管如此,它还是有效的。
因此,唯一剩下的问题是,当用户已经点击“验证”按钮,但想要测试其他提案时,是否可以自动“重置”测验。在这种情况下,无需再次点击“验证”按钮即可显示结果。(可能我还是不太清楚... 测试 MWE)。
MWE 编辑 3− 2019-05-23:考虑到评论
\documentclass{article}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{xcolor}
\usepackage{fontawesome}
\usepackage{tikz}
\usepackage{calc}
\usepackage{tcolorbox}
\usepackage{hyperref}
\usepackage[tikz]{ocgx2}
\tcbuselibrary{%
skins,
breakable,
xparse,
}
\hypersetup{%
pdfborder=0 0 0,% no border to links
colorlinks=true,%
linkcolor=gray,
}
\definecolor{buttongray}{RGB}{200, 200, 200}
\tikzset{%
quizbutton/.style={
shape=rectangle, rounded corners=1pt,
text=black, draw=#1!90,
top color=#1!15!white, bottom color=#1!75,
inner xsep=6pt, inner ysep=2pt,
},
}
\tcbset{
quizquestionstyle/.style={
breakable, enhanced jigsaw,
colframe=black!75,
colback=black!2!white,
coltitle=red!75!black,
fonttitle={\normalfont\strut},
boxrule=0.4pt, boxsep=0pt, arc=0.8pt,
left=6pt, right=6pt,
attach title to upper={\par\vspace{6pt}},
before skip=4pt, after skip=6pt,
},
}
\newcounter{quizquestion}
\newcounter{mcqproposal}% Multiple choice counter within a quiz question
\newcounter{mcqquiztotal}[quizquestion]% Total proposition counter within a quiz question
\newcounter{mcqsolutiontotal}[quizquestion]% Total number of (multiple) solutions within a quiz question
\newlength{\checkboxwidth}
\newlength{\checkgap}
\setlength{\checkgap}{0.5em}
\newlength{\symbolwidth}
\setlength{\symbolwidth}{10pt}
% \faCheck width = 10.O pt; \faTimes width = 7.85pt => same width in a box
\newcommand{\checktick}{%
\makebox[\symbolwidth][c]{%
\textcolor{green!60!black}{\normalfont\normalsize\faCheck}%
}%
}
\newcommand{\crosstick}{%
\makebox[\symbolwidth][c]{%
\textcolor{red!60!black}{\normalfont\normalsize\faTimes}%
}%
}
%-- Only one answer to multiple choice question (stared environment)
%- Defining a single solution MCQ environment
\NewTColorBox[use counter=quizquestion]{quizquestion*}{o g}{%
% Syntax − #1 = more tcbox options, #2 = optional title
quizquestionstyle,
label={quizquestion:\thetcbcounter},
lowerbox=ignored,
IfValueTF={#2}%
{title=\textbf{Quiz~\thetcbcounter\enspace---\enspace#2}}%
{before upper=\textcolor{tcbcol@title}{\textbf{Quiz~\thetcbcounter}}\vspace*{2pt}},
IfValueTF={#1}{#1}{},% More options
}
%- Traditional presentation of checked radio buttons
%- For inspiration and example, see the answers of Heiko Oberdiek to:
%- https://tex.stackexchange.com/questions/236041/how-to-typeset-a-radio-button
%- Here, we just adapt our needs to the 'Fontawesome' icons
\newlength{\radius}
\settowidth{\radius}{\normalfont\normalsize\faCircleThin}
\addtolength{\radius}{-2.0pt}
%- Empty radio button
\newcommand{\freeRadioButton}{%
\raisebox{-4pt}{%
\begin{tikzpicture}
\fill[color=white, radius=0.6\radius] circle;
\node[color=gray] {\normalfont\normalsize\faCircleThin};
\end{tikzpicture}%
}%
}
%- Checked radio button
\newcommand{\checkedRadioButton}{%
\raisebox{-4pt}{%
\begin{tikzpicture}
\fill[color=green!60!black, radius=0.6\radius] circle;
\node[color=gray] {\normalfont\normalsize\faCircleThin};
\fill[color=white, radius=1.4pt] circle;
\end{tikzpicture}%
}%
}
%- Defining a radio buttons command for layer switching
\NewDocumentCommand{\layerRadioButton}{m m m m}{% From Alexander Grann's answers on TeX.SE
% Syntax − #1: radiobutton group name, #2: layer name, #3: layer id, #4: initial visibility
\switchocg{#3}{\freeRadioButton}%
\settowidth{\checkboxwidth}{\freeRadioButton}%
\begin{ocg}[radiobtngrp=#1]{#2}{#3}{#4}%
\hspace*{-\checkboxwidth}%
\textcolor{green!60!black}{\checkedRadioButton}%
\end{ocg}%
}
%- Defining a proposition for single solution MCQ
\NewDocumentCommand{\mcqproposalSingle}{o m}{%
% Syntax − #1 = more tcbox options, #2 = answering proposal
\begin{tcolorbox}[%
breakable, enhanced,
notitle, colframe=black!60, colback=white,
boxrule=0.2pt, arc=0.4pt, boxsep = 0pt,
left = 4pt, right = 4pt,
top = 4pt, bottom = 4pt,
before skip=4pt, after skip=4pt,
IfValueTF={#1}{#1}{},% More options
]
\stepcounter{mcqproposal}%
\stepcounter{mcqquiztotal}%
\parbox[t]{16pt}{%
%\hspace*{2pt}%
\layerRadioButton{Choice:\thequizquestion}%
{mcqproposalsingle:\themcqproposal}{mcqproposalsingleref:\themcqproposal}{off}%
}%
\parbox[t]{\linewidth-16pt}{#2}%
\end{tcolorbox}%
}
%- Defining the verification command/button for single solution MCQ
\NewDocumentCommand{\verifySingle}{m}{%
% Syntax − #1 = the solely correct answer
\noindent%
\switchocg{checkchoiceref:\thequizquestion}{%
\begin{tikzpicture}
\node[quizbutton=buttongray] (checksolutionbutton)
{\strut\footnotesize\textbf{Verify}};%
\end{tikzpicture}%
}%
\begin{ocg}{CheckChoice:\thequizquestion}{checkchoiceref:\thequizquestion}{off}
\hspace*{\checkgap}% Horizontal space between the button and the checkmark
\foreach \X in {1,...,\value{mcqquiztotal}} {%
\ifnum\X=#1
\begin{ocg}[radiobtngrp=Choices:\thequizquestion]{mcqproposalsingle:\X}{mcqproposalsingleref:\X}{off}%
\ifnum\numexpr\X=1\relax%
\else
\hspace*{-\symbolwidth}%
\fi
\raisebox{5pt}{\checktick}%
\end{ocg}%
\else
\begin{ocg}[radiobtngrp=Choices:\thequizquestion]{mcqproposalsingle:\X}{mcqproposalsingleref:\X}{off}%
\ifnum\numexpr\X=1\relax%
\else
\hspace*{-\symbolwidth}%
\fi
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\fi
}%
\end{ocg}%
}
%- Resetting a single solution MCQ
\NewDocumentCommand{\resetSingle}{}{%
\def\ocglist{}%
\foreach \X in {1,...,\value{mcqquiztotal}} {\xdef\ocglist{\ocglist\space mcqproposalsingleref:\X}}%
\hideocg{\ocglist}{%
\begin{tikzpicture}
\node[quizbutton=buttongray] (resetbutton)
{\strut\footnotesize\textbf{Reset}};
\end{tikzpicture}%
}%
}
%- Applying the different commands for a MCQ with a single solution
\AtBeginEnvironment{quizquestion*}{%
\setcounter{mcqproposal}{0}%
\let\mcqproposal\mcqproposalSingle%
\let\verifyMCQ\verifySingle%
\let\resetMCQ\resetSingle%
}
%-- Several answers to multiple choices question (normal i.e. not stared environment)
%- Defining a multiple solution MCQ environment
\NewTColorBox[use counter=quizquestion]{quizquestion}{o g}{%
% Syntax − #1 = more options, #2 = optional title
quizquestionstyle,
label={quizquestion:\thetcbcounter},
lowerbox=ignored,
IfValueTF={#2}%
{title=\textbf{Quiz~\thetcbcounter\enspace---\enspace#2}}%
{before upper=\textcolor{tcbcol@title}{\textbf{Quiz~\thetcbcounter}}\vspace*{2pt}},
IfValueTF={#1}{#1}{},% More options
}
%- Empty check button
\newcommand{\freeButton}{%
\raisebox{-4pt}{%
\begin{tikzpicture}
\node[color=gray] {\normalfont\normalsize\faSquareO};
\end{tikzpicture}%
}%
}
%- Checked button
\newcommand{\checkedButton}{%
\raisebox{-4pt}{%
\begin{tikzpicture}
\node[color=gray] {%
%\normalfont\normalsize\faSquareO%
\hspace*{-\checkboxwidth}\textcolor{green!60!black}{\faCheck}};
\end{tikzpicture}%
}%
}
%- Check box command for layer switching
\NewDocumentCommand{\layerCheckBox}{m m m}{% From Alexander Grann's answers on TeX.SE
% Syntax − #1: layer name, #2: layer id, #3: initial visibility
\switchocg{#2}{\freeButton}%
\settowidth{\checkboxwidth}{\freeButton}%
\begin{ocg}{#1}{#2}{#3}
\checkedButton%
\end{ocg}%
}
\NewDocumentCommand{\layerCheckBoxMultiple}{m m m}{% From Alexander Grann's answers on TeX.SE:
% https://tex.stackexchange.com/questions/481812/
% Syntax − #1: switch id,
% #2: layer ids to be toggled (space separated if multiple ids),
% #3: initial visibility
\switchocg{#1 #2}{\faSquareO}%
\settowidth{\checkboxwidth}{\normalfont\normalsize\faSquareO}%
\begin{ocg}{\ifx\nil#1\nil#2\else#1\fi}{\ifx\nil#1\nil#2\else#1\fi}{#3}
\hspace*{-\checkboxwidth}\textcolor{green!60!black}{\faCheck}%
\end{ocg}%
}
%- Defining a proposition for multiple solution MCQ
\NewDocumentCommand{\mcqproposalMultiple}{o m}{%
% Syntax − #1 = more tcbox options, #2 = answering proposal
\begin{tcolorbox}[%
breakable, enhanced,
notitle, colframe=black!60, colback=white,
boxrule=0.2pt, arc=0.4pt, boxsep = 0pt,
left = 4pt, right = 4pt,
top = 4pt, bottom = 4pt,
before skip=4pt, after skip=4pt,
IfValueTF={#1}{#1}{},% More options
]
\stepcounter{mcqproposal}%
\stepcounter{mcqquiztotal}%
\parbox[t]{16pt}{%
\hspace*{2pt}%
%- Old
\layerCheckBox{mcqproposalmultiple:\themcqproposal}{mcqproposalmultipleref:\themcqproposal}{off}%
%- New
%\layerCheckBoxMultiple{}{mcqproposalmultipleref:\themcqproposal}{off}%
}%
\parbox[t]{\linewidth-16pt}{#2}%
\end{tcolorbox}%
\newtoggle{Question\thequizquestion:\themcqproposal}%
}
%- Defining the verification command/button for multiple solution MCQ (awful syntax)
\NewDocumentCommand{\verifyMultiple}{m m g g g}{% Up to five correct answers: obvious minimum = 2
% Syntax − The different integers arguments are referenced to the different proposals
\newbool{Question\thequizquestion:#1}\boolfalse{Question\thequizquestion:#1}%
\newbool{Question\thequizquestion:#2}\boolfalse{Question\thequizquestion:#2}%
\IfValueT{#3}{%
\newbool{Question\thequizquestion:#3}%
\boolfalse{Question\thequizquestion:#3}%
}%
\IfValueT{#4}{%
\newbool{Question\thequizquestion:#4}%
\boolfalse{Question\thequizquestion:#4}%
}%
\IfValueT{#5}{%
\newbool{Question\thequizquestion:#5}%
\boolfalse{Question\thequizquestion:#5}%
}%
\noindent%
\switchocg{checkchoicemultipleref:\thequizquestion}{%
\begin{tikzpicture}
\node[quizbutton=buttongray]
(checksolutionmultiplebutton) {\strut\footnotesize\textbf{Verify}};
\end{tikzpicture}%
}
\begin{ocg}{CheckChoiceMultiple:\thequizquestion}{checkchoicemultipleref:\thequizquestion}{off}
\hspace{6.5pt}% <-- Empirical value to adjust the checkmark position like for the single solution! WHY?!!?
\hspace*{\checkgap}% Horizontal space between the button and the checkmark
\IfValueTF{#3}{%
\IfValueTF{#4}{%
\IfValueTF{#5}{%
\switchocg{mcqproposalmultipleref:#1 mcqproposalmultipleref:#2 %
mcqproposalmultipleref:#3 mcqproposalmultipleref:#4 mcqproposalmultipleref:#5}{}%
\begin{ocg}{mcqproposalmultiple:#1}{mcqproposalmultipleref:#1}{off}%
\begin{ocg}{mcqproposalmultiple:#2}{mcqproposalmultipleref:#2}{off}%
\begin{ocg}{mcqproposalmultiple:#3}{mcqproposalmultipleref:#3}{off}%
\begin{ocg}{mcqproposalmultiple:#4}{mcqproposalmultipleref:#4}{off}%
\begin{ocg}{mcqproposalmultiple:#5}{mcqproposalmultipleref:#5}{off}%
\raisebox{5pt}{\checktick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
}{% If value #5 False
\foreach \X in {1,...,\value{mcqquiztotal}} {%
\foreach \Y in {1,...,\X} {%
\foreach \Z in {1,...,\Y} {%
\foreach \U in {1,...,\Z} {%
\ifbool{Question\thequizquestion:#1}{}{%
\ifbool{Question\thequizquestion:#2}{}{%
\ifbool{Question\thequizquestion:#3}{}{%
\ifbool{Question\thequizquestion:#4}{}{%
\ifnum\U=\Z
\relax%
\else
\ifnum\Z=\Y
\relax%
\else
\ifnum\Y=\X
\relax
\else
\hspace*{-\symbolwidth}%
%\X{:}\Y{:}\Z{:}\U{}\space%
\ifnum\U=#1
\ifnum\Z=#2
\ifnum\Y=#3
\ifnum\X=#4
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y %
mcqproposalmultipleref:\Z mcqproposalmultipleref:\U}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\begin{ocg}{mcqproposalmultiple:\U}{mcqproposalmultipleref:\U}{off}%
\raisebox{5pt}{\checktick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y %
mcqproposalmultipleref:\Z mcqproposalmultipleref:\U}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\begin{ocg}{mcqproposalmultiple:\U}{mcqproposalmultipleref:\U}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y %
mcqproposalmultipleref:\Z mcqproposalmultipleref:\U}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\begin{ocg}{mcqproposalmultiple:\U}{mcqproposalmultipleref:\U}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y %
mcqproposalmultipleref:\Z mcqproposalmultipleref:\U}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\begin{ocg}{mcqproposalmultiple:\U}{mcqproposalmultipleref:\U}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y %
mcqproposalmultipleref:\Z mcqproposalmultipleref:\U}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\begin{ocg}{mcqproposalmultiple:\U}{mcqproposalmultipleref:\U}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi
\fi
\fi
\fi
}%
}%
}%
}%
}%
}%
}%
}%
}% End if value #5
}{% If value #4 false
\foreach \X in {1,...,\value{mcqquiztotal}} {%
\foreach \Y in {1,...,\X} {%
\foreach \Z in {1,...,\Y} {%
\ifbool{Question\thequizquestion:#1}{}{%
\ifbool{Question\thequizquestion:#2}{}{%
\ifbool{Question\thequizquestion:#3}{}{%
\ifnum\Z=\Y
\relax%
\else
\ifnum\Y=\X
\relax%
\else
\hspace*{-\symbolwidth}%
%\X{:}\Y{:}\Z{}\space%
\ifnum\Z=#1
\ifnum\Y=#2
\ifnum\X=#3
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y mcqproposalmultipleref:\Z}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\raisebox{5pt}{\checktick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y mcqproposalmultipleref:\Z}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi%
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y mcqproposalmultipleref:\Z}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi%
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y mcqproposalmultipleref:\Z}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\begin{ocg}{mcqproposalmultiple:\Z}{mcqproposalmultipleref:\Z}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\end{ocg}%
\fi%
\fi
\fi
}%
}%
}%
}%
}%
}%
}% End if value #4
}{% If value #3 false
\foreach \X in {1,...,\value{mcqquiztotal}} {%
\foreach \Y in {1,...,\X} {%
\ifbool{Question\thequizquestion:#1}{}{%
\ifbool{Question\thequizquestion:#2}{}{%
\ifnum\Y=\X
\relax%
\else
%\X{:}\Y{}\space%
\hspace*{-\symbolwidth}%
\ifnum\Y=#1
\ifnum\X=#2
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\raisebox{5pt}{\checktick}%
\end{ocg}%
\end{ocg}%
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\fi%
\else
\switchocg{mcqproposalmultipleref:\X mcqproposalmultipleref:\Y}{}%
\begin{ocg}{mcqproposalmultiple:\X}{mcqproposalmultipleref:\X}{off}%
\begin{ocg}{mcqproposalmultiple:\Y}{mcqproposalmultipleref:\Y}{off}%
\raisebox{5pt}{\crosstick}%
\end{ocg}%
\end{ocg}%
\fi%
\fi%
}%
}%
}%
}%
}% End if value #3
\end{ocg}% End of 'Verify' OCG definition
}
%- Resetting and/or selecting all items of a multiple solution MCQ
\NewDocumentCommand{\resetMultiple}{}{%
\def\ocglist{}%
\foreach \X in {1,...,\value{mcqquiztotal}} {\xdef\ocglist{\ocglist\space mcqproposalmultipleref:\X}}%
\showocg{\ocglist}{%
\begin{tikzpicture}
\node[quizbutton=buttongray] (selectallbutton)
{\strut\footnotesize\textbf{Select all}};
\end{tikzpicture}%
}%
\qquad%
\hideocg{\ocglist}{%
\begin{tikzpicture}
\node[quizbutton=buttongray] (resetbutton)
{\strut\footnotesize\textbf{Reset}};
\end{tikzpicture}%
}%
}
%- Applying the different commands for a MCQ with multiple solutions
\AtBeginEnvironment{quizquestion}{%
\setcounter{mcqproposal}{0}%
\let\mcqproposal\mcqproposalMultiple%
\let\verifyMCQ\verifyMultiple%
\let\resetMCQ\resetMultiple%
}
\begin{document}
% Single solution MCQ
%--------------------
\begin{quizquestion*}{A relevant statement}
In short, what is the color of a black cat?
Choose the answer.
\mcqproposal[before skip=8pt]{The color is obviously red.}
\mcqproposal{The color may be green.}
\mcqproposal{The color is black.}
\mcqproposal[after skip=8pt]{The color is undoubtedly yellow.}
\verifyMCQ{3}
\qquad\hspace{3cm}\resetMCQ
\end{quizquestion*}
% Multiple solutions MCQ
%-----------------------
\begin{quizquestion}{Test of knowledge}
What are the different colors of an RGB image?
Check off the three exact assertions.
\mcqproposal[before skip=8pt]{Green.}
\mcqproposal{Yellow.}
\mcqproposal{Blue.}
\mcqproposal{Red.}
\mcqproposal[after skip=8pt]{Cyan.}
% Must be given in ascending order: if not => wrong results
%\verifyMCQ{1}{4}% Test with 2 correct choices
\verifyMCQ{1}{3}{4}% Correct answer of this particular quiz (3 choices)
%\verifyMCQ{1}{3}{4}{5}% Test with 4 correct choices
%\verifyMCQ{1}{2}{3}{4}{5}% Test with 5 correct choices
\qquad\hspace{3cm}\resetMCQ
\end{quizquestion}
\end{document}
答案1
该软件包ocgx2
现在提供环境ocmd
,它根据 PDF 规范实现可选内容成员字典。OCMD 是一种 PDF 层,其可见性取决于文档中其他 OCG 的可见性状态。OCMD 是创建测验的便捷方式。
假设我们插入了多个测验按钮,每个按钮都会切换 OCG 的可见性。这些 OCG 被命名为red
、green
、blue
、cyan
、magenta
和 。为了正确回答问题,必须检查 OCG 、
yellow
和,但其他的则不需要检查。black
red
green
blue
现在,验证文本“正确...”将通过环境放置在新的 PDF 层上ocmd
。OCMD 的可见性将在运行时根据布尔表达式从 OCG 可见性计算得出:
\begin{ocmd}{
\And{
red,green,blue, \Not{\Or{cyan,magenta,yellow,black}}
}
}
Correct. These are the components of the RGB model.
\end{ocmd}
PDF 层中“错误”的定义如下
\begin{ocmd}{
\Not{
\And{
red,green,blue, \Not{\Or{cyan,magenta,yellow,black}}
}
}
}
Wrong.
\end{ocmd}
完整示例,基于问题中给出的示例。为了减少代码量并使 OCG/OCMD 相关代码更加明显,简化了视觉外观。在第一个示例中,测验按钮被添加到单选按钮组中,这样一次只能选中其中一个。
\documentclass{article}
\usepackage{ocgx2}
\usepackage{fontawesome5}
\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
\showocg{#1}{\fbox{\strut Verify}}
\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}