%20do%20mesmo%20arquivo%20tex%20com%20arara.png)
Dou aulas em cursos universitários e meu objetivo é conseguir gerar dois pdf
's do mesmo tex
arquivo:
- Um conjunto de problemas
- Um problema definido com soluções
Já faço isso manualmente chamando \newif
e configurando \soltrue
ou \solfalse
no cabeçalho dependendo se desejo gerar soluções ou não. Então cerco as soluções \ifsol
e \fi
partimos para as corridas. É ótimo porque as edições no conjunto de problemas exigem alterações em apenas um documento, não em dois. O único incômodo é que preciso compilá-lo uma vez, alterar o pdf
nome, alterar o cabeçalho de \soltrue
para \solfalse
e recompilar novamente para obter os dois documentos. Eu gostaria de usar arara
para automatizar isso.
Tenho acompanhado isso excelentecomoem criar uma yaml
regra para arara
fazer o que quero. No tutorial, o autor (cmhughes) cria uma regra para compilar um tex
documento em dois pdf
's, um com uma coluna e outro com duas. Obviamente, minha aplicação é um pouco diferente.
Eu criei a seguinte solutions.yaml
regra:
!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
E este é o mytex.tex
arquivo de teste:
% 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 muito bem. Quando executo arara
o tex
arquivo, ele gera dois pdf
, um com a solução e outro sem, conforme desejado. Há duas melhorias que gostaria de fazer, mas não sei como implementar:
Como está, atualmente só posso compilar o
tex
arquivo,arara
pois o próprio arquivo não contém\soltrue
nem\solfalse
nele. Eu gostaria de poder colocar algo que o definisse se e somente se ainda não estivesse definido,arara
para que eu pudesse compilar isso foraarara
também. Mas não quero substituirarara
a configuração de , pois isso anularia o propósito. Alguma ideia?Atualmente os
pdf
arquivos gerados são chamadosmytexTRUE.pdf
(com soluções) emytexFALSE.pdf
(sem soluções). Prefiro ter algo comomytexS.pdf
(com soluções) emytexQ.pdf
(sem soluções). A única maneira que eu poderia pensar de implementar isso seria uma declaração condicional emsolutions.yaml
, mas pelo que liyaml
não foi realmente projetado para declarações condicionais. Alguma ideia nesta frente?
Se você leu até aqui, você é um verdadeiro herói. Obrigado! Se você pulou o meio, tl; dr: ajude esse estranho a tornar seu fluxo de trabalho um pouco mais eficiente.
Responder1
Uma maneira possível de alcançar a primeira melhoria é explorar \ifdefined
em vez de confiar em um \newif
, como no código original. Vamos ver o novo 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}
O plano aqui é simples: se \solutionflag
for definido, esse trecho de código específico será processado. A ideia é muito parecida com o using \if<flag>
, mas não reclama se essa engenhoca não estiver configurada.:)
O código anterior pode ser compilado normalmente com seu mecanismo favorito e não requer arara
. Se quiser imprimir as respostas, basta escrever \def\solutionflag{}
em algum lugar do preâmbulo e pronto.
Atualizar:esta resposta é atualizada com uma regra para a versão 4.0+. Verifique o histórico de edições de uma versão mais antiga.
Vamos dar uma olhada nesta regra aprimorada:
!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.');
}
}
Os argumentos da regra:
engine
: string, opcional, define o mecanismo. As opções possíveis sãopdflatex
, elatex
. Padrão: .xelatex
lualatex
pdflatex
solutions
: booleano natural, opcional, define se a macro da solução será definida no escopo do documento. Padrão:false
.name
: string, obrigatório, define o nome do documento. O documento será renomeado para este valor. Não há necessidade de especificar a.pdf
extensão.options
: list, opcional, define a lista de parâmetros adicionais de linha de comando a serem fornecidos ao mecanismo.
Um exemplo de execução:
% 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}
Ao executá-lo com 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
Obtemos a seguinte saída:
[paulo@cambridge ~] $ ls *.pdf
answers.pdf questions.pdf
Outra sugestão interessante é melhorar a semântica do seu documento criando um ambiente para exibir soluções de forma seletiva. O código a seguir foi gentilmente sugerido por David Carlisle (devo US$ 5 a ele):
\newenvironment{solution}{\ifdefined\solutionflag\else\setbox0\vbox\fi\bgroup}{\par\egroup}
Espero que ajude!:)