Generieren von zwei PDF-Versionen (basierend auf bedingten Anweisungen) aus derselben Tex-Datei mit Arara

Generieren von zwei PDF-Versionen (basierend auf bedingten Anweisungen) aus derselben Tex-Datei mit Arara

pdfIch unterrichte Universitätskurse und mein Ziel ist es, zwei 's aus derselben Datei ausgeben zu können tex:

  1. Eine Reihe von Problemen
  2. Ein Problemsatz mit Lösungen

Ich mache das bereits manuell, indem ich aufrufe und dann oder im Header \newifeinstelle, je nachdem, ob ich Lösungen ausgeben möchte oder nicht. Dann umschließe ich die Lösungen mit und und schon kann es losgehen. Das ist großartig, weil Änderungen am Problemsatz nur Änderungen an einem Dokument erfordern, nicht an zwei. Das einzige Ärgernis ist, dass ich es einmal kompilieren muss, den Namen von ändern muss, dann den Header von in ändern muss und dann erneut kompilieren muss, um beide Dokumente zu erhalten. Ich würde das gerne automatisieren, indem ich verwende.\soltrue\solfalse\ifsol\fipdf\soltrue\solfalsearara

Ich verfolge diese ausgezeichnetewie manzum Erstellen einer yamlRegel, um das zu erreichen arara, was ich will. In der Anleitung erstellt der Autor (cmhughes) eine Regel, um ein texDokument in zwei pdf's zu kompilieren, eines mit einer Spalte und das andere mit zwei. Offensichtlich ist meine Anwendung etwas anders.

Ich habe folgende solutions.yamlRegel erstellt:

!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

Und das ist die Testdatei mytex.tex:

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

Es funktioniert großartig. Wenn ich araradie texDatei ausführe, werden zwei 's ausgegeben pdf, eines mit der Lösung und eines ohne, wie gewünscht. Es gibt zwei Verbesserungen, die ich gerne vornehmen würde, aber nicht weiß, wie ich sie umsetzen soll:

  1. texSo wie es ist, kann ich die Datei derzeit nur mit kompilieren, ararada die Datei selbst weder \soltruenoch \solfalseenthält. Ich möchte etwas einfügen können, das es genau dann festlegt, wenn es nicht bereits von festgelegt wurde, araradamit ich es araraauch außerhalb von kompilieren könnte. Aber ich möchte nicht, dass araradie Einstellung von überschrieben wird, da dies den Zweck verfehlen würde. Irgendwelche Ideen?

  2. Derzeit pdfheißen die generierten Dateien mytexTRUE.pdf(mit Lösungen) und mytexFALSE.pdf(ohne Lösungen). Ich hätte lieber etwas wie mytexS.pdf(mit Lösungen) und mytexQ.pdf(ohne Lösungen). Die einzige Möglichkeit, dies umzusetzen, die mir einfällt, wäre eine bedingte Anweisung in solutions.yaml, aber soweit ich gelesen habe, yamlist es nicht wirklich für bedingte Anweisungen ausgelegt. Irgendwelche Ideen diesbezüglich?

Wenn Sie bis hierhin gelesen haben, sind Sie ein wahrer Held. Danke! Wenn Sie den Teil mit dem Text übersprungen haben, tl;dr: Helfen Sie diesem Fremden, seinen Arbeitsablauf ein klein wenig effizienter zu gestalten.

Antwort1

Eine Möglichkeit, die erste Verbesserung zu erreichen, besteht darin, \ifdefinedstatt sich \newifwie im Originalcode auf einen zu verlassen, einen auszunutzen. Sehen wir uns den neuen TeX-Code an:

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

Der Plan ist hier unkompliziert: Wenn \solutionflagdefiniert ist, wird dieser bestimmte Codeausschnitt verarbeitet. Die Idee ist der Verwendung von sehr ähnlich \if<flag>, aber es gibt keine Beanstandungen, wenn diese Vorrichtung nicht festgelegt ist.:)

Der vorherige Code kann normalerweise mit Ihrer bevorzugten Engine kompiliert werden und erfordert kein arara. Wenn Sie die Antworten ausdrucken möchten, schreiben Sie einfach \def\solutionflag{}irgendwo in die Präambel und wir sind fertig.

Aktualisieren:Diese Antwort wurde mit einer Regel für Version 4.0+ aktualisiert. Überprüfen Sie den Bearbeitungsverlauf für eine ältere Version.

Schauen wir uns diese verbesserte Regel einmal an:

!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.');
        }
    }

Die Regelargumente:

  • engine: Zeichenfolge, optional, legt die Engine fest. Mögliche Optionen sind pdflatex, latex, xelatexund lualatex. Standard: pdflatex.

  • solutions: natürlicher Boolescher Wert, optional, legt fest, ob das Lösungsmakro im Dokumentbereich definiert wird. Standard: false.

  • name: Zeichenfolge, erforderlich, legt den Dokumentnamen fest. Das Dokument wird in diesen Wert umbenannt. Die .pdfErweiterung muss nicht angegeben werden.

  • options: Liste, optional, legt die Liste der zusätzlichen Befehlszeilenparameter fest, die der Engine bereitgestellt werden sollen.

Eine Beispielausführung:

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

Beim Ausführen mit 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

Wir erhalten die folgende Ausgabe:

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

Ein weiterer interessanter Vorschlag besteht darin, die Semantik Ihres Dokuments zu verbessern, indem Sie eine Umgebung erstellen, in der Lösungen selektiv angezeigt werden. Der folgende Code wurde freundlicherweise von David Carlisle vorgeschlagen (ich schulde ihm 5 $):

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

Ich hoffe es hilft!:)

verwandte Informationen