Writing enumitem's to a file

You should use the ref feature of enumitem, also exploiting the fact that the package braces the \@currentlabel.

Define \answeritem as you like.

\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}

Here's the output in \jobname.keys:

\answeritem {a}
Answer 1

\answeritem {b}
$\frac {1}{2}$

\answeritem {c}
\begin {tikzpicture} \draw (0,0) rectangle (1,1); \end {tikzpicture}

enter image description here

Some more words about the problem.

The key ref defines what's stored in \@currentlabel (typically written in the .aux file, but you're using it yourself). Writing in the .aux file is safe, because \protected@write is used by LaTeX; however you're using \write and \emph is not a command TeX likes to see there. You could use \protected@iwrite (you find how to define it on the site), but the trick I suggest above is even better because you can then decide what \answeritem gets expanded to. It's important its definition is \protected, so it will remain untouched during the \write operation.


I suggest to expand \@currentlabel and write that content to the file with \unexpanded, however, this will place 'fake' item labels and not really \item layout in the file.

A better strategy would be to 'replicate' the enumerate environment in the output file.

\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}

Another approach by writing \begin{answerenumerate} to the file, which is a copy of enumerate, basically:

\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}

enter image description here

Tags:

Enumitem