Создание двух версий PDF (на основе условного оператора) из одного и того же файла tex с помощью arara

Создание двух версий PDF (на основе условного оператора) из одного и того же файла tex с помощью arara

Я преподаю в университете, и моя цель — научиться выводить два pdfфайла tex:

  1. Набор проблем
  2. Проблема с решениями

Я уже делаю это вручную, вызывая \newifи затем устанавливая \soltrueили \solfalseв заголовке в зависимости от того, хочу ли я выводить решения или нет. Затем я заключаю решения в \ifsolи , \fiи мы отправляемся в путь. Это здорово, потому что редактирование набора задач требует изменений только в одном документе, а не в двух. Единственное, что раздражает, это то, что мне нужно скомпилировать его один раз, изменить pdfимя этого , затем изменить заголовок с \soltrueна \solfalse, затем снова перекомпилировать, чтобы получить оба документа. Я хотел бы использовать araraдля автоматизации этого.

Я следил за этим прекраснымкако создании yamlправила, чтобы araraсделать то, что я хочу. В инструкции автор (cmhughes) создает правило для компиляции texдокумента в два pdf, один с одним столбцом, а другой с двумя. Очевидно, мое приложение немного отличается.

Я создал следующее solutions.yamlправило:

!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

А это тестовый 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}

Работает отлично. Когда я запускаю araraфайл tex, он выводит два pdf', один с решением и один без, как и требовалось. Есть два улучшения, которые я хотел бы сделать, но не знаю, как это реализовать:

  1. Как есть, в настоящее время я могу скомпилировать файл только texс помощью , araraпоскольку сам файл не имеет ни \soltrueни \solfalseв себе. Я хотел бы иметь возможность вставить что-то, что устанавливало бы его, если и только если он еще не был установлен, araraчтобы я мог скомпилировать это вне araraalso. Но я не хочу, чтобы он перезаписывал araraнастройку , так как это противоречило бы цели. Есть идеи?

  2. В настоящее время pdfгенерируемые файлы называются mytexTRUE.pdf(с решениями) и mytexFALSE.pdf(без решений). Я бы предпочел что-то вроде mytexS.pdf(с решениями) и mytexQ.pdf(без решений). Единственный способ, который я мог придумать для реализации этого, — это условный оператор в solutions.yaml, но из того, что я читал, yamlон на самом деле не предназначен для условных операторов. Есть идеи на этот счет?

Если вы дочитали до этого места, вы настоящий герой. Спасибо! Если вы пропустили середину, то вкратце: помогите этому незнакомцу сделать его рабочий процесс хоть немного эффективнее.

решение1

Возможный способ достижения первого улучшения — эксплуатация \ifdefinedвместо того, чтобы полагаться на \newif, как в исходном коде. Давайте посмотрим на новый код TeX:

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

План здесь прост: если \solutionflagопределено, то будет обработан этот конкретный фрагмент кода. Идея очень похожа на использование \if<flag>, но он не жалуется, если эта штуковина не установлена.:)

Предыдущий код может быть нормально скомпилирован вашим любимым движком и не требует arara. Если вы хотите распечатать ответы, просто напишите \def\solutionflag{}где-нибудь в преамбуле, и мы закончили.

Обновлять:этот ответ обновлен правилом для версии 4.0+. Проверьте историю правок и более старую версию.

Давайте рассмотрим это улучшенное правило:

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

Аргументы правила:

  • engine: string, необязательно, задает движок. Возможные варианты: pdflatex, latex, xelatexи lualatex. По умолчанию: pdflatex.

  • solutions: натуральное логическое значение, необязательное, устанавливает, будет ли определен макрос решения в области действия документа. По умолчанию: false.

  • name: string, обязательно, задает имя документа. Документ будет переименован в это значение. Не нужно указывать расширение .pdf.

  • options: список, необязательный, задает список дополнительных параметров командной строки, которые будут предоставлены движку.

Пример исполнения:

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

При запуске с 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

Получаем следующий вывод:

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

Еще одно интересное предложение — улучшить семантику документа, создав среду для выборочного отображения решений. Следующий код любезно предложил Дэвид Карлайл (я должен ему 5 долларов):

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

Надеюсь, поможет!:)

Связанный контент