
Gostaria de pegar o conteúdo de uma caixa gerada \begin{lrbox} ... \end{lrbox}
e gravá-lo em um arquivo.
O caso de uso é um ambiente de perguntas e respostas, onde a resposta deve ser coletada e mostrada em diferentes locais do documento. Além disso, gostaria de mostrar a resposta ao lado da pergunta. Portanto coloco a pergunta em uma caixa, e então presumo que o conteúdo desta caixa pode tanto ser usado dentro do ambiente quanto para armazenar os dados em um arquivo externo. Mas a última parte é a razão desta pergunta.
A abordagem que usei até agora é o newfile
pacote e o código abaixo. O problema é que o que está escrito em test3.comment é o seguinte
\unhbox \voidb@x \copy \myboxquestion \relax
Código quase 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}
Responder1
O TeX não possui uma serialização de suas estruturas de caixa que podem ser acessadas, em particular não pode ser gravado em um arquivo. Você precisa salvar a caixa na memória TeX para reutilização ou, em vez de salvar a caixa, pegar os tokens que compõem o texto e gravá-los em um arquivo para ser redefinido quando o arquivo for lido. os pacotes de índices e notas finais funcionam para repetir os títulos das seções ou notas de rodapé no início ou no final de um documento
Aqui está o MWE usando um registrador de caixa global em vez de um arquivo 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}
Responder2
Como David já disse, o conteúdo das caixas não pode ser gravado em um arquivo. Porém o conteúdo do ambiente pode ser capturado usando o pacote environ
e armazenado em uma macro que pode ser chamada e também gravada em um arquivo.
Aliás, antes de ler o fluxo de saída, ele deve ser fechado primeiro.
\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:
A desvantagem desse método é o conteúdo literal do conteúdo do ambiente. Isto poderia ser apoiado pela captura do conteúdo do ambiente de maneira literal. Nesta forma, ele pode ser gravado em um arquivo. O ambiente capturado pode ser definido com a ajuda de \scantokens
.