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 \question
Befehl schreibt alle Antworten in eine temporäre Datei und ein späterer \printtheanswers
Befehl 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.aux
die usw. definiert \answernumber1
, \answernumber2
um die Vorwärtsverweise zu enthalten.
Dies ist eine zweistufige Kompilierung. Die qa.aux
Datei wird am Anfang geladen, wenn sie existiert. Der \question
Befehl muss \answernumberN
für jede Datei, die nicht existiert, angeben, dass sie zu einem Platzhalter erweitert werden soll.
Im Moment \question
ist es teilweise definiert – es definiert immer \answernumberN
einen 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.aux
fü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 \label
und\ref
Der \question
Befehl enthält jetzt
Q\arabic{chapter}.\arabic{questionnumberinchapter} #1 \emph{(See answer \expandafter\ref{\expandafter qanswer\arabic{questionnumber}}.)}
und der \printtheanswers
Befehl generiert Tex wie folgt:
\item\label{qanswer123} (text of answer to the 123rd question)