3

In the following code, I would like to put the two lists displayed in the same environment with one vertical specified spacing.

How can I do that ?

Code

\documentclass{article}
    \usepackage{tikz}
    \usepackage{xstring}

    \tikzset{
        raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
        sort entry black/.style={raw sort entry, black, fill=white},
        sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
        s1/.style={raw sort entry, red, fill=yellow!30},
        s2/.style={raw sort entry, blue, fill=green!20},
        s3/.style={raw sort entry, violet, fill=orange!25}
    }

    \newcommand*{\List}[2][sort entry black]{%
      \par\noindent%
      \edef\listtoprocess{#2}%
      \def\ListToProcess{}%
      \begin{tikzpicture}[inner sep=2pt, outer sep=0]
        \foreach \content in \listtoprocess{
          \IfSubStr{\content}{/}{% true
            \xdef\ListToProcess{\ListToProcess,\content}
          }{%                      false
            \xdef\ListToProcess{\ListToProcess,#1/\content}
          }
        }
        \StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
        \foreach [count=\i] \Style/\Value in \ListToProcess {
          \ifnum\i=1\relax
            \node [raw sort entry, \Style] (sortnode\i) {\Value};
          \else
            \node [raw sort entry, right of=sortnode\number\numexpr\i-1\relax, \Style] (sortnode\i) {\Value};
          \fi
        }
      \end{tikzpicture}%
    }

\begin{document}

\List[sort entry blackgray]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}

\bigskip

\List[sort entry blackgray]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}

\end{document}
4
  • Of course you can't have \begin{tikzpicture} and \end{tikzpicture} in the definition of \List, to begin with.
    – egreg
    Commented Jan 19, 2013 at 10:40
  • Ok. Indeed the code is not mine and I'm not a TikZ expert.
    – projetmbc
    Commented Jan 19, 2013 at 10:42
  • And the question is?
    – egreg
    Commented Jan 19, 2013 at 10:45
  • Is it as simple to remove the TikZ environment ine the code of the macro ? The 2nd point to solve is the vertical spacing.
    – projetmbc
    Commented Jan 19, 2013 at 10:49

1 Answer 1

2

I’m just re-using code from TikZ arrows for displaying sorting algorithms and added the keys

  • previous row and
  • previous col

I replaced the old syntax right of=… with the syntax right=… of … provided by the positioning library. (→ Difference between "right of=" and "right=of" in PGF/TikZ)
The values .5em (horizontal) and 1em (vertical) are hard-coded in the \List macro.

The key previous row is automatically set at the end of processing all nodes in one row to the current row name so that in a following \List call previous row is already set to the previous row name (see the first example).

A manual placement is possible with the aforementioned keys. See the second example (previous row=a is actually not needed but for completeness added anyway).

Code

\documentclass[tikz]{standalone}
    \usepackage{tikz}
    \usepackage{xstring}
    \usetikzlibrary{calc,positioning}
    \tikzset{
        raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
        sort entry black/.style={raw sort entry, black, fill=white},
        sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
        s1/.style={raw sort entry, red, fill=yellow!30},
        s2/.style={raw sort entry, blue, fill=green!20},
        s3/.style={raw sort entry, violet, fill=orange!25},
        /qrr/default/.style=sort entry black,
        name row/.initial={},
        previous row/.initial={},
        previous col/.initial={1},
        default/.style={/qrr/default/.style={#1}},
        |-|/.style={
          to path={
            let \p1=(\tikztostart),
                \p2=(\tikztotarget) in
                -- (\x1,.5*\y1+.5*\y2) -- (\x2,.5*\y1+.5*\y2) \tikztonodes
                                                                       -- (\tikztotarget)
          }
        }
    }
    \newcommand*{\List}[2][default=sort entry black]{%
      \tikzset{#1}%
      \edef\listtoprocess{#2}%
      \pgfkeysgetvalue{/tikz/name row}{\rowname}%
      \pgfkeysgetvalue{/tikz/previous row}{\previousRow}%
      \pgfkeysgetvalue{/tikz/previous col}{\previousCol}%
      \def\ListToProcess{}%
      \foreach \content in \listtoprocess{
        \IfSubStr{\content}{/}{% true
          \xdef\ListToProcess{\ListToProcess,\content}
        }{%                      false
          \xdef\ListToProcess{\ListToProcess,{/qrr/default}/\content}
        }
      }
      \StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
      \foreach [count=\i] \Style/\Value in \ListToProcess {
        \ifnum\i=1\relax
          \expandafter\ifx\expandafter\relax\previousRow\relax
            \node [raw sort entry, \Style] (\rowname-\i) {\Value};
          \else
            \node [raw sort entry, \Style, below=1em of \previousRow-\previousCol] (\rowname-\i) {\Value};
          \fi
        \else
          \node [raw sort entry, right=.5em of \rowname-\number\numexpr\i-1\relax, \Style] (\rowname-\i) {\Value};
        \fi
      }
      \tikzset{previous row/.expand once=\rowname}
    }

\begin{document}
\begin{tikzpicture}
\List[default=sort entry blackgray, name row=a]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\List[default=sort entry blackgray, name row=b]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\draw[thick, shorten >=\pgflinewidth,->] (a-7) to[|-|] (b-9);
\end{tikzpicture}

\begin{tikzpicture}
\List[default=sort entry blackgray, name row=a]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\List[default=sort entry blackgray, name row=b, previous row=a, previous col=3]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\draw[thick, shorten >=\pgflinewidth,->] (a-7) to[|-|] (b-9);
\end{tikzpicture}
\end{document}

Output

enter image description here

enter image description here

1
  • Tanks for this quick answer.
    – projetmbc
    Commented Jan 19, 2013 at 22:19

You must log in to answer this question.

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