将枚举项写入文件

将枚举项写入文件

我是一名教师,经常需要制作带有答案的工作表和评论。在 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@writeLaTeX 使用 ;但是您使用的\write\emph并不是 TeX 喜欢在那里看到的命令。您可以使用\protected@iwrite(您可以在网站上找到如何定义它),但我上面建议的技巧更好,因为您可以决定\answeritem扩展为什么。重要的是它的定义是\protected,因此它在操作期间将保持不变\write

相关内容