Stapeln/Gruppieren-Befehl definiert Tikz-Bilder

Stapeln/Gruppieren-Befehl definiert Tikz-Bilder

Ich arbeite an einem Paket, das ausführlich Befehle verwendet, die pgfkeyszum Erstellen eines Tikz-Bildes erforderlich sind. Unten ist ein einfaches Beispiel:

\documentclass[tikz,border=5pt]{standalone}
\makeatletter
\usetikzlibrary{shapes.geometric, calc}
\newcommand{\example}[2][]{
\tikzset{
 /Example/.cd,
 caption/.store in=\Example@caption,
 caption=X,
 #1,
}
\draw [local bounding box=M] rectangle (1,1);
\node at (0.5,0.5) {\Example@caption};
}
\makeatother
\begin{document}
\begin{tikzpicture}
\example[caption=A];
\end{tikzpicture}
\end{document}

Dies führt wie erwartet zu folgender Ausgabe:

Makroausgabe

(Denken Sie daran, dass dies ein Beispiel zur Vereinfachung ist und nicht die Komplexität der tatsächlichen Befehle widerspiegelt, die viel mehr Tasten enthalten, die komplexere Dinge tun).

Ich möchte zwei neue Listenumgebungen erstellen, denen ich einen der Befehle mehrmals mit unterschiedlichen Schlüsselwerten hinzufügen kann. Die resultierenden Bilder werden dann mit einer von Tikz gezeichneten Klammer „gruppiert“ oder mit einer Linie „gestapelt“, die von der südwestlichen Ecke eines definierten lokalen Begrenzungsrahmens innerhalb des Befehls eine bestimmte Länge nach unten verläuft, sodass sie mit dem nächsten Bild verbunden wird, falls vorhanden (alle Bilder haben den gleichen Abstand und jedes Bild hat die gleiche Gesamtgröße):

der Stapel und die Gruppe

Was ich idealerweise suche, ist eine Listenumgebungsstruktur ähnlich dieser:

\begin{examplestack}
    \item \example[caption=A] 
    \item \example[caption=B] 
    \item \example[caption=C] 
\end{examplestack}

\begin{examplegroup}
    \item \example[caption=A] 
    \item \example[caption=B] 
    \item \example[caption=C] 
\end{examplegroup}

Sowohl der Stapel als auch die Gruppe sollten ihren Ursprung innerhalb der tikzpictureLeinwand versetzt haben, die Gruppe an der Spitze der Klammer, der Stapel am unteren Ende der letzten Linie (dem unteren Ende des „Fahnenmasts“). So können sie richtig platziert werden, wenn sie auf einer anderen Ebene überlagert werden (wie eine Karte).

Antwort1

Proof of Concept. Scheint zumindest für diesen einfachen Fall zu funktionieren. Die Längen müssen hier und da angepasst werden, beispielsweise ist die vertikale Verschiebung jedes Elements einfach auf 1,2 cm fest codiert. Im Allgemeinen ist dies kein sehr flexibler Ansatz, ich bin sicher, dass es andere gibt, die das besser machen könnten.

Bildbeschreibung hier eingeben

\documentclass[tikz,border=5pt]{standalone}
\makeatletter
\usetikzlibrary{shapes.geometric, calc}
\newcommand{\example}[2][]{
\tikzset{
 /Example/.cd,
 caption/.store in=\Example@caption,
 caption=X,
 #1,
}
\draw [local bounding box=M] rectangle (1,1);
\node at (0.5,0.5) {\Example@caption};
}
\makeatother

\newcounter{exitem}

\newenvironment{examplestack}{
\setcounter{exitem}{0}
\renewcommand\item{
% if you only want to draw a line between items
%\ifnum \value{exitem}>0
%  \draw ([xshift=0.5\pgflinewidth]current bounding box.south west) -- ++(0,-0.2cm);
%\fi
%
% if you also want the line below the last item -- not very elegant
\draw (0,{-(1.2cm+\theexitem*1.2cm)}) -- ++(0,-2mm);
%
\stepcounter{exitem}\scoped[yshift=-\theexitem*1.2cm]}
\tikzpicture
}{
%\draw (current bounding box.north west) -- ([yshift=-3pt]current bounding box.south west);
\node [above right] at (current bounding box.north west) {``Stack''};
\endtikzpicture
}

\newenvironment{examplegroup}{
\setcounter{exitem}{0}
\renewcommand\item{\stepcounter{exitem}\scoped[yshift=-\theexitem*1.2cm]}
\tikzpicture
}{
\draw ([shift={(5pt,3pt)}]current bounding box.north west) -| ([shift={(-3pt,-3pt)}]current bounding box.south west) -- ++(8pt,0)
 (current bounding box.west) -- ++(-5pt,0);

\node [above right] at (current bounding box.north west) {``Group''};
\endtikzpicture
}


\begin{document}
\begin{examplegroup}
\item\example[caption=A];
\item\example[caption=B];
\item\example[caption=C];
\end{examplegroup}

\begin{examplestack}
\item\example[caption=A];
\item\example[caption=B];
\item\example[caption=C];
\end{examplestack}
\end{document}

Antwort2

Ich denke, ich sollte eine Antwort darauf hinzufügen, da ich eine bessere und flexiblere Lösung gefunden habe als Torbjørn T.s Antwort auf das Problem. Ihre Lösung erlaubte es nicht, dass Bilder unterschiedlicher Höhe den gleichen Abstand zueinander hatten. Durch die Verwendung eines Längenmakros konnte ich die Länge des vorherigen Bildes speichern und sie verwenden, um das nächste zu versetzen, und mithilfe eines Koordinatensatzes konnte ich sie im „Stapel“ zusammenfügen.

Wichtiger Hinweis: \itemwurde neu definiert, um ein Argument anzunehmen, daher sollten Sie innerhalb der Umgebungen \item{<picture>}anstelle von verwenden \item <picture>.

Diese Lösung verwendet xparseeine sauberere Befehls- und Umgebungssyntax, aber eine einfache LaTeX-Lösung könnte genauso gut verwendet werden.

Präambel (plus der Rest aus dem MWE):

\newcounter{exitem}
\newlength{\itemlength}

Die „Stack“-Syntax:

\NewDocumentEnvironment{examplestack}{}{
\setlength{\itemlength}{0}
\begin{scope}
\setcounter{exitem}{0}
\RenewDocumentCommand\item{m}{
\scoped[yshift=-\itemlength, local bounding box=T]
##1;
\ifnum \value{exitem}>0
\pgfmathtruncatemacro\result{\value{exitem}-1}
\draw ($(M.south west) + (0, -0.25)$) -- (F\result);
\fi
\coordinate (F\arabic{exitem}) at (M.north west);
\pgfpointdiff{\pgfpointanchor{T}{north west}}{\pgfpointanchor{T}{south west}}
\addtolength{\itemlength}{\pgf@y-5pt} % 5pt is the spacing between pictures.
\stepcounter{exitem}}
}{\end{scope}}

Die „Gruppe“-Syntax:

\NewDocumentEnvironment{examplegroup}{}{
\setlength{\itemlength}{0}
\begin{scope}[local bounding box=G]
\RenewDocumentCommand\item{m}{
\scoped[yshift=-\itemlength, local bounding box=T]
##1;
\pgfpointdiff{\pgfpointanchor{T}{north west}}{\pgfpointanchor{T}{south west}}
\addtolength{\itemlength}{\pgf@y-5pt}} % 5pt is the spacing between pictures.
}{
\draw ([shift={(5pt,3pt)}]G.north west) -| ([shift={(-3pt,-3pt)}]G.south west) -- ++(8pt,0)
 (G.west) -- ++(-5pt,0);
\end{scope}}

Beispiele:

\begin{examplegroup}
\item{\example[caption=A]}
\item{\example[caption=B]}
\item{\example[caption=C]}
\end{examplegroup}

\begin{examplestack}
\item{\example[caption=A]}
\item{\example[caption=B]}
\item{\example[caption=C]}
\end{examplestack}

verwandte Informationen