Was ist die beste Möglichkeit, aufgezählte Befehle \cmd1 \cmd2 ... usw. bedingt zu definieren (sofern sie nicht bereits definiert sind)?

Was ist die beste Möglichkeit, aufgezählte Befehle \cmd1 \cmd2 ... usw. bedingt zu definieren (sofern sie nicht bereits definiert sind)?

Ich schreibe ein Dokument, das Fragen und Antworten enthält. Zum Beispiel

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

Die Antworten werden gespeichert, um sie in einem späteren Abschnitt zu sammeln. Dabei werden die Antworten neu gemischt, um ein Ausspionieren zu verhindern. Das bedeutet, dass die Fragen Vorwärtsverweise auf die Antwortnummern enthalten müssen. Beispiel:

F2.1 Was ist 2+3?(Siehe Antwort 104)

F2.2 Was ist Käse?(Siehe Antwort 57)

ich habe dasfastArbeiten.

Der \questionBefehl schreibt alle Antworten in eine temporäre Datei und ein späterer \printtheanswersBefehl sendet diese an ein externes Programm, das

a. mischt die Antworten,

b. generiert Latex für den Abschnitt „Antworten“ und

c. generiert eine Hilfsdatei , qa.auxdie usw. definiert \answernumber1, \answernumber2um die Vorwärtsverweise zu enthalten.

Dies ist eine zweistufige Kompilierung. Die qa.auxDatei wird am Anfang geladen, wenn sie existiert. Der \questionBefehl muss \answernumberNfür jede Datei, die nicht existiert, angeben, dass sie zu einem Platzhalter erweitert werden soll.

Im Moment \questionist es teilweise definiert – es definiert immer \answernumberNeinen Platzhalter:

\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}.)}
}

Hier ist die interessante Zeile:

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

Das Problem istdies definiert IMMER \answernumberN, unabhängig davon, ob es in der Hilfsdatei definiert ist.

Hier ist ein MWE, obwohl Sie es ohne das externe Programm nicht kompilieren können.

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

Die qa.auxfür dieses Dokument generierte Datei ist

\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.

Ich weiß, dass Sie verschiedene Wenn-Dann-Konstruktionen und verwenden können \providecommand, aber ich konnte sie nicht zum Laufen bringen, wenn der Befehlsname mit erstellt wird \expandafter\answernumber\roman{questionnumber}. Wie definiere ich bedingt einen Befehl, dessen Name aus einer Zahl wie dieser erstellt wird?

Antwort1

Dank cfr verwende ich nun \labelund\ref

Der \questionBefehl enthält jetzt

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

und der \printtheanswersBefehl generiert Tex wie folgt:

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

verwandte Informationen