arara를 사용하여 동일한 tex 파일에서 두 개의 PDF 버전(조건문 기반) 생성

arara를 사용하여 동일한 tex 파일에서 두 개의 PDF 버전(조건문 기반) 생성

pdf나는 대학 과정을 가르치고 있으며 내 목표는 동일한 파일에서 두 개의 '를 출력할 수 있는 것입니다 tex.

  1. 문제 세트
  2. 해결책이 있는 문제 세트

솔루션을 출력할지 여부에 따라 헤더에서 또는 를 호출한 \newif다음 설정하여 이미 이 작업을 수동으로 수행합니다 . 그런 다음 솔루션을 둘러싸서 경주 를 시작합니다. 문제 세트를 편집하려면 문서 두 개가 아닌 하나의 문서만 변경하면 되기 때문에 좋습니다. 유일한 성가심은 한 번 컴파일하고 이름을 변경한 다음 헤더를 에서 로 변경한 다음 두 문서를 모두 얻으려면 다시 컴파일해야 한다는 것입니다. 나는 이것을 자동화하는 데 사용하고 싶습니다 .\soltrue\solfalse\ifsol\fipdf\soltrue\solfalsearara

나는이 훌륭한 것을 따라 왔습니다어떻게내가 원하는 것을 하기 yaml위한 규칙을 만드는 것 . araraHow-to에서 작성자(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\solfalseararaararaarara

  2. 현재 생성된 파일은 (솔루션 포함) 및 (솔루션 없음) pdf이라고 합니다 . 나는 (솔루션 포함) 및 (솔루션 없음) 과 같은 것을 선호합니다 . 이것을 구현하기 위해 내가 생각할 수 있는 유일한 방법은 의 조건문이겠지만 , 내가 읽은 내용은 실제로 조건문용으로 설계되지 않았습니다. 이 부분에 대한 아이디어가 있나요?mytexTRUE.pdfmytexFALSE.pdfmytexS.pdfmytexQ.pdfsolutions.yamlyaml

여기까지 읽으셨다면 당신은 진정한 영웅이십니다. 감사해요! 중간을 건너뛰셨다면, 이 낯선 사람의 작업 흐름을 조금 더 효율적으로 만들 수 있도록 도와주세요.

답변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: 문자열, 선택사항, 엔진을 설정합니다. 가능한 옵션은 , pdflatex및 입니다 . 기본: .latexxelatexlualatexpdflatex

  • solutions: natural boolean, option, 문서 범위에서 솔루션 매크로를 정의할지 여부를 설정합니다. 기본: false.

  • name: 문자열, 필수, 문서 이름을 설정합니다. 문서 이름이 이 값으로 변경됩니다. 확장자를 지정할 필요가 없습니다 .pdf.

  • options: list, 선택사항이며 엔진에 제공할 추가 명령줄 매개변수 목록을 설정합니다.

샘플 실행:

% 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

또 다른 흥미로운 제안은 솔루션을 선택적으로 표시하는 환경을 만들어 문서 의미를 개선하는 것입니다. 다음 코드는 David Carlisle이 친절하게 제안한 것입니다(저는 그에게 5달러를 빚지고 있습니다).

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

도움이 되길 바랍니다!:)

관련 정보