
Me gustaría tomar el contenido de un cuadro generado \begin{lrbox} ... \end{lrbox}
y escribirlo en un archivo.
El caso de uso es un entorno de preguntas y respuestas, donde la respuesta debe recopilarse y mostrarse en diferentes ubicaciones del documento. Además me gustaría mostrar la respuesta al lado de la pregunta. Por lo tanto, empaqueto la pregunta en una caja y luego asumo que el contenido de esta caja se puede usar dentro del entorno y para almacenar los datos en un archivo externo. Pero la última parte es el motivo de esta pregunta.
El enfoque que he utilizado hasta ahora es el newfile
paquete y el código siguiente. El problema es que lo que está escrito en test3.comment es lo siguiente
\unhbox \voidb@x \copy \myboxquestion \relax
Código casi funcionando
\documentclass{article}
\usepackage{newfile}
\newoutputstream{comment}
\openoutputfile{\jobname.comment}{comment}
\newsavebox{\myboxquestion}
\newenvironment{question}{%
\begin{lrbox}{\myboxquestion}\begin{minipage}{\linewidth}}{%
\end{minipage}\end{lrbox} \par\usebox{\myboxquestion}
% What to do here?
\addtostream{comment}{\usebox{\myboxquestion}}}
\setlength{\parindent}{0.0cm}
\begin{document}
Testing
\begin{question}
What is 3 + 4
\end{question}
\section{Collected}
\input{\jobname.comment}
\end{document}
Respuesta1
TeX no tiene una serialización de sus estructuras de cajas a las que se pueda acceder, en particular, no se puede escribir en un archivo. Debe guardar el cuadro en la memoria TeX para reutilizarlo o, en lugar de guardar el cuadro, tomar los tokens que componen el texto y escribirlos en un archivo para restablecerlos cuando se lea el archivo. Así es como Los paquetes de tablas de contenido y notas finales funcionan para repetir los títulos de las secciones o las notas al pie al principio o al final de un documento.
Aquí está el MWE que utiliza un registro de cuadro global en lugar de un archivo externo.
\documentclass{article}
\newsavebox{\myboxquestion}
\newbox\savedqns
\setbox\savedqns\vbox{}
\newenvironment{question}{%
\begin{lrbox}{\myboxquestion}\begin{minipage}{\linewidth}}{%
\end{minipage}\end{lrbox} \par\noindent\usebox{\myboxquestion}
\global\setbox\savedqns\vbox{%
\unvbox\savedqns
\bigskip
\filbreak
\noindent\usebox{\myboxquestion}}}
\setlength{\parindent}{0.0cm}
\begin{document}
Testing
\begin{question}
What is 3 + 4
\end{question}
Testing again
\begin{question}
What is 3 + 3
\end{question}
\section{Collected}
\unvbox\savedqns
\end{document}
Respuesta2
Como ya dijo David, el contenido de las cajas no se puede escribir en un archivo. Sin embargo, el contenido del entorno se puede capturar mediante el paquete environ
y almacenarse en una macro a la que se puede llamar y que también se puede escribir en un archivo.
Por cierto, antes de leer el flujo de salida, primero se debe cerrar.
\documentclass{article}
\usepackage{newfile}
\newoutputstream{comment}
\openoutputfile{\jobname.comment}{comment}
\usepackage{environ}
\NewEnviron{question}{%
\BODY
\addtostream{comment}{\detokenize\expandafter{\BODY}}%
% \detokenize prevents macro expansion
}
\setlength{\parindent}{0cm}
\begin{document}
Testing
\begin{question}
What is 3 + 4?
\end{question}
\section{Collected}
\closeoutputstream{comment}
\input{\jobname.comment}
\end{document}
Resultado:
El inconveniente de este método es el contenido textual dentro del contenido del entorno. Esto podría respaldarse capturando el contenido del entorno palabra por palabra. De esta forma se puede escribir en un archivo. El entorno capturado se puede configurar con la ayuda de \scantokens
.