10

I teach university courses and my goal is to be able to output two pdf's from the same tex file:

  1. A problem set
  2. A problem set with solutions

I already do this manually by calling \newif and then setting \soltrue or \solfalse in the header depending on whether I want to output solutions or not. Then I surround the solutions in \ifsol and \fi and we're off to the races. It's great because edits to the problem set require changes to only one document, not two. The only annoyance is that I have to compile it once, change that pdf's name, then change the header from \soltrue to \solfalse, then recompile again to get both documents. I'd like to use arara to automate this.

I've been following this excellent how-to on creating a yaml rule to get arara to do what I want. In the how-to, the author (cmhughes) creates a rule to compile a tex document into two pdf's, one with one column and the other with two. Obviously my application is slightly different.

I have created the following solutions.yaml rule:

!config
# Make two versions of document depending on if statement "sol"
# author: Shane Auerbach (based on work by Chris Hughes)
# requires arara 3.0+
#
# Sample usage
#
# % arara: solutions
# % arara: solutions: {solutions: true}
# % arara: solutions: {solutions: false}
#
identifier: solutions
name: Solutions
commands: 
- <arara> pdflatex "\newif\ifsol\sol@{trigger}\input{@{file}}" 
- <arara> @{ isWindows( "cmd /c move", "mv" ) } @{getBasename(file)}.pdf @{getBasename(file)}@{trigger.toUpperCase()}.pdf
arguments: 
- identifier: trigger
  flag: <arara> @{parameters.trigger}
  default: false

And this is the test mytex.tex file:

% arara: solutions:  {trigger: true}
% arara: solutions: {trigger: false}

\documentclass{article}
\begin{document}
Question: What is $2+2$?
\ifsol \begin{quote} \textbf{Solution:} $2+2=3$ \end{quote} \fi
\end{document}

It works great. When I run arara on the tex file, it outputs two pdf's, one with the solution and one without, as desired. There are two improvements I would like to make but do not know how to implement:

  1. As is, I can currently only compile the tex file with arara as the file itself has neither \soltrue nor \solfalse in it. I would like to be able to put in something that set it if and only if it was not already set by arara so that I could compile this outside of arara also. But I do not want it to overwrite arara's setting, as this would defeat the purpose. Any ideas?

  2. Currently the pdf files generated are called mytexTRUE.pdf (with solutions) and mytexFALSE.pdf (without solutions). I'd prefer to have something like mytexS.pdf (with solutions) and mytexQ.pdf (without solutions). The only way I could think to implement this would be a conditional statement in solutions.yaml, but from what I've read yaml is not really designed for conditional statements. Any ideas on this front?

If you've read this far, you're a true hero. Thanks! If you skipped the middle, tl;dr: help this stranger make his workflow ever-so-slightly more efficient.

  • Hello! Sorry for missing your question earlier! I will come up with some suggestions for improvements later on. Version 4.0 of arara might have some goodies for this case, but since it's not officially released (it's in the works), I will write a compatible solution for version 3.0 as well. :) – Paulo Cereda Jun 7 '16 at 21:20
10

A possible way to achieve the first improvement is by exploiting \ifdefined instead of relying on a \newif, as in the original code. Let us see the new TeX code:

\documentclass{article}
\begin{document}
Question: What is $2+2$?
\ifdefined\solutionflag\begin{quote} \textbf{Solution:} $2+2=3$ \end{quote}\fi
\end{document}

The plan here is straightforward: if \solutionflag is defined, that particular code excerpt will be processed. The idea is very similar to using \if<flag>, but it does not complain if this contraption isn't set. :)

The previous code can be normally compiled with your favourite engine and does not require arara. If you want to print the answers, just write \def\solutionflag{} somewhere in the preamble and we are done.

Now, the arara part. As mentioned in the comments, I will provide a solution for version 3.0 (the current one). When version 4.0 is out, the syntax will change a little, so I will update this answer accordingly. :)

Let us take a look at this improved rule:

!config
# Make two versions of document depending on defining a \solutionflag command
# author: Shane Auerbach (based on work by Chris Hughes)
# requires arara 3.0
identifier: solutions
name: Solutions
commands: 
- <arara> pdflatex "@{ isTrue(solutions, '\\def\\solutionflag{}','') }\input{@{file}}" 
- <arara> @{ isWindows( "cmd /c move", "mv" ) } @{getBasename(file)}.pdf @{ getBasename(file) }@{ isEmpty(name, solutions.toUpperCase(), name) }.pdf
arguments:
- identifier: name
  flag: <arara> @{parameters.name}
- identifier: solutions
  flag: <arara> @{parameters.solutions}
  default: false

I took the liberty of renaming trigger to solutions.

So, we now have two rule parameters: solutions and name. The first acts as a boolean flag indicating if the solutions should be displayed and the latter regards the suffix to be added to the base name. A sample execution:

% arara: solutions: { solutions: true, name: 'A' }
% arara: solutions: { solutions: false, name: 'Q' }

\documentclass{article}
\begin{document}
Question: What is $2+2$?
\ifdefined\solutionflag\begin{quote} \textbf{Solution:} $2+2=3$ \end{quote}\fi
\end{document}

When running it with arara:

[paulo@cambridge ~] $ arara test.tex 
  __ _ _ __ __ _ _ __ __ _ 
 / _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
 \__,_|_|  \__,_|_|  \__,_|

Running Solutions... SUCCESS
Running Solutions... SUCCESS
Running Solutions... SUCCESS
Running Solutions... SUCCESS

We get the following output:

[paulo@cambridge ~] $ ls test*.pdf
testA.pdf  testQ.pdf

Note that the Q and A prefixes were provided in the directive parameters. If we ommit one of them, the rule will append TRUE or FALSE (all in caps) to the base name, as the original rule.

Another interesting suggestion is to improve your document semantics by creating an environment to selectively display solutions. The following code was kindly suggested by David Carlisle (I owe him $5):

\newenvironment{solution}{\ifdefined\solutionflag\else\setbox0\vbox\fi\bgroup}{‌​\par\egroup}

Hope it helps! :)

  • This is fantastic -- thank you, Paulo, for arara and your support of its users! – Shane Jun 8 '16 at 3:01
  • @Shane: My pleasure, I am at your service. :) – Paulo Cereda Jun 8 '16 at 10:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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