Estou trabalhando em um pacote que usa extensivamente comandos necessários pgfkeys
para produzir uma imagem tikz. Abaixo está um exemplo simples:
\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}
Isso fornece a seguinte saída, conforme esperado:
(Tenha em mente que este é um exemplo feito para simplificação e não reflete a complexidade dos comandos reais, que contêm muito mais chaves que fazem coisas mais complexas).
O que desejo criar são dois novos ambientes de lista aos quais posso adicionar um dos comandos várias vezes com valores de chave diferentes. As imagens resultantes são então "agrupadas" com uma chave desenhada tikz ou "empilhadas" com uma linha que se estende para baixo a partir do canto sudoeste de uma caixa delimitadora local definida dentro do comando em um determinado comprimento para que se conecte com a próxima imagem, se presente (todas terão espaçamento igual e cada imagem terá o mesmo tamanho geral):
O que estou procurando idealmente é uma estrutura de ambiente de lista semelhante a esta:
\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}
Tanto a pilha quanto o grupo devem ter sua origem deslocada dentro do tikzpicture
canvas, o grupo na ponta da chave, a pilha na parte inferior da última linha (a parte inferior do "mastro"). Isso ocorre para que eles possam ser colocados corretamente se forem sobrepostos em outra camada (como um mapa).
Responder1
Prova de conceito. Parece funcionar pelo menos neste caso simples. Os comprimentos precisarão ser ajustados aqui e ali, por exemplo, o deslocamento vertical de cada item é simplesmente codificado para 1,2 cm. Em geral, esta não é uma abordagem muito flexível, tenho certeza de que há outros que poderiam fazer melhor.
\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}
Responder2
Sinto que deveria acrescentar uma resposta a isto, pois consegui encontrar uma solução melhor e mais flexível do que a resposta de Torbjørn T para o problema. A solução deles não permitia que fotos de alturas variadas tivessem o mesmo espaçamento entre elas. Através do uso de uma macro de comprimento consegui armazenar o comprimento da imagem anterior e usá-la para compensar a próxima, e usando um conjunto de coordenadas consegui juntá-las na "Pilha".
Nota importante: \item
foi redefinido para receber um argumento, portanto, dentro dos ambientes, você deve usar \item{<picture>}
em vez de \item <picture>
.
Esta solução usa xparse
comandos e sintaxe de ambiente mais limpos, mas uma solução LaTeX simples pode ser usada com a mesma facilidade.
Preâmbulo (mais o restante do MWE):
\newcounter{exitem}
\newlength{\itemlength}
A sintaxe "Pilha":
\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}}
A sintaxe do "Grupo":
\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}}
Exemplos:
\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}