%20%D0%B8%D0%B7%20%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%B8%20%D1%82%D0%BE%D0%B3%D0%BE%20%D0%B6%D0%B5%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B0%20tex%20%D1%81%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E%20arara.png)
Я преподаю в университете, и моя цель — научиться выводить два pdf
файла tex
:
- Набор проблем
- Проблема с решениями
Я уже делаю это вручную, вызывая \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
', один с решением и один без, как и требовалось. Есть два улучшения, которые я хотел бы сделать, но не знаю, как это реализовать:
Как есть, в настоящее время я могу скомпилировать файл только
tex
с помощью ,arara
поскольку сам файл не имеет ни\soltrue
ни\solfalse
в себе. Я хотел бы иметь возможность вставить что-то, что устанавливало бы его, если и только если он еще не был установлен,arara
чтобы я мог скомпилировать это внеarara
also. Но я не хочу, чтобы он перезаписывалarara
настройку , так как это противоречило бы цели. Есть идеи?В настоящее время
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}
Надеюсь, поможет!:)