我是一名教师,经常需要制作带有答案的工作表和评论。在 TeX StackExchange 的帮助下,我现在拥有一个相当强大的系统,但有一个明显的例外,那就是它不适用于enumitem
。我收到的错误消息超出了我的 LaTeX 知识范围。有谁能帮我吗?
梅威瑟:
\documentclass[10pt]{article}
\usepackage{pgfplots}
\usepackage{enumitem}
\newwrite\answerkeyfile
\AtBeginDocument{%
\immediate\openout\answerkeyfile=\jobname.keys
}
\begingroup
\catcode`\#=12
\gdef\hashchar{#}%
\endgroup
\makeatletter
\newcommand{\answerkey}[1]{%
\begingroup
\let\#\hashchar
\immediate\write\answerkeyfile{\@currentlabel.\ }
\immediate\write\answerkeyfile{\unexpanded{#1}}%
\immediate\write\answerkeyfile{ }
\endgroup
}
\makeatother
\AtEndDocument{%
\immediate\closeout\answerkeyfile
}
\begin{document}
Answer these questions:
%% With \begin{enumerate}, this code works. Switch to
%% \begin{enumerate}[label=\emph{\alph*)}] and it fails.
%\begin{enumerate}
\begin{enumerate}[label=\emph{\alph*)}]
\item Question 1 \answerkey{Answer 1}
\item Question 2 \answerkey{$\frac{1}{2}$}
\item Question 3 \answerkey{\begin{tikzpicture}
\draw (0,0) rectangle (1,1);
\end{tikzpicture}}
\end{enumerate}
Answer Key:
% Copy the mwe.keys to mwe.ans, then use this to show the answers.
%\input{mwe.ans}
\end{document}
正如评论中所述,将枚举行切换到使用enumitem
功能的行,这将失败。我该怎么做才能不损害我拥有但仍在使用的系统enumitem
?
这是我收到的错误:
! \@item 的使用与其定义不符。\text@command #1->\def \reserved@a {#1}\ifx \reserved@a \@empty \let \check@... l.37 \item 问题 1 \answerkey{答案 1}
更新:
下面的注释说,问题实际上不是 enumitem 代码,而是标签中的 \emph(或类似的 \textbf、\textit 等)。下面创建“假”标签的解决方案是最不具侵入性/最不复杂的,同时添加了标签格式传递到答案键文档的功能。我开始使用的代码没有将答案放入真正的枚举环境中,因此下面提出的解决方案对于我的情况来说是过度的。最后,根据下面的帮助/指导,我重写了 \answerkey 命令,如下所示:
\newcommand{\answerkey}[2][.]{%
\begingroup
\let\#\hashchar
\immediate\write\answerkeyfile{\expandafter\unexpanded
\expandafter{\@currentlabel}#1\ }
\immediate\write\answerkeyfile{\unexpanded{#2}}%
\immediate\write\answerkeyfile{ }
\endgroup
}
在实际使用中,它看起来是这样的:
如果使用默认项目标签:
\begin{enumerate}
\item Question 1 \answerkey{Answer 1}
如果使用 enumitem 标签格式:
\begin{enumerate}[label={\arabic*.}]
\item Question 1 \answerkey[]{Answer 1}
答案1
我建议扩展\@currentlabel
该内容并将其写入文件,但是,这会在文件中\unexpanded
放置“假”项目标签,而不是真正的布局。\item
更好的策略是enumerate
在输出文件中“复制”环境。
\documentclass[10pt]{article}
\usepackage{pgfplots}
\usepackage{enumitem}
\newwrite\answerkeyfile
\AtBeginDocument{%
\immediate\openout\answerkeyfile=\jobname.keys
}
\begingroup
\catcode`\#=12
\gdef\hashchar{#}%
\endgroup
\makeatletter
\newcommand{\answerkey}[1]{%
\begingroup
\let\#\hashchar
\immediate\write\answerkeyfile{\expandafter\unexpanded\expandafter{\@currentlabel}.\ }
\immediate\write\answerkeyfile{\unexpanded{#1}}%
\immediate\write\answerkeyfile{ }
\endgroup
}
\makeatother
\AtEndDocument{%
\immediate\closeout\answerkeyfile
}
\begin{document}
Answer these questions:
%% With \begin{enumerate}, this code works. Switch to
%% \begin{enumerate}[label=\emph{\alph*)}] and it fails.
%\begin{enumerate}
\begin{enumerate}[label=\emph{\alph*)}]
\item Question 1 \answerkey{Answer 1}
\item Question 2 \answerkey{$\frac{1}{2}$}
\item Question 3 \answerkey{\begin{tikzpicture}
\draw (0,0) rectangle (1,1);
\end{tikzpicture}}
\end{enumerate}
Answer Key:
% Copy the mwe.keys to mwe.ans, then use this to show the answers.
\immediate\closeout\answerkeyfile
\input{\jobname.keys}
\end{document}
另一种方法是写入\begin{answerenumerate}
文件,该文件enumerate
基本上是:
\documentclass[10pt]{article}
\usepackage{pgfplots}
\usepackage{enumitem}
\newwrite\answerkeyfile
\AtBeginDocument{%
\immediate\openout\answerkeyfile=\jobname.keys
}
\begingroup
\catcode`\#=12
\gdef\hashchar{#}%
\endgroup
\makeatletter
\newcommand{\answerkey}[1]{%
\begingroup
\let\#\hashchar
\immediate\write\answerkeyfile{\string\item}
\immediate\write\answerkeyfile{\unexpanded{#1}}%
\immediate\write\answerkeyfile{ }
\endgroup
}
\makeatother
\AtEndDocument{%
\immediate\closeout\answerkeyfile
}
\begin{document}
Answer these questions:
\newlist{answerenumerate}{enumerate}{1}
\setlist[answerenumerate]{label=\emph{\alph*)}}
\setlist[enumerate,1]{label=\emph{\alph*)},
before={\immediate\write\answerkeyfile{\string\begin{answerenumerate}}},
after={\immediate\write\answerkeyfile{\string\end{answerenumerate}}}
}
\begin{enumerate}
\item Question 1 \answerkey{Answer 1}
\item Question 2 \answerkey{$\frac{1}{2}$}
\item Question 3 \answerkey{\begin{tikzpicture}
\draw (0,0) rectangle (1,1);
\end{tikzpicture}}
\end{enumerate}
Answer Key:
% Copy the mwe.keys to mwe.ans, then use this to show the answers.
\immediate\closeout\answerkeyfile
\input{\jobname.keys}
\end{document}
答案2
您应该使用ref
的功能enumitem
,同时利用包支撑的事实\@currentlabel
。
按你喜欢的方式定义\answeritem
。
\documentclass[10pt]{article}
\usepackage{pgfplots}
\usepackage{enumitem}
\newwrite\answerkeyfile
\AtBeginDocument{%
\immediate\openout\answerkeyfile=\jobname.keys
}
\edef\hashchar{\string#}
\makeatletter
\newcommand{\answerkey}[1]{%
\begingroup
\let\#\hashchar
\immediate\write\answerkeyfile{\answeritem\@currentlabel}
\immediate\write\answerkeyfile{\unexpanded{#1}^^J}%
\endgroup
}
\protected\def\answeritem#1{\item[\emph{#1})]}
\makeatother
\begin{document}
Answer these questions:
%% With \begin{enumerate}, this code works. Switch to
%% \begin{enumerate}[label=\emph{\alph*)}] and it fails.
%\begin{enumerate}
\begin{enumerate}[label=\emph{\alph*}),ref=\alph*]
\item Question 1 \answerkey{Answer 1}
\item Question 2 \answerkey{$\frac{1}{2}$}
\item Question 3 \answerkey{\begin{tikzpicture}
\draw (0,0) rectangle (1,1);
\end{tikzpicture}}
\end{enumerate}
Answer Key:
\immediate\closeout\answerkeyfile
\begin{enumerate}
\input{\jobname.keys}
\end{enumerate}
\end{document}
以下是输出\jobname.keys
:
\answeritem {a}
Answer 1
\answeritem {b}
$\frac {1}{2}$
\answeritem {c}
\begin {tikzpicture} \draw (0,0) rectangle (1,1); \end {tikzpicture}
关于这个问题还有几点话要说。
键ref
定义存储在 中的内容\@currentlabel
(通常写在.aux
文件中,但您自己使用它)。写入.aux
文件是安全的,因为\protected@write
LaTeX 使用 ;但是您使用的\write
和\emph
并不是 TeX 喜欢在那里看到的命令。您可以使用\protected@iwrite
(您可以在网站上找到如何定义它),但我上面建议的技巧更好,因为您可以决定\answeritem
扩展为什么。重要的是它的定义是\protected
,因此它在操作期间将保持不变\write
。