Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to save the present value of an enumeration into an output file. Using information from another question I have the following minimal example:

\documentclass{article}


\newcommand{\collectSolutions}{\immediate\openout\tempfile=solutions.tex}

\newwrite\tempfile

\newcommand{\solution}[1]{\immediate\write\tempfile{\theenumi\theenumii\theenumiii:\unexpanded{#1}}}

\newcommand{\printSolutions}{%
\immediate\closeout\tempfile
\noindent\input{solutions}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}

\collectSolutions

\begin{enumerate}
    \item Text 
    \begin{enumerate}
      \item Part Q 1 \solution{A}
      \item Part Q 1 \solution{B}
      \item Part Q 1 \solution{\mbox{$solution$}}
    \end{enumerate}
    \item Another Q \solution{D}
\end{enumerate}

\printSolutions

\end{document}

The out put lists the final question as being 2c. I assume this is because the enumii counter is not reset until this level is restarted. All the same, how can I obtain the 1a, 1b, 1c, 2 in the final list from \printSolutions?

share|improve this question
add comment

1 Answer 1

up vote 7 down vote accepted

Define control sequences based on the depths; one could use \p@enumi, \p@enumii and \p@enumiii, but the result would depend on the class; in this way, instead, you can choose your own representation.

The key is that the macro \@enumctr records the current enumeration counter name; thus with

\csname sol@\@enumctr\endcsname

we access \sol@enumi, \sol@enumii or \sol@enumiii without manual intervention. Adjust the meaning of these macros to suit your needs.

\documentclass{article}

\makeatletter
\newwrite\solutions@file
\newcommand{\collectSolutions}{\immediate\openout\solutions@file=\jobname.sol}
\newcommand{\sol@enumi}{\theenumi}
\newcommand{\sol@enumii}{\theenumi.\theenumii}
\newcommand{\sol@enumiii}{\theenumi.\theenumii.\theenumiii}
\newcommand{\solution}[1]{%
  \immediate\write\solutions@file{%
    \csname sol@\@enumctr\endcsname: \unexpanded{#1}%
  }%
}

\newcommand{\printSolutions}{%
  \immediate\closeout\solutions@file
  \noindent\input{\jobname.sol}
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}

\collectSolutions

\begin{enumerate}
    \item Text 
    \begin{enumerate}
      \item Part Q 1 \solution{A}
      \item Part Q 1 \solution{B}
      \item Part Q 1 \solution{C}
    \end{enumerate}
    \item Another Q \solution{D}
\end{enumerate}

\printSolutions

\end{document}

This is the contents of the "solutions" file:

1.a: A
1.b: B
1.c: C
2: D

I prefer not to give a "fixed" name to the output file, so as not to clobber existing files. With the proposed macros, the output file will have the same name as the main LaTeX file with extension .sol.


If you want to add formatting instructions for writing in the .sol file, then you have two ways.

First method

\newcommand{\sol@enumi}{\noexpand\textbf{\theenumi}}

will not expand \textbf when the writing operation takes place. Every "unsafe" macro should be preceded by \noexpand (not \theenumi, which we want to be expanded right away).

Second method

Define a \protected@immediatewrite macro similar to \protected@write:

\makeatletter
\newwrite\solutions@file
\newcommand{\collectSolutions}{\immediate\openout\solutions@file=\jobname.sol}
\newcommand{\sol@enumi}{\textbf{\theenumi}}
\newcommand{\sol@enumii}{\theenumi.\theenumii}
\newcommand{\sol@enumiii}{\theenumi.\theenumii.\theenumiii}

\newcommand{\protected@immediatewrite}[3]{%
  \begingroup
    \let\thepage\relax
    #2% additional settings
    \let\protect\@unexpandable@protect
    \edef\reserved@a{\immediate\write#1{#3}}\reserved@a
  \endgroup
  \if@nobreak\ifvmode\nobreak\fi\fi
}

\newcommand{\solution}[1]{%
  \protected@immediatewrite\solutions@file{}{\csname sol@\@enumctr\endcsname: \unexpanded{\unexpanded{#1}}}}

\newcommand{\printSolutions}{%
  \immediate\closeout\solutions@file
  \noindent\input{\jobname.sol}
}
\makeatother

The rest of the file can be the same as before.

share|improve this answer
    
+1. I was about to post a solution that used a loop to concatenate \theenum... based on the \@enumdepth, but this solution seems cleaner. –  cyberSingularity Dec 26 '12 at 11:35
    
This works great. A question though: you say ``Adjust the meaning of these macros to suit your needs.'' so I tried to make the question number bold, so I did \textbf{\theenumi} but this didn't work. –  Geoff Dec 26 '12 at 18:45
    
@Geoff No, formatting instructions must be protected against expansion. I'll add a more robust way for this. –  egreg Dec 26 '12 at 18:49
    
@egreg Thx for the update. The first method works, the second method hits problems when there is a box (an mbox in my case) within the \solution input. –  Geoff Dec 26 '12 at 19:10
    
@Geoff Please, add some example cases. –  egreg Dec 26 '12 at 20:08
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.