Best way to part answers from solutions?
All of this can be achieved using the answers
and hyperref
package.
In the MWE below, I've linked the question number to the solution, and the solution number back to the question by using the hypertarget
and hyperlink
mechanism from the hyperref
package.
The example I have shown is very simple, but you can get pretty sophisticated with it as I've shown in my answer to
Contest: Show Off Your Skillz in TeX & Friends [TeX.sx birthday]
The main thing to note is that I have renewenvironment
for the solution file immediately before I have inputted it- you have to wait until this point to avoid messing up the process of writing to a file.
\documentclass{article}
\usepackage{answers}
\usepackage{enumitem}
\usepackage{hyperref}
\usepackage{multicol}
\setlength{\parindent}{0.0mm}
\hypersetup{colorlinks=true,
linkcolor=blue}
% very useful during de-bugging!
%\usepackage[left]{showlabels}
%\showlabels{hypertarget}
%\showlabels{hyperlink}
% solutions file
\Opensolutionfile{mysolutions}
\Newassociation{mysolution}{mySoln}{mysolutions}
% new environment that sets up hypertargets both in the question
% section, and in the answer section
\newlist{myenum}{enumerate}{3}
\newcounter{question}
\newenvironment{question}%
{%
\refstepcounter{question}%
% hyperlink to solution
\hypertarget{question:{\thequestion}}{}%
\Writetofile{mysolutions}{\protect\hypertarget{soln:\thequestion}{}}%
\begin{myenum}[label=\bfseries\protect\hyperlink{soln:\thequestion}{\thequestion},ref=\thequestion]
\item%
}%
{%
\end{myenum}}
\begin{document}
\section{Questions}
\begin{multicols}{3}
\begin{question}
$\int\sqrt{4-x}\mathrm{d}x$
\begin{mysolution}
$-\frac{2}{3}(4-x)^{\frac{3}{2}}+C$
\end{mysolution}
\end{question}
\begin{question}
$\int(2x-1)^{50}\mathrm{d}x$
\begin{mysolution}
$\frac{1}{102}(2x-1)^{51}+C$
\end{mysolution}
\end{question}
\begin{question}
$\int\sqrt[n]{x}\mathrm{d}x$
\begin{mysolution}
$\frac{n}{n+1}x^{\frac{1+n}{n}}+C$
\end{mysolution}
\end{question}
\end{multicols}
% close solution file
\Closesolutionfile{mysolutions}
% renew the solution environment so that it hyperlinks back to
% the question
\renewenvironment{mySoln}[1]{%
% add some glue
\vskip .5cm plus 2cm minus 0.1cm%
{\bfseries \hyperlink{question:#1}{#1.}}%
}%
{%
}%
\clearpage
\section{Answers!}
% input the file if it exists
\IfFileExists{mysolutions.tex}{\input{mysolutions.tex}}{}
\end{document}
You can define a new environment to write the answer verbatim into a seperate file, and then you can \input
the answer file when necessary.
Here is a private package for my own book:
\ProvidesPackage{latexexercise}[2011/08/03 by Leo]
\RequirePackage{verbatim}
\newwrite\ltxex@ansfile
\def\ltxex@ansfilename{\jobname.ans}
\newcounter{exercise}
\ifdefined\c@chapter
\@addtoreset{exercise}{chapter}
\def\theexercise{\arabic{chapter}.\arabic{exercise}}
\else\ifdefined\c@section
\@addtoreset{exercise}{section}
\def\theexercise{\arabic{section}.\arabic{exercise}}
\else
\def\theexercise{\arabic{exercise}}
\fi\fi
\def\exercisename{Exercise}
\newcommand\startexercise{%
\immediate\openout\ltxex@ansfile=\ltxex@ansfilename
\immediate\write\ltxex@ansfile{\noexpand\begin{answerlist}}}
\newcommand\stopexercise{%
\immediate\write\ltxex@ansfile{\noexpand\end{answerlist}}%
\immediate\closeout\ltxex@ansfile}
\newcommand\printanswer{%
\InputIfFileExists{\ltxex@ansfilename}%
{\PackageInfo{latexexercise}{answer file `\ltxex@ansfilename' inputed.}}%
{\PackageWarning{latexexercise}%
{answer file `\ltxex@ansfilename' does not exsist.}}}
\newenvironment{exercise}%
{\list{\ltxex@labelstyle\theexercise}%
{\ltxex@listargs\normalfont\normalsize}%
\ltxex@pre}%
{\endlist}
\newenvironment{answer}%
{\immediate\write\ltxex@ansfile{\noexpand\item[\theexercise]}%
\ltxex@startwrite}%
{\ltxex@endwrite}
\newenvironment{answerlist}%
{\list{}{\ltxex@anslistargs\normalfont\normalsize}}%
{\endlist}
%
\def\ltxex@pre{\item[]\hskip-\labelsep {\large\bfseries \exercisename}}
\def\ltxex@listargs{%
\@nmbrlisttrue\def\@listctr{exercise}%
%\topsep=0pt
\partopsep=0pt
\itemsep=0pt
\leftmargin=0pt
\rightmargin=0pt
\parsep=\parskip
\listparindent=\parindent
\itemindent=\parindent
\labelwidth=0pt
\labelsep=0.5em}
\def\ltxex@labelstyle{\bfseries}
\def\ltxex@anslistargs{%
\def\makelabel##1{\ltxex@anslabelstyle ##1}
\topsep=0pt
\partopsep=0pt
\itemsep=0pt
\leftmargin=0pt
\rightmargin=0pt
\parsep=\parskip
\listparindent=\parindent
\itemindent=\parindent
\labelwidth=0pt
\labelsep=0.5em}
\def\ltxex@anslabelstyle{\bfseries}
\def\ltxex@startwrite{%
\begingroup
\@bsphack
\let\do\@makeother \dospecials
\catcode`\^^M\active
\def\verbatim@processline{%
\immediate\write\ltxex@ansfile{\the\verbatim@line}}%
\verbatim@start}
\def\ltxex@endwrite{\@esphack\endgroup}
\endinput
Test code:
\documentclass{article}
\usepackage{latexexercise}
\begin{document}
\startexercise
\section{Foo}
\begin{exercise}
\item $1+1=?$
\begin{answer}
$1+1=2$.
\end{answer}
\item $2\times 2 = ?$
\begin{answer}
That's 4.
\end{answer}
\end{exercise}
\section{Bar}
\begin{exercise}
\item Foo
\begin{answer}
Bar
\end{answer}
\end{exercise}
\stopexercise
\section{Solutions}
\printanswer
\end{document}