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

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

编辑:最初的问题不明确,表达方式不当,发布得太早,而且太冗长。经过一段时间的休息和深入研究,我现在几乎可以自己回答基本问题了。

总体介绍和期望保持不变,并为想要解决类似问题的人解释所采用的解决方案。现在的问题只涉及如何在已经激活“验证”按钮时“重置”测验。


目的是在 PDF 手册中显示交互式多项选择题或测验 (MCQ)。使用的工具是:hyperref、、ocgx2和Linux 上的 TeXLive 软件包tikz以及tcolorboxEvince/Atril PDF 查看器(Okular 不支持 OCG)。结果是使用 LuaLaTeX 引擎获得的(pdfLaTeX 应该可以使用)。

目标是显示如下面的第一个链接所示的测验(第一步不使用数据库:测验及其解决方案将在tcolorbox包功能的帮助下进一步记录),但同时也能够模仿 MOOC 平台的布局(例如法国平台:有趣的 MOOC也就是说,一方面,显示测验及其建议(使用 相当简单ocgx2);另一方面,将解决方案的显示委托给一些可点击的按钮,以便检查、重置和对答案进行解释(并在进一步的工作中保存分数)。

单一解决方案和多个解决方案的 MCQ 都需要这种一般行为。

使用 OCG 的单一解决方案 MCQ 的第一种方法如下:

(1)使用可选内容组 (OCG) 的解决方案链接的多项选择题

其他有用的 OCG 入门链接是 AlexG 对以下问题的回答:

(2)使用 ocgs 在 PDF 中实现可点击的复选标记

(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 被命名为redgreenbluecyanmagenta和 。为了正确回答问题,必须检查 OCG 、 yellow和,但其他的则不需要检查。blackredgreenblue

现在,验证文本“正确...”将通过环境放置在新的 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}

相关内容