Ich möchte Daten iterativ in einer Savebox (oder einem anderen Speicherelement) speichern. Am Ende möchte ich jeden Datenpunkt in eine Framebox und dann in einen Framebox-Container mit einer bestimmten Breite setzen. Hier ist meine Implementierung:
\documentclass{article}
\newsavebox{\foo}
\newcommand{\savedata}[1]{\savebox{\foo}{\usebox{\foo} \fbox{#1}}}
\newcommand{\printdata}{\framebox{\parbox{4cm}{\usebox{\foo}}}}
\begin{document}
The desired usage:
\savedata{This is a box}
\savedata{This is another box}
\savedata{This is third box}
\printdata
\\
The desired output:
\framebox{\parbox{4cm}{
\fbox{This is a box}
\fbox{This is another box}
\fbox{This is third box}}}
\end{document}
Ausgabe:
Wie man sieht, umschließt der Container die innere Framebox nicht, wenn die programmgesteuerte Implementierung verwendet wird. Was ist falsch?
Antwort1
Sie möchten, dass raggedright kurze Zeilen zulässt, und müssen die gespeicherten Daten entpacken, um Zeilenumbrüche zu ermöglichen:
\documentclass{article}
\newsavebox{\foo}
\newcommand{\savedata}[1]{\savebox{\foo}{\ifvoid\foo\else\unhbox\foo{} \fi\fbox{#1}}}
\newcommand{\printdata}{\framebox{\parbox{4cm}{\raggedright\unhbox\foo}}}
\begin{document}
The desired usage:
\savedata{This is a box}
\savedata{This is another box}
\printdata
The desired output:
\framebox{\parbox{4cm}{\raggedright\fbox{This is a box} \fbox{This is another box}}}
\end{document}
Antwort2
Ich bin nicht sicher, ob Sie Boxen verwenden möchten:
\documentclass{article}
\usepackage{etoolbox}
\newcommand{\cleardata}{\renewcommand*{\saveddata}{}}
\newcommand*\saveddata{} % initialize
\newcommand{\savedata}[1]{%
\unskip
\ifx\saveddata\empty
\else
\appto{\saveddata}{\\}
\fi
\appto{\saveddata}{\fbox{#1}}\ignorespaces
}
\newcommand{\printdata}[1][4cm]{\fbox{\parbox{#1}{\raggedright\saveddata}}}
\begin{document}
The desired usage:
\savedata{This is a box}
\savedata{This is another box}
\savedata{This is third box}
\printdata
The desired output:
\framebox{\parbox{4cm}{
\fbox{This is a box} \\
\fbox{This is another box} \\
\fbox{This is third box}}}
With optional argument: \printdata[6cm]
\end{document}
Der Befehl \cleardata
setzt den Mechanismus zum Hinzufügen neuer Boxen zurück.
Hier habe ich etoolbox
der Einfachheit halber Folgendes verwendet. Sie können es vermeiden, indem \appto
Sie es selbst definieren:
\makeatletter
\providecommand\appto[2]{%
\ifx#1\@undefined
\def#1{#2}%
\else
\expandafter\def\expandafter#1\expandafter{#1#2}%
\fi
}
\makeatother
Antwort3
Sind Sie sicher, dass die fertige Box 4 cm breit sein muss? Ist es nicht besser, diese Breite als die Breite der breitesten Box im Inneren festzulegen? Wenn ja, können Sie Folgendes verwenden:
\newbox\foo
\def\savedata#1{\setbox\foo=\vbox{\unvbox\foo \hbox{\fbox{#1}}\kern1pt}\ignorespaces}
\def\printdata{\framebox{$\vcenter{\box\foo\kern-1pt}$}}