我设计了一个包含数百个问题和答案的测验。给定问题的答案就在它下面的一行,但并非所有问题都有答案。下面是该测验的较短版本的 LaTeX 代码。
\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
\newcommand{\ans}{\item[$\circ$] \bfseries}
%\newcommand{\ans}{%} % this doesn't work
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}
现在我想准备第二个版本的测验,但省略答案(仅在最终的 PDF 文档中,而不是在 LaTeX 文件中)。有没有通过仅重新定义 \ans 来快速完成此操作的方法?我最初的想法是通过 \newcommand{\ans}{%} 重新定义 \ans,但这当然行不通。我查看了 comment 和versions 等软件包,但它们似乎都需要用括号或 \begin/\end 对将要省略的材料括起来。我还希望能够通过使用适当的 \ans 定义(即,在我不想使用的定义前面放置一个 %)轻松地在测验的各个版本之间来回切换。
谢谢。
答案1
您可以定义\ans
将其文本放入一个临时未使用的框中,以 或 终止\end
。\qsn
这里的主要限制是,如果您在答案中有一个嵌套环境,则必须用 包围它,以便看到的{...}
第一个顶层是\end
\end{list}
\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
%\newcommand{\ans}{\item[$\circ$] \bfseries}
%\newcommand{\ans}{%} % this doesn't work
\newcommand\ans{\setbox0\vbox\bgroup%
\def\qsn{\egroup\qsn}%
\def\end{\egroup\end}}
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}
答案2
定义\ans
为查找下一行结尾的命令(但您最好确保您的答案只有一行)。
\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$]}
\newif\ifshowanswers
\newcommand\ans{\begingroup\catcode`\^^M=12 \xans}
{\catcode`\^^M=12 %
\gdef\xans#1^^M{\ifshowanswers\item[$\circ$]\bfseries #1\fi\endgroup}%
}
\showanswerstrue % comment to turn off showing the answers
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}
\showanswerstrue
如果该行被注释掉,则输出如下:
如果您不能保证答案在一行上,则必须使用更复杂的东西,并且有必要将您的答案更改\begin{list}
为其他内容。
\documentclass{article}
\usepackage{xparse,l3regex,environ}
\newcommand{\qsn}{\item[$\bullet$]\normalfont}
\newcommand{\ans}{\item[$\circ$]\bfseries}
\newcommand{\questionterminator}{}
\ExplSyntaxOn
\NewEnviron{questions}
{
\begin{list}{$\bullet$}{}
\ifshowanswers
\BODY
\else
\tl_put_right:Nn \BODY { \questionterminator }
\regex_replace_all:nnN { \c{ans}.*?(\c{qsn}|\c{questionterminator}) } { \1 } \BODY
\BODY
\fi
\end{list}
}
\ExplSyntaxOff
\newif\ifshowanswers
%\showanswerstrue % comment to turn off showing the answers
\begin{document}
\begin{questions}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{questions}
\end{document}
输出完全相同。
答案3
IMP 备注:正如@egreg正确指出的那样,这种方法不会省略答案,而是将它们打印在与问题相同的行中。让它起作用的唯一方法是不要使用修改后的命令,\ans
而是使用\hashed{}
命令隐藏答案,如更新后的代码所示。然而,OP 的要求只是在输出 PDF 中在“答案”和“无答案”之间进行简单的切换;而这个特定的解决方案失败了!
只需使用\hashed{}
命令即可从 PDF 中省略所需的文本!
省略答案的 MWE(已更新):
\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
\newcommand{\ans}{\item[$\circ$] \bfseries} % -- v1 : prints answers
\newcommand{\hashed}[2]{#2} % -- hashes out the selected text: \hashed{I want to hide!}
%\newcommand{\ans}{\hashed{\item[$\circ$] \bfseries}} % -- v2 : USELESS!
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
%\ans Green, red, and white.
\hashed{\ans Green, red, and white.}
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
%\ans Nine.
\hashed{\ans Nine.}
\end{list}
\end{document}
省略答案的结果(已更新):
用于显示答案的 MWE(已更新):
\documentclass{article}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
\newcommand{\ans}{\item[$\circ$] \bfseries} % -- v1 : prints answers
\newcommand{\hashed}[2]{#2} % -- hashes out the selected text: \hashed{I want to hide!}
%\newcommand{\ans}{\hashed{\item[$\circ$] \bfseries}} % -- v2 : USELESS!
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
%\hashed{\ans Green, red, and white.}
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
%\hashed{\ans Nine.}
\end{list}
\end{document}
显示答案的结果(已更新):
答案4
一行答案
如果答案受行尾限制,且没有两个行,那么这是包的工作eolgrab
(egreg 的第一个例子回答显示手动方式)。
\documentclass{article}
\usepackage{eolgrab}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
%\newcommand{\ans}{\item[$\circ$] \bfseries}
\makeatletter
\newcommand{\ans}{\eolgrab{\@gobble}}
\makeatother
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green, red, and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}
评论:
\@gobble
是一个 LaTeX 内核宏,它只是丢弃了它的参数。也可以定义一个新的宏来避免\makeatother
和\makeatletter
:
\newcommand{\ans}{\eolgrab{\GobbleOne}}
\newcommand{\GobbleOne}[1]{}
用几行字回答
如果答案可以有几行,然后受下一行\qsn
或\end
列表末尾的限制,则可以使用以下内容:
\documentclass{article}
\usepackage{eolgrab}
\newcommand{\qsn}{\item[$\bullet$] \normalfont}
%\newcommand{\ans}{\item[$\circ$] \bfseries}
\makeatletter
\newcommand{\ans}{\eolgrab{\@ans}}
\newcommand*{\@ans}[1]{%
\@ifnextchar\qsn{}{%
\@ifnextchar\end{}{\ans}%
}%
}
\makeatother
\begin{document}
\begin{list}{$\bullet$}{}
\qsn What are the colors on the Italian flag?
\ans Green,
red,
and white.
\qsn Pick a number between 30 and 40.
\qsn How many lives does a cat have?
\ans Nine.
\end{list}
\end{document}
评论:
\@ifnextchar
是一个 LaTeX 内核宏,用于检查下一个标记(空格标记会被悄悄删除)。通常用于检测[
可选参数,但也可以用于其他标记。