3

I would like to define a macro, which would take a list of node definitions, like this

\mymacro[boxes={{\node[rectangle] {foo};},
                {\node[rectangle] {bar};},
                {\node[circle] {baz};},
                alignment=stacked]{ ... }

and place the nodes vertically, i.e. stacked on top of each other.

[ ]
[ ]
( )

Or like this:

\mymacro[boxes={{\node[rectangle] {foo};},
                {\node[rectangle] {bar};},
                {\node[circle] {baz};},
                alignment=listed]{ ... }

[ ] , [ ] , ( )

to place them besides each other, interspersed with another node (containing a comma in this case).

I know how to handle a list option with pgfkeys, but have no idea where to start on the stacking or listing bit.

1 Answer 1

3

I would use styles instead of a macro for this: The vertical and horizontal placement can be accomplished by using chains, the comma between the horizontal nodes can be placed using a decoration.

I've used two styles here: nodelist defines all nodes to be drawn and to be part of a chain, and calls a second style called nodelist direction, which actually starts the chain, defines the direction the chain will grow in, and in the case of nodelist direction=horizontal sets up the decoration that will replace the joins of the chain with nodes containing commas.

You can then just enclose the nodes in a scope with the nodelist style, and everything will be set up:

\begin{scope}[nodelist]
\node {A};
\node [circle] {B};
\node [star] {C};
\end{scope}

\begin{scope}[xshift=6cm,nodelist=vertical]
\node {A};
\node [circle] {B};
\node [star] {C};
\end{scope}

will lead to

chains!

And here's the complete code:

\documentclass{article}
\usepackage{tikz} 
\usetikzlibrary{calc,shapes,chains,decorations.markings}  
\begin{document}

\tikzset{
    nodelist direction/.is choice,
    nodelist direction/.default=horizontal,
    nodelist direction/horizontal/.style={
        start chain=going right,
        every node/.style=join,
        decoration={
            markings, % switch on markings
            mark=at position 0.5 with {
                \tikzset{every node/.style={}} % Reset the style locally
                \node {,}; % Create a node that holds a comma
            }
        },
        every join/.style={
            decorate    % Decorate every join with the decoration defined above
        }
    },
    nodelist direction/vertical/.style={
        start chain=going below, % Much simpler, just go down, no decorations, no joins
    },
    nodelist/.style={ % Options common to horizontal and vertical
        nodelist direction=#1,
        every node/.append style={
            on chain,
            draw
        },
    }
}

\begin{tikzpicture}

\begin{scope}[nodelist]
\node {A};
\node [circle] {B};
\node [star] {C};
\end{scope}

\begin{scope}[xshift=6cm,nodelist=vertical]
\node {A};
\node [circle] {B};
\node [star] {C};
\end{scope}
\end{tikzpicture} 


\end{document} 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .