Каков наилучший способ условного определения (если еще не определены) перечисляемых команд \cmd1 \cmd2 ... и т. д.?

Каков наилучший способ условного определения (если еще не определены) перечисляемых команд \cmd1 \cmd2 ... и т. д.?

Я пишу документ, который содержит вопросы и ответы. Например

\question{What is 2+3?}{2+3=5}
\question{What is cheese?}{Food made from milk.}

Ответы сохраняются для последующего сбора в разделе, с той разницей, что ответы перемешиваются, чтобы предотвратить подглядывание. Это означает, что вопросы должны содержать прямые ссылки на номера ответов. Например:

В2.1 Сколько будет 2+3?(См. ответ 104)

В2.2 Что такое сыр?(См. ответ 57)

у меня есть этопочтиработающий.

Команда \questionзаписывает все ответы во временный файл, а более поздняя \printtheanswersкоманда отправляет его во внешнюю программу, которая

а. перемешивает ответы,

б. генерирует Latex для раздела ответов и

c. генерирует вспомогательный файл , qa.auxкоторый определяет и т. д. для хранения прямых ссылок.\answernumber1\answernumber2

Это двухпроходная компиляция. qa.auxФайл загружается в начале, если он существует. \questionКоманда должна определить \answernumberNдля каждого из них, который не существует, чтобы расшириться до заполнителя.

На данный момент \questionопределен частично — всегда определяется \answernumberNкак заполнитель:

\newcommand{\question}[2]{
    \stepcounter{questionnumber}
    \stepcounter{questionnumberinchapter}

    % Define the placeholder for \answernumberN
    \expandafter\edef\expandafter\answernumber\roman{questionnumber}{PLACEHOLDER:\arabic{questionnumber}}

    % FOR DEBUGGING
    DEFINING \texttt{\textbackslash answernumber\roman{questionnumber} as \{PLACEHOLDER:\arabic{questionnumber}\}}

    % Write "x.y #2" to \qainpfilename
    \immediate\write\qafile{\arabic{chapter}.\arabic{questionnumberinchapter} \unexpanded{#2}}

    % Print the qustion to the document.
    Q\arabic{chapter}.\arabic{questionnumberinchapter} #1 \emph{(See answer \expandafter\answernumber\roman{questionnumber}.)}
}

Вот линия интереса:

\expandafter\edef\expandafter\answernumber\roman{questionnumber}{PLACEHOLDER:\arabic{questionnumber}}

Проблема вэто ВСЕГДА определяет \answernumberN, независимо от того, определено ли это во вспомогательном файле.

Вот MWE, хотя на самом деле вы не сможете скомпилировать его без внешней программы.

\documentclass[a4paper,10pt,openany]{scrbook}

\usepackage{verbatim}

% Define \bashline command
% Taken from https://gist.github.com/w495/7328b76e76aee49657e0bd7a3b46c870
\makeatletter
    \newcommand{\bashline@file@name}[1]{%
        /tmp/${USER}-${HOSTNAME}-\jobname-#1.tex%
    }
    \newread\bashline@file
    \newcommand{\bashline@command@one}[2][tmp]{%
        \immediate\write18{#2 > \bashline@file@name{#1}}
        \openin\bashline@file=\bashline@file@name{#1}
        % The group localizes the change to \endlinechar
        \bgroup
            \endlinechar=-1
            \read\bashline@file to \localline
            % Since everything in the group is local, 
            % we have to explicitly make the assignment global
            \global\let\bashline@result\localline
        \egroup
        \closein\bashline@file
        % Clean up after ourselves
        \immediate\write18{rm \bashline@file@name{#1}}
        \bashline@result
    }
    \newcommand{\bashline@command@many}[2][tmp]{%
        \immediate\write18{#2 > \bashline@file@name{#1}}
        \openin\bashline@file=\bashline@file@name{#1}
        % The group localizes the change to \endlinechar
        \newcount\linecnt
        \bgroup
            \endlinechar=-1
            \loop\unless\ifeof\bashline@file 
                \read\bashline@file to \localline%
                \localline
                \newline
            \repeat
        \egroup
        \closein\bashline@file
        % Clean up after ourselves
        \immediate\write18{rm \bashline@file@name{#1}}
    }
    \newcommand{\bashline}[2][tmp]{%
        \bashline@command@one[#1]{#2}%
    }
    \newcommand{\bashlines}[2][tmp]{%
        \bashline@command@many[#1]{#2}%
    }
\makeatother

% Question-answer stuff.

\def\qainpfilename{qa.inp}
\def\qaauxfilename{qa.aux}
\def\qatexfilename{qa.tex}

\newwrite\qafile
\immediate\openout\qafile=\qainpfilename

\newcounter{questionnumber}
\newcounter{questionnumberinchapter}[chapter]

\newcommand{\question}[2]{
    \stepcounter{questionnumber}
    \stepcounter{questionnumberinchapter}

    % Define the placeholder for \answernumberN
    \expandafter\edef\expandafter\answernumber\roman{questionnumber}{PLACEHOLDER:\arabic{questionnumber}}

    DEFINING \texttt{\textbackslash answernumber\roman{questionnumber} as \{PLACEHOLDER:\arabic{questionnumber}\}}

    % Write "x.y #2" to \qainpfilename
    \immediate\write\qafile{\arabic{chapter}.\arabic{questionnumberinchapter} \unexpanded{#2}}

    % Print the qustion to the document.
    Q\arabic{chapter}.\arabic{questionnumberinchapter} #1 \emph{(See answer \expandafter\answernumber\roman{questionnumber}.)}
}

\newcommand{\printtheanswers}{
    \immediate\closeout\qafile
    \bashline{bash bin/generate-answers.sh '\qainpfilename' '\qatexfilename' '\qaauxfilename'}

    \input{\qatexfilename}
}

% Demonstrate that this will not be expanded until after qa.tex has been
% generated loaded into the document.
\def\examplething{this is expanded later}



\begin{document}

TEST

\IfFileExists{\qaauxfilename}{\input{\qaauxfilename}}{AUX DOES NOT EXIST}



\chapter{Maths}

\question{What is $1+2$?}{$1+2=3$ \examplething}

\question{What is $2\times 3$?}{$2\times 3=6$}



\chapter{Science}

\question{Name the six quarks.}{Up down, charm, strange, truth, and beauty.}

\question{How many planets orbit the Sun?}{Eight. Deal with it.}



\chapter{Answers}

\printtheanswers

\end{document}

Файл qa.aux, который создается для этого документа, —

\def\answernumberi{3}% (Q1.1): $1+2=3$ \examplething 
\def\answernumberii{1}% (Q1.2): $2\times 3=6$
\def\answernumberiii{4}% (Q2.1): Up down, charm, strange, truth, and beauty.
\def\answernumberiv{2}% (Q2.2): Eight. Deal with it.

Я знаю, что можно использовать \providecommandи различные конструкции if-then, но мне не удалось заставить их работать, когда имя команды составлено с помощью \expandafter\answernumber\roman{questionnumber}. Как мне условно определить команду, имя которой составлено из такого числа?

решение1

Благодаря cfr я теперь использую \labelи\ref

Команда \questionтеперь включает в себя

Q\arabic{chapter}.\arabic{questionnumberinchapter} #1 \emph{(See answer \expandafter\ref{\expandafter qanswer\arabic{questionnumber}}.)}

и \printtheanswersкоманда генерирует tex следующим образом:

\item\label{qanswer123} (text of answer to the 123rd question)

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