Nearly seven years ago I was updating two mathematics textbooks (An Undergraduate Introduction to Financial Mathematics and A First Course in Partial Differential Equations) for which I am author or co-author. These books are composed using the LaTeX text formatting system. Figures are created and solutions are checked with the assistance of Wolfram Mathematica. In earlier editions of both texts, homework exercises were found at the end of each chapter. The instructors’ and students’ solution manuals were composed as completely separate LaTeX productions. Hence if an exercise was modified in the textbook, corresponding modifications had to take place in both the instructors’ and students’ solution manuals. For the latest editions I had hope that the xsim (eXercise Sheets IMproved) would streamline the composition of the exercises in the textbooks and automatically update the solution manuals. In case you have not used xsim package, it provides two new environments relevant to exercises and solutions (in the context of books, homework sheets, tests, etc.). The environments work as in the following example.
\begin{exercise} Evaluate the following expression. \[ 1 + 1 \] \end{exercise} \begin{solution} \[ 1 + 1 = 2 \] \end{solution}
The xsim package allows me to include the exercise and its solution in the same LaTeX file. In the prologue section of the LaTeX for the textbook, I include the following code segment. It instructs LaTeX to store the bodies of exercise and solution environments as individual text files in the subdirectory “exercises” of the current working directory. Exercises should be numbered within each section. The textbook will have multiple sections within each chapter. It also specifies that the solutions should not be printed in the output of the LaTeX compile step.
\xsimsetup{% path = {exercises}, exercise/within = {section}, solution/print = false }
The xsim manual states that exercises and solutions can be collected (either printed or not printed) and later printed. However, I found that could not quite achieve the result I wanted (probably due to my confusion over the instructions in the xsim manual). I wanted a separate LaTeX file for the solution manual with just the solutions. The instructors’ solution manual should contain solutions to all the exercises in the textbook and the students’ solution manual should contain only every other solution. While not able to achieve the needed results using just LaTeX, a little programming in Wolfram Mathematica combined with LaTeX yields acceptable results.
When xsim is used in LaTeX a file with the extension “.xsim” is created with useful information about the exercises and solutions. Here is a sample of that file.
\XSIM \XSIM{counter}{exercise-1=={1.1.1}||exercise-2=={1.1.2}||exercise-3== ...}
This particular textbook contains 716 exercises and solutions. The first exercise has a Chapter.Section.Exercise numbering of “1.1.1” and goes from there. At first I though I could use the LaTeX multido command to embed each solution using the LaTeX “\include{}” command. The biggest drawback to this approach is the situation that the exercise and solution files xsim creates do not contain the “\begin{}” and “\end{}” tags and are simply named as “main-exercise-num-solution-body.tex” where num is one of {1, 2, …, 716}. Thus my strategy was to copy a static preamble file containing the typical LaTeX commands that start a document including:
the \documentclass{} command
all the necessary packages (mathtools, amsmath, etc.) and XR so that I can cross-reference equation, exercise, figure numbers in the textbook.
any necessary \newcommand, \renewcommand, \newenvironment, and \DeclareMathOperator commands
\begin{document}
This is accomplished using the
str = OpenAppend["Solutions.intro"]
Next I open the “.xsim” file and read until finding the line “\XSIM{counter}”. This line must be parsed by stripping off the “\XSIM{counter}{” text and the final closing “}”. Then the remaining text from that line must be split into substrings at each “||”.
solns = Map[StringSplit[#, "=="] &, StringSplit[ StringReplace[ First[FindList["main.xsim", "\\XSIM"]], {" -> "", "}}" -> "}"}], "||"]]
Out[4] = {{"exercise-1", {1.1.1}", {"exercise-2", {1.1.2}", {"exercise-3", {1.1.3}", ...}
Next for each element of the solns list append to the preamble LaTeX file a line like the following
\noindent\textbf{x,y,z} \input{exercises/main-exercise-num-solution-body}
where “x.y.z” is the chapter.section.exercise number and num is one of {1, 2, …, 716}.
numsolns = Map[If[OddQ[ToExpression[StringTrim[#[[1]], "exercise-"]]], StringJoin[ "\n\\noindent\\textbf" <> #[[2]] <> "\n\\input{exercises/main-" <> #[[1]] <> "-solution-body}\n"], Nothing] &, solns] Map[WriteString[str, #] &, numsolns]
Next append a line containing the “\end{document}” command and close the file. Finally I can compile the LaTeX file from the command line.