Estoy escribiendo un documento que contiene preguntas y respuestas. Por ejemplo
\question{What is 2+3?}{2+3=5}
\question{What is cheese?}{Food made from milk.}
Las respuestas se guardan para recopilarlas en una sección posterior, con el detalle de que las respuestas se mezclan para evitar que se miren. Esto significa que las preguntas deben contener referencias directas a los números de respuesta. Por ejemplo:
Q2.1 ¿Qué es 2+3?(Ver respuesta 104)
Q2.2 ¿Qué es el queso?(Ver respuesta 57)
tengo estocasilaboral.
El \question
comando escribe todas las respuestas en un archivo temporal y un \printtheanswers
comando posterior lo envía a un programa externo que
a. baraja las respuestas,
b. genera látex para la sección de respuestas, y
C. genera un archivo auxiliar qa.aux
que define \answernumber1
, \answernumber2
etc. para contener las referencias directas.
Esta es una compilación de dos pasos. El qa.aux
archivo se carga al principio, si existe. El \question
comando debe definir \answernumberN
para cada uno de ellos lo que no existe, para expandirse a un marcador de posición.
Por el momento, \question
está parcialmente definido: siempre se define \answernumberN
como un marcador de posición:
\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}.)}
}
Aquí está la línea de interés:
\expandafter\edef\expandafter\answernumber\roman{questionnumber}{PLACEHOLDER:\arabic{questionnumber}}
El problema esesto SIEMPRE define \answernumberN
, independientemente de si está definido en el archivo auxiliar.
Aquí hay un MWE, aunque en realidad no puedes compilarlo sin el programa externo.
\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}
El qa.aux
archivo que se genera para este documento es
\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.
Sé que puedes usar \providecommand
varias construcciones si-entonces, pero no he podido hacer que funcionen cuando el nombre del comando se construye con \expandafter\answernumber\roman{questionnumber}
. ¿Cómo defino condicionalmente un comando cuyo nombre se construye a partir de un número como este?
Respuesta1
Gracias a cfr, ahora uso \label
y\ref
El \question
comando ahora incluye
Q\arabic{chapter}.\arabic{questionnumberinchapter} #1 \emph{(See answer \expandafter\ref{\expandafter qanswer\arabic{questionnumber}}.)}
y el \printtheanswers
comando genera un texto como este:
\item\label{qanswer123} (text of answer to the 123rd question)