Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to create figures with tikz as seen in the graphic below. The main idea is, that between two lines I sometimes want to copy nodes, which is easy. And sometimes I want to put into the horizontal space of a node on one line new nodes on another line.

So, the three nodes on the 2nd line do not exceed the horizontal space of the first S. Also the three nodes in the middle of the 3rd line to not exceed the horizontal space of the 2nd S.

Also it would be nice if I can insert horizontal rules between the lines, but I didn't do that so far.

I hoped there would be a nicer solution to create these figures. I tried with tikz-chains. I thought about tikz-trees and matrices, but couldn't think of something. I would be grateful for suggestions on how to create similar figures with less fiddling. A solution with tikz would be nice, but I also accept other ways.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{res/.style={rectangle,draw, minimum height=1.8em} }
\begin{document}
\begin{tikzpicture}[align=center, node distance=8mm]
% 1st line
\node [res, minimum width=8cm] (l0s0) {$S$};
% 2nd line
\node [res, below=of l0s0.south west, anchor=west, xshift=4mm] (l1t0) {$($};
\node [res, right=of l1t0, minimum width=5cm] (l1s0) {$S$};
\node [res, right=of l1s0, node distance=2mm] (l1t1) {$)$};
% 3rd line
\node [res, below=of l1t0.south, anchor=center] (l2t0) {$($};
\node [res, below=of l1s0.south west, anchor=west, xshift=4mm] (l2t1)  {$($};
\node [res, right=of l2t1, minimum width=2cm] (l2s0) {$S$};
\node [res, right=of l2s0] (l2t2) {$)$};
\node [res, below=of l1t1.south, anchor=center] (l2t3) {$)$};
\end{tikzpicture} 
\end{document}

enter image description here

share|improve this question
    
So, to clarify, you are looking for a simpler means within tikz, as opposed to an alternative to tikz, is that right? –  Steven B. Segletes Apr 30 at 10:07
    
@StevenB.Segletes I added information for your question, thanks. –  Heinrich Ody Apr 30 at 10:33

2 Answers 2

up vote 6 down vote accepted

If you are not looking for an automatic or recursive solution, I think that positioning library is flexible enough to help you.

What I did in next code is first positioning central nodes and later positioning parenthesis nodes. I don't know if this is what you want.

Regarding to horizontal rules between lines there are several ways of drawing them. Here I've used an auxiliary coordinate node and intersections (|- or -|) to delimitate them.

\documentclass[tikz, border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{res/.style={rectangle,draw, minimum height=1.8em} }
\begin{document}
\begin{tikzpicture}[align=center, node distance=8mm]
% 1st line
\node [res, minimum width=8cm] (l0s0) {$S$};
% 2nd line
\node [res, below=5mm of l0s0, minimum width=5cm] (l1s0) {$S$};
\node [res, left=2mm of l1s0] (l1t0) {$($};
\node [res, right=2mm of l1s0] (l1t1) {$)$};
% 3rd line
\node [res, below=5mm of l1s0, minimum width=2cm] (l2s0) {$S$};
\node [res, left= 2mm of l2s0] (l2t1) {$($};
\node [res, right=2mm of l2s0] (l2t2) {$)$};
\node [res, below=5mm of l1t0] (l2t0)  {$($};
\node [res, below=5mm of l1t1] (l2t3) {$)$};

\path (l0s0) -- (l1s0) coordinate[midway] (aux);
\draw (aux-|l0s0.west) -- (aux-|l0s0.east);

\path (l2s0) -- (l1s0) coordinate[midway] (aux);
\draw (aux-|l0s0.west) -- (aux-|l0s0.east);
\end{tikzpicture} 
\end{document}

enter image description here

share|improve this answer
    
How would you add a horizontal rule above/below the first/last line? If I use an invisible node of the same height as the others the picture gets too much height. If it is of different height the spacing is wrong. –  Heinrich Ody Apr 30 at 13:48
    
You don't need auxiliary nodes or coordinates, something like \draw ([yshift=2mm]l0s0.north west)--([yshift=2mm]l0s0.north east); is enough. You can use shift with any already known coordinate. –  Ignasi Apr 30 at 13:55
    
Works nicely, thanks –  Heinrich Ody Apr 30 at 14:06

enter image description here

    \documentclass{article}
    \usepackage{tikz}
    %\usetikzlibrary{positioning,calc}
    \tikzset{res/.style={rectangle,draw, minimum height=1.8em} }

    \begin{document}

\xdef\Max{6}

    \begin{tikzpicture}
    \node [res,minimum width=8 cm,draw] at (0,-1) {$S$};
    % change 1.15-.15*\n in 1.20-.20*\n or more
    % if one wants 's box' dicrease faster
    \foreach \n [evaluate=\n as \w using (1.15-.15*\n)*8 ]
        in {2,...,\Max} {%

    \node [res,minimum width= \w cm,draw] at (0,-\n) {$S$};

    \foreach \i in {\n,...,\Max} {%
        \node[draw] at (\w/2+.45,-\i) {)} ;
        \node[draw] at (-\w/2-.45,-\i) {(} ;}

    }

    \foreach \i in {1,...,\Max} {%
        \draw (-4,-\i+.5) -- (4,-\i+.5) ;}

    \end{tikzpicture}

    \end{document}
share|improve this answer
    
I consider S as a non-terminal that is replaced by (S). I want that on the next line the whole replacement of S is within the horizontal boundaries set by S on the previous line. As I also consider other grammars I think your solution is too difficult to adapt. Thanks anyway! –  Heinrich Ody Apr 30 at 13:45
    
Let's try again ;-) –  Tarass Apr 30 at 14:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.