Generando dos versiones en pdf (basadas en una declaración condicional) del mismo archivo tex con arara

Generando dos versiones en pdf (basadas en una declaración condicional) del mismo archivo tex con arara

Doy cursos universitarios y mi objetivo es poder generar dos pdfdel mismo texarchivo:

  1. un conjunto de problemas
  2. Un conjunto de problemas con soluciones.

Ya hago esto manualmente llamando \newify luego configurando \soltrueo \solfalseen el encabezado dependiendo de si quiero generar soluciones o no. Luego rodeo las soluciones \ifsoly \finos vamos a las carreras. Es fantástico porque las ediciones del conjunto de problemas requieren cambios en un solo documento, no en dos. La única molestia es que tengo que compilarlo una vez, cambiar el pdfnombre, luego cambiar el encabezado de \soltruea \solfalsey luego volver a compilar para obtener ambos documentos. Me gustaría utilizar ararapara automatizar esto.

He estado siguiendo este excelente.cómoen crear una yamlregla para poder ararahacer lo que quiero. En el procedimiento, el autor (cmhughes) crea una regla para compilar un texdocumento en dos pdf, uno con una columna y el otro con dos. Obviamente mi aplicación es ligeramente diferente.

He creado la siguiente solutions.yamlregla:

!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

Y este es el mytex.texarchivo de prueba:

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

Funciona muy bien. Cuando ejecuto ararael texarchivo, genera dos pdf, uno con la solución y otro sin ella, según se desee. Hay dos mejoras que me gustaría hacer pero no sé cómo implementarlas:

  1. Tal como está, actualmente solo puedo compilar el texarchivo, araraya que el archivo en sí no tiene ni \soltruecontenido \solfalse. Me gustaría poder poner algo que lo configure si y solo si aún no lo ha configurado ararapara poder compilarlo fuera de araratambién. Pero no quiero que sobrescriba ararala configuración, ya que esto frustraría el propósito. ¿Algunas ideas?

  2. Actualmente los pdfarchivos generados se llaman mytexTRUE.pdf(con soluciones) y mytexFALSE.pdf(sin soluciones). Preferiría tener algo como mytexS.pdf(con soluciones) y mytexQ.pdf(sin soluciones). La única forma en que se me ocurre implementar esto sería una declaración condicional en solutions.yaml, pero por lo que he leído, yamlen realidad no está diseñado para declaraciones condicionales. ¿Alguna idea en este frente?

Si has leído hasta aquí, eres un verdadero héroe. ¡Gracias! Si te saltaste la mitad, tl;dr: ayuda a este extraño a hacer que su flujo de trabajo sea un poco más eficiente.

Respuesta1

Una posible forma de lograr la primera mejora es explotando \ifdefineden lugar de depender de un \newif, como en el código original. Veamos el nuevo código TeX:

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

El plan aquí es sencillo: si \solutionflagse define, se procesará ese extracto de código en particular. La idea es muy similar a usar \if<flag>, pero no se queja si este artilugio no está configurado.:)

El código anterior normalmente se puede compilar con su motor favorito y no requiere arara. Si desea imprimir las respuestas, simplemente escriba \def\solutionflag{}en algún lugar del preámbulo y listo.

Actualizar:esta respuesta se actualiza con una regla para la versión 4.0+. Consulte el historial de ediciones para ver versiones anteriores.

Echemos un vistazo a esta regla mejorada:

!config
identifier: solutions
name: Solutions
authors:
- A duck
commands:
- name: The engine
  command: >
    @{
        prefix = isTrue(solutions, '\\def\\solutionflag{}', '');
        input = '\\input{' + reference.getName() + '}';
        return getCommand(engine, prefix + input, options);
    }
- name: The renaming procedure
  command: >
    @{
        separator = java.io.File.separator;
        prefix = [];
        if (isUnix()) {
            prefix = [ 'mv' ];
        }
        else {
            prefix = [ 'cmd', '/c', 'move' ];
        }
        parent = reference.getParent(); 
        input = parent + separator + getBasename(reference) + '.pdf';
        output = parent + separator + name + '.pdf';
        return getCommand(prefix, input, output);
    }
arguments:
- identifier: engine
  flag: >
    @{
        if ([ 'pdflatex', 'latex', 'xelatex',
              'lualatex' ].contains(parameters.engine)) {
            return parameters.engine;
        }
        else {
            throwError('The provided engine is not valid');
        }
    }
  default: pdflatex
- identifier: name
  flag: >
    @{
        return parameters.name;
    }
  required: true
- identifier: solutions
  flag: >
    @{
        return isTrue(parameters.solutions);
    }
  default: >
    @{
        return false
    }
- identifier: options
  flag: >
    @{
        if (isList(parameters.options)) {
            return parameters.options;
        }
        else {
            throwError('I was expecting a list of options.');
        }
    }

Los argumentos de la regla:

  • engine: cadena, opcional, configura el motor. Las opciones posibles son pdflatex, y latex. Por defecto: .xelatexlualatexpdflatex

  • solutions: booleano natural, opcional, establece si la macro de solución se definirá en el alcance del documento. Por defecto: false.

  • name: cadena, obligatoria, establece el nombre del documento. El nombre del documento cambiará a este valor. No es necesario especificar la .pdfextensión.

  • options: lista, opcional, establece la lista de parámetros de línea de comando adicionales que se proporcionarán al motor.

Una ejecución de muestra:

% arara: solutions: { solutions: true, name: 'answers' }
% arara: solutions: { solutions: false, name: 'questions' }

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

Al ejecutarlo con arara:

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

Processing 'test.tex' (size: 264 bytes, last modified: 03/22/2020
06:54:54), please wait.

(Solutions) The engine .................................. SUCCESS
(Solutions) The renaming procedure ...................... SUCCESS
(Solutions) The engine .................................. SUCCESS
(Solutions) The renaming procedure ...................... SUCCESS

Total: 1.25 seconds

Obtenemos el siguiente resultado:

[paulo@cambridge ~] $ ls *.pdf
answers.pdf  questions.pdf

Otra sugerencia interesante es mejorar la semántica de sus documentos creando un entorno para mostrar soluciones de forma selectiva. David Carlisle sugirió amablemente el siguiente código (le debo $5):

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

¡Espero eso ayude!:)

información relacionada