summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/doc/pgfmanual-en-tutorial-chains.tex
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/base/doc/pgfmanual-en-tutorial-chains.tex')
-rw-r--r--graphics/pgf/base/doc/pgfmanual-en-tutorial-chains.tex1067
1 files changed, 1067 insertions, 0 deletions
diff --git a/graphics/pgf/base/doc/pgfmanual-en-tutorial-chains.tex b/graphics/pgf/base/doc/pgfmanual-en-tutorial-chains.tex
new file mode 100644
index 0000000000..04b6f58433
--- /dev/null
+++ b/graphics/pgf/base/doc/pgfmanual-en-tutorial-chains.tex
@@ -0,0 +1,1067 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Free Documentation License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+\section{Tutorial: Diagrams as Simple Graphs}
+
+In this tutorial we have a look at how graphs and matrices can be used to
+typeset a diagram.
+
+Ilka, who just got tenure for her professorship on Old and Lovable Programming
+Languages, has recently dug up a technical report entitled \emph{The
+Programming Language Pascal} in the dusty cellar of the library of her
+university. Having been created in the good old times using pens and rules, it
+looks like this%
+\footnote{The shown diagram was not scanned, but rather typeset using
+\tikzname. The jittering lines were created using the |random steps|
+decoration.}:
+
+{
+ \tikzset{
+ nonterminal/.style={
+ % The shape:
+ rectangle,
+ % The size:
+ minimum size=6mm,
+ % The border:
+ very thick,
+ draw=red!50!black!50, % 50% red and 50% black,
+ % and that mixed with 50% white
+ % The filling:
+ top color=white, % a shading that is white at the top...
+ bottom color=red!50!black!20, % and something else at the bottom
+ % Font
+ font=\itshape
+ },
+ terminal/.style={
+ % The shape:
+ rounded rectangle,
+ minimum size=6mm,
+ % The rest
+ very thick,draw=black!50,
+ top color=white,bottom color=black!20,
+ font=\ttfamily},
+ skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}
+ }
+ \tikzset{terminal/.append style={text height=1.5ex,text depth=.25ex}}
+ \tikzset{nonterminal/.append style={text height=1.5ex,text depth=.25ex}}
+ \pgfmathsetseed{1}
+\medskip
+\noindent\begin{tikzpicture}[
+ >=latex,thick,
+ /pgf/every decoration/.style={/tikz/sharp corners},
+ fuzzy/.style={decorate,decoration={random steps,segment length=0.5mm,amplitude=0.15pt}},
+ minimum size=6mm,line join=round,line cap=round,
+ terminal/.style={rectangle,draw,fill=white,fuzzy,rounded corners=3mm},
+ nonterminal/.style={rectangle,draw,fill=white,fuzzy},
+ node distance=4mm]
+
+ \ttfamily
+ \begin{scope}[start chain,
+ every node/.style={on chain},
+ terminal/.append style={join=by {->,shorten >=-1pt,fuzzy,decoration={post length=4pt}}},
+ nonterminal/.append style={join=by {->,shorten >=-1pt,fuzzy,decoration={post length=4pt}}},
+ support/.style={coordinate,join=by fuzzy}]
+ \node [support] (start) {};
+ \node [nonterminal] {unsigned integer};
+ \node [support] (after ui) {};
+ \node [terminal] {.};
+ \node [support] (after dot) {};
+ \node [terminal] {digit};
+ \node [support] (after digit) {};
+ \node [support] (skip) {};
+ \node [support] (before E) {};
+ \node [terminal] {E};
+ \node [support] (after E) {};
+ \node [support,xshift=5mm] (between) {};
+ \node [support,xshift=5mm] (before last) {};
+ \node [nonterminal] {unsigned integer};
+ \node [support] (after last) {};
+ \node [coordinate,join=by ->] (end) {};
+ \end{scope}
+ \node (plus) [terminal,above=of between] {+};
+ \node (minus) [terminal,below=of between] {-};
+
+ \begin{scope}[->,decoration={post length=4pt},rounded corners=2mm,every path/.style=fuzzy]
+ \draw (after ui) -- +(0,.7) -| (skip);
+ \draw (after digit) -- +(0,-.7) -| (after dot);
+ \draw (before E) -- +(0,-1.2) -| (after last);
+ \draw (after E) |- (plus);
+ \draw (plus) -| (before last);
+ \draw (after E) |- (minus);
+ \draw (minus) -| (before last);
+ \end{scope}
+\end{tikzpicture}
+\medskip
+
+For her next lecture, Ilka decides to redo this diagram, but this time perhaps
+a bit cleaner and perhaps also bit ``cooler''.
+
+\medskip
+\noindent\begin{tikzpicture}[point/.style={coordinate},>={Stealth[round]},thick,draw=black!50,
+ tip/.style={->,shorten >=1pt},every join/.style={rounded corners},
+ hv path/.style={to path={-| (\tikztotarget)}},
+ vh path/.style={to path={|- (\tikztotarget)}}]
+ \matrix[column sep=4mm] {
+ % First row:
+ & & & & & & & & & & & \node (plus) [terminal] {+};\\
+ % Second row:
+ \node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; &
+ \node (p2) [point] {}; & \node (dot) [terminal] {.}; &
+ \node (p3) [point] {}; & \node (digit) [terminal] {digit}; &
+ \node (p4) [point] {}; & \node (p5) [point] {}; &
+ \node (p6) [point] {}; & \node (e) [terminal] {E}; &
+ \node (p7) [point] {}; & &
+ \node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; &
+ \node (p9) [point] {}; & \node (p10) [point] {};\\
+ % Third row:
+ & & & & & & & & & & & \node (minus)[terminal] {-};\\
+ };
+
+ { [start chain]
+ \chainin (p1);
+ \chainin (ui1) [join=by tip];
+ \chainin (p2) [join];
+ \chainin (dot) [join=by tip];
+ \chainin (p3) [join];
+ \chainin (digit) [join=by tip];
+ \chainin (p4) [join];
+ { [start branch=digit loop]
+ \chainin (p3) [join=by {skip loop=-6mm,tip}];
+ }
+ \chainin (p5) [join,join=with p2 by {skip loop=6mm,tip}];
+ \chainin (p6) [join];
+ \chainin (e) [join=by tip];
+ \chainin (p7) [join];
+ { [start branch=plus]
+ \chainin (plus) [join=by {vh path,tip}];
+ \chainin (p8) [join=by {hv path,tip}];
+ }
+ { [start branch=minus]
+ \chainin (minus) [join=by {vh path,tip}];
+ \chainin (p8) [join=by {hv path,tip}];
+ }
+ \chainin (p8) [join];
+ \chainin (ui2) [join=by tip];
+ \chainin (p9) [join,join=with p6 by {skip loop=-11mm,tip}];
+ \chainin (p10) [join=by tip];
+ }
+\end{tikzpicture}
+}\medskip
+
+Having read the previous tutorials, Ilka knows already how to set up the
+environment for her diagram, namely using a |tikzpicture| environment. She
+wonders which libraries she will need. She decides that she will postpone the
+decision and add the necessary libraries as needed as she constructs the
+picture.
+
+
+\subsection{Styling the Nodes}
+
+The bulk of this tutorial will be about arranging the nodes and connecting them
+using chains, but let us start with setting up styles for the nodes.
+
+There are two kinds of nodes in the diagram, namely what theoreticians like to
+call \emph{terminals} and \emph{nonterminals}. For the terminals, Ilka decides
+to use a black color, which visually shows that ``nothing needs to be done
+about them''. The nonterminals, which still need to be ``processed'' further,
+get a bit of red mixed in.
+
+Ilka starts with the simpler nonterminals, as there are no rounded corners
+involved. Naturally, she sets up a style:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning}}]
+\begin{tikzpicture}[
+ nonterminal/.style={
+ % The shape:
+ rectangle,
+ % The size:
+ minimum size=6mm,
+ % The border:
+ very thick,
+ draw=red!50!black!50, % 50% red and 50% black,
+ % and that mixed with 50% white
+ % The filling:
+ top color=white, % a shading that is white at the top...
+ bottom color=red!50!black!20, % and something else at the bottom
+ % Font
+ font=\itshape
+ }]
+ \node [nonterminal] {unsigned integer};
+\end{tikzpicture}
+\end{codeexample}
+%
+Ilka is pretty proud of the use of the |minimum size| option: As the name
+suggests, this option ensures that the node is at least 6mm by 6mm, but it will
+expand in size as necessary to accommodate longer text. By giving this option
+to all nodes, they will all have the same height of 6mm.
+
+Styling the terminals is a bit more difficult because of the round corners.
+Ilka has several options how she can achieve them. One way is to use the
+|rounded corners| option. It gets a dimension as parameter and causes all
+corners to be replaced by little arcs with the given dimension as radius. By
+setting the radius to 3mm, she will get exactly what she needs: circles, when
+the shapes are, indeed, exactly 6mm by 6mm and otherwise half circles on the
+sides:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning}}]
+\begin{tikzpicture}[node distance=5mm,
+ terminal/.style={
+ % The shape:
+ rectangle,minimum size=6mm,rounded corners=3mm,
+ % The rest
+ very thick,draw=black!50,
+ top color=white,bottom color=black!20,
+ font=\ttfamily}]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+\end{tikzpicture}
+\end{codeexample}
+
+Another possibility is to use a shape that is specially made for typesetting
+rectangles with arcs on the sides (she has to use the |shapes.misc| library to
+use it). This shape gives Ilka much more control over the appearance. For
+instance, she could have an arc only on the left side, but she will not need
+this.
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm,
+ terminal/.style={
+ % The shape:
+ rounded rectangle,
+ minimum size=6mm,
+ % The rest
+ very thick,draw=black!50,
+ top color=white,bottom color=black!20,
+ font=\ttfamily}]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+\end{tikzpicture}
+\end{codeexample}
+%
+At this point, she notices a problem. The baseline of the text in the nodes is
+not aligned:
+%
+\begin{codeexample}[setup code,hidden]
+\tikzset{
+ terminal/.style={
+ % The shape:
+ rounded rectangle,
+ minimum size=6mm,
+ % The rest
+ very thick,draw=black!50,
+ top color=white,bottom color=black!20,
+ font=\ttfamily},
+}
+\end{codeexample}
+%
+\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+
+ \draw [help lines] let \p1 = (dot.base),
+ \p2 = (digit.base),
+ \p3 = (E.base)
+ in (-.5,\y1) -- (3.5,\y1)
+ (-.5,\y2) -- (3.5,\y2)
+ (-.5,\y3) -- (3.5,\y3);
+\end{tikzpicture}
+\end{codeexample}
+%
+\noindent (Ilka has moved the style definition to the preamble by saying
+|\tikzset{terminal/.style=...}|, so that she can use it in all pictures.)
+
+For the |digit| and the |E| the difference in the baselines is almost
+imperceptible, but for the dot the problem is quite severe: It looks more like
+a multiplication dot than a period.
+
+Ilka toys with the idea of using the |base right=of...| option rather than
+|right=of...| to align the nodes in such a way that the baselines are all on
+the same line (the |base right| option places a node right of something so that
+the baseline is right of the baseline of the other object). However, this does
+not have the desired effect:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,base right=of dot] {digit};
+ \node (E) [terminal,base right=of digit] {E};
+\end{tikzpicture}
+\end{codeexample}
+%
+The nodes suddenly ``dance around''! There is no hope of changing the position
+of text inside a node using anchors. Instead, Ilka must use a trick: The
+problem of mismatching baselines is caused by the fact that |.| and |digit| and
+|E| all have different heights and depth. If they all had the same, they would
+all be positioned vertically in the same manner. So, all Ilka needs to do is to
+use the |text height| and |text depth| options to explicitly specify a height
+and depth for the nodes.
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm,
+ text height=1.5ex,text depth=.25ex]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+\end{tikzpicture}
+\end{codeexample}
+
+
+\subsection{Aligning the Nodes Using Positioning Options}
+
+Ilka now has the ``styling'' of the nodes ready. The next problem is to place
+them in the right places. There are several ways to do this. The most
+straightforward is to simply explicitly place the nodes at certain coordinates
+``calculated by hand''. For very simple graphics this is perfectly alright, but
+it has several disadvantages:
+%
+\begin{enumerate}
+ \item For more difficult graphics, the calculation may become
+ complicated.
+ \item Changing the text of the nodes may make it necessary to recalculate
+ the coordinates.
+ \item The source code of the graphic is not very clear since the
+ relationships between the positions of the nodes are not made
+ explicit.
+\end{enumerate}
+
+For these reasons, Ilka decides to try out different ways of arranging the
+nodes on the page.
+
+The first method is the use of \emph{positioning options}. To use them, you
+need to load the |positioning| library. This gives you access to advanced
+implementations of options like |above| or |left|, since you can now say
+|above=of some node| in order to place a node above of |some node|, with the
+borders separated by |node distance|.
+
+Ilka can use this to draw the place the nodes in a long row:
+%
+\begin{codeexample}[setup code,hidden]
+\tikzset{
+ nonterminal/.style={
+ % The shape:
+ rectangle,
+ % The size:
+ minimum size=6mm,
+ % The border:
+ very thick,
+ draw=red!50!black!50, % 50% red and 50% black,
+ % and that mixed with 50% white
+ % The filling:
+ top color=white, % a shading that is white at the top...
+ bottom color=red!50!black!20, % and something else at the bottom
+ % Font
+ font=\itshape,
+ },
+}
+\tikzset{
+ terminal/.append style={text height=1.5ex,text depth=.25ex},
+ nonterminal/.append style={text height=1.5ex,text depth=.25ex},
+}
+\end{codeexample}
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm and 5mm]
+ \node (ui1) [nonterminal] {unsigned integer};
+ \node (dot) [terminal,right=of ui1] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+ \node (plus) [terminal,above right=of E] {+};
+ \node (minus) [terminal,below right=of E] {-};
+ \node (ui2) [nonterminal,below right=of plus] {unsigned integer};
+\end{tikzpicture}
+\end{codeexample}
+
+For the plus and minus nodes, Ilka is a bit startled by their placements.
+Shouldn't they be more to the right? The reason they are placed in that manner
+is the following: The |north east| anchor of the |E| node lies at the ``upper
+start of the right arc'', which, a bit unfortunately in this case, happens to
+be the top of the node. Likewise, the |south west| anchor of the |+| node is
+actually at its bottom and, indeed, the horizontal and vertical distances
+between the top of the |E| node and the bottom of the |+| node are both 5mm.
+
+There are several ways of fixing this problem. The easiest way is to simply add
+a little bit of horizontal shift by hand:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm and 5mm]
+ \node (E) [terminal] {E};
+ \node (plus) [terminal,above right=of E,xshift=5mm] {+};
+ \node (minus) [terminal,below right=of E,xshift=5mm] {-};
+ \node (ui2) [nonterminal,below right=of plus,xshift=5mm] {unsigned integer};
+\end{tikzpicture}
+\end{codeexample}
+
+A second way is to revert back to the idea of using a normal rectangle for the
+terminals, but with rounded corners. Since corner rounding does not affect
+anchors, she gets the following result:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm and 5mm,terminal/.append style={rectangle,rounded corners=3mm}]
+ \node (E) [terminal] {E};
+ \node (plus) [terminal,above right=of E] {+};
+ \node (minus) [terminal,below right=of E] {-};
+ \node (ui2) [nonterminal,below right=of plus] {unsigned integer};
+\end{tikzpicture}
+\end{codeexample}
+%
+A third way is to use matrices, which we will do later.
+
+Now that the nodes have been placed, Ilka needs to add connections. Here, some
+connections are more difficult than others. Consider for instance the
+``repeat'' line around the |digit|. One way of describing this line is to say
+``it starts a little to the right of |digit| than goes down and then goes to
+the left and finally ends at a point a little to the left of |digit|''. Ilka
+can put this into code as follows:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm and 5mm]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+
+ \path (dot) edge[->] (digit) % simple edges
+ (digit) edge[->] (E);
+
+ \draw [->]
+ % start right of digit.east, that is, at the point that is the
+ % linear combination of digit.east and the vector (2mm,0pt). We
+ % use the ($ ... $) notation for computing linear combinations
+ ($ (digit.east) + (2mm,0) $)
+ % Now go down
+ -- ++(0,-.5)
+ % And back to the left of digit.west
+ -| ($ (digit.west) - (2mm,0) $);
+\end{tikzpicture}
+\end{codeexample}
+
+Since Ilka needs this ``go up/down then horizontally and then up/down to a
+target'' several times, it seems sensible to define a special \emph{to-path}
+for this. Whenever the |edge| command is used, it simply adds the current value
+of |to path| to the path. So, Ilka can set up a style that contains the correct
+path:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm and 5mm,
+ skip loop/.style={to path={-- ++(0,-.5) -| (\tikztotarget)}}]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+
+ \path (dot) edge[->] (digit) % simple edges
+ (digit) edge[->] (E)
+ ($ (digit.east) + (2mm,0) $)
+ edge[->,skip loop] ($ (digit.west) - (2mm,0) $);
+\end{tikzpicture}
+\end{codeexample}
+
+Ilka can even go a step further and make her |skip loop| style parameterized.
+For this, the skip loop's vertical offset is passed as parameter |#1|. Also, in
+the following code Ilka specifies the start and targets differently, namely as
+the positions that are ``in the middle between the nodes''.
+%
+\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
+\begin{tikzpicture}[node distance=5mm and 5mm,
+ skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
+ \node (dot) [terminal] {.};
+ \node (digit) [terminal,right=of dot] {digit};
+ \node (E) [terminal,right=of digit] {E};
+
+ \path (dot) edge[->] (digit) % simple edges
+ (digit) edge[->] (E)
+ ($ (digit.east)!.5!(E.west) $)
+ edge[->,skip loop=-5mm] ($ (digit.west)!.5!(dot.east) $);
+\end{tikzpicture}
+\end{codeexample}
+
+
+\subsection{Aligning the Nodes Using Matrices}
+
+Ilka is still bothered a bit by the placement of the plus and minus nodes.
+Somehow, having to add an explicit |xshift| seems too much like cheating.
+
+A perhaps better way of positioning the nodes is to use a \emph{matrix}. In
+\tikzname\ matrices can be used to align quite arbitrary graphical objects in
+rows and columns. The syntax is very similar to the use of arrays and tables in
+\TeX\ (indeed, internally \TeX\ tables are used, but a lot of stuff is going on
+additionally).
+
+In Ilka's graphic, there will be three rows: One row containing only the plus
+node, one row containing the main nodes and one row containing only the minus
+node.
+%
+\begin{codeexample}[preamble={\usetikzlibrary{shapes.misc}}]
+\begin{tikzpicture}
+ \matrix[row sep=1mm,column sep=5mm] {
+ % First row:
+ & & & & \node [terminal] {+}; & \\
+ % Second row:
+ \node [nonterminal] {unsigned integer}; &
+ \node [terminal] {.}; &
+ \node [terminal] {digit}; &
+ \node [terminal] {E}; &
+ &
+ \node [nonterminal] {unsigned integer}; \\
+ % Third row:
+ & & & & \node [terminal] {-}; & \\
+ };
+\end{tikzpicture}
+\end{codeexample}
+%
+That was easy! By toying around with the row and columns separations, Ilka can
+achieve all sorts of pleasing arrangements of the nodes.
+
+Ilka now faces the same connecting problem as before. This time, she has an
+idea: She adds small nodes (they will be turned into coordinates later on and
+be invisible) at all the places where she would like connections to start and
+end.
+%
+\begin{codeexample}[preamble={\usetikzlibrary{shapes.misc}}]
+\begin{tikzpicture}[point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
+ skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
+ \matrix[row sep=1mm,column sep=2mm] {
+ % First row:
+ & & & & & & & & & & & \node (plus) [terminal] {+};\\
+ % Second row:
+ \node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; &
+ \node (p2) [point] {}; & \node (dot) [terminal] {.}; &
+ \node (p3) [point] {}; & \node (digit) [terminal] {digit}; &
+ \node (p4) [point] {}; & \node (p5) [point] {}; &
+ \node (p6) [point] {}; & \node (e) [terminal] {E}; &
+ \node (p7) [point] {}; & &
+ \node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; &
+ \node (p9) [point] {}; & \node (p10) [point] {};\\
+ % Third row:
+ & & & & & & & & & & & \node (minus)[terminal] {-};\\
+ };
+
+ \path (p4) edge [->,skip loop=-5mm] (p3)
+ (p2) edge [->,skip loop=5mm] (p6);
+\end{tikzpicture}
+\end{codeexample}
+%
+Now, it's only a small step to add all the missing edges.
+
+
+\subsection{The Diagram as a Graph}
+
+Matrices allow Ilka to align the nodes nicely, but the connections are not
+quite perfect. The problem is that the code does not really reflect the paths
+that underlie the diagram. For this, it seems natural enough to Ilka to use the
+|graphs| library since, after all, connecting nodes by edges is exactly what
+happens in a graph. The |graphs| library can both be used to connect nodes that
+have already been created, but it can also be used to create nodes ``on the
+fly'' and these processes can also be mixed.
+
+
+\subsubsection{Connecting Already Positioned Nodes}
+
+Ilka has already a fine method for positioning her nodes (using a |matrix|), so
+all that she needs is an easy way of specifying the edges. For this, she uses
+the |\graph| command (which is actually just a shorthand for |\path graph|). It
+allows her to write down edges between them in a simple way (the macro
+|\matrixcontent| contains exactly the matrix content from the previous example;
+no need to repeat it here):
+%
+\begin{codeexample}[setup code,hidden]
+\def\matrixcontent{
+ % First row:
+ \& \& \& \& \& \& \& \& \& \& \& \node (plus) [terminal] {+};\\
+ % Second row:
+ \node (p1) [point] {}; \& \node (ui1) [nonterminal] {unsigned integer}; \&
+ \node (p2) [point] {}; \& \node (dot) [terminal] {.}; \&
+ \node (p3) [point] {}; \& \node (digit) [terminal] {digit}; \&
+ \node (p4) [point] {}; \& \node (p5) [point] {}; \&
+ \node (p6) [point] {}; \& \node (e) [terminal] {E}; \&
+ \node (p7) [point] {}; \& \&
+ \node (p8) [point] {}; \& \node (ui2) [nonterminal] {unsigned integer}; \&
+ \node (p9) [point] {}; \& \node (p10) [point] {};\\
+ % Third row:
+ \& \& \& \& \& \& \& \& \& \& \& \node (minus)[terminal] {-};\\
+}
+\end{codeexample}
+%
+\begin{codeexample}[
+ preamble={\usetikzlibrary{graphs,shapes.misc}},
+ pre={\tikzset{ampersand replacement=\&,point/.style={coordinate}}},
+]
+\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}},
+ hv path/.style={to path={-| (\tikztotarget)}},
+ vh path/.style={to path={|- (\tikztotarget)}}]
+ \matrix[row sep=1mm,column sep=2mm] { \matrixcontent };
+
+ \graph {
+ (p1) -> (ui1) -- (p2) -> (dot) -- (p3) -> (digit) -- (p4)
+ -- (p5) -- (p6) -> (e) -- (p7) -- (p8) -> (ui2) -- (p9) -> (p10);
+ (p4) ->[skip loop=-5mm] (p3);
+ (p2) ->[skip loop=5mm] (p5);
+ (p6) ->[skip loop=-11mm] (p9);
+ (p7) ->[vh path] (plus) -> [hv path] (p8);
+ (p7) ->[vh path] (minus) -> [hv path] (p8);
+ };
+\end{tikzpicture}
+\end{codeexample}
+
+This is already pretty near to the desired result, just a few ``finishing
+touches'' are needed to style the edges more nicely.
+
+However, Ilka does not have the feeling that the |graph| command is all that
+hot in the example. It certainly does cut down on the number of characters she
+has to write, but the overall graph structure is not that much clear -- it is
+still mainly a list of paths through the graph. It would be nice to specify
+that, say, there the path from |(p7)| sort of splits to |(plus)| and |(minus)|
+and then merges once more at |(p8)|. Also, all these parentheses are bit hard
+to type.
+
+It turns out that edges from a node to a whole group of nodes are quite easy to
+specify, as shown in the next example. Additionally, by using the
+|use existing nodes| option, Ilka can also leave out all the parentheses
+(again, some options have been moved outside to keep the examples shorter):
+%
+\begin{codeexample}[
+ preamble={\usetikzlibrary{arrows.meta,graphs,shapes.misc}},
+ pre={\tikzset{
+ ampersand replacement=\&,
+ point/.style={coordinate},
+ skip loop/.style={to path={-- ++(0,##1) -| (\tikztotarget)}},
+ hv path/.style={to path={-| (\tikztotarget)}},
+ vh path/.style={to path={|- (\tikztotarget)}},
+}},
+]
+\begin{tikzpicture}[>={Stealth[round]},thick,black!50,text=black,
+ every new ->/.style={shorten >=1pt},
+ graphs/every graph/.style={edges=rounded corners}]
+ \matrix[column sep=4mm] { \matrixcontent };
+
+ \graph [use existing nodes] {
+ p1 -> ui1 -- p2 -> dot -- p3 -> digit -- p4 -- p5 -- p6 -> e -- p7 -- p8 -> ui2 -- p9 -> p10;
+ p4 ->[skip loop=-5mm] p3;
+ p2 ->[skip loop=5mm] p5;
+ p6 ->[skip loop=-11mm] p9;
+ p7 ->[vh path] { plus, minus } -> [hv path] p8;
+ };
+\end{tikzpicture}
+\end{codeexample}
+
+
+\subsubsection{Creating Nodes Using the Graph Command}
+
+Ilka has heard that the |graph| command is also supposed to make it easy to
+create nodes, not only to connect them. This is, indeed, correct: When the
+|use existing nodes| option is not used and when a node name is not surrounded
+by parentheses, then \tikzname\ will actually create a node whose name and text
+is the node name:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs}}]
+\tikz \graph [grow right=2cm] { unsigned integer -> d -> digit -> E };
+\end{codeexample}
+%
+Not quite perfect, but we are getting somewhere. First, let us change the
+positioning algorithm by saying |grow right sep|, which causes new nodes to be
+placed to the right of the previous nodes with a certain fixed separation
+(|1em| by default). Second, we add some options to make the node ``look nice''.
+Third, note the funny |d| node above: Ilka tried writing just |.| there first,
+but got some error messages. The reason is that a node cannot be called |.| in
+\tikzname, so she had to choose a different name -- which is not good, since
+she wants a dot to be shown! The trick is to put the dot in quotation marks,
+this allows you to use ``quite arbitrary text'' as a node name:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,shapes.misc}}]
+\tikz \graph [grow right sep] {
+ unsigned integer[nonterminal] -> "."[terminal] -> digit[terminal] -> E[terminal]
+};
+\end{codeexample}
+%
+Now comes the fork to the plus and minus signs. Here, Ilka can use the grouping
+mechanism of the |graph| command to create a split:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{graphs,shapes.misc}}]
+\tikz \graph [grow right sep] {
+ unsigned integer [nonterminal] ->
+ "." [terminal] ->
+ digit [terminal] ->
+ E [terminal] ->
+ {
+ "+" [terminal],
+ "" [coordinate],
+ "-" [terminal]
+ } ->
+ ui2/unsigned integer [nonterminal]
+};
+\end{codeexample}
+%
+Let us see, what is happening here. We want two |unsigned integer| nodes, but
+if we just were to use this text twice, then \tikzname\ would have noticed that
+the same name was used already in the current graph and, being smart (actually
+too smart in this case), would have created an edge back to the already-created
+node. Thus, a fresh name is needed here. However, Ilka also cannot just write
+|unsigned integer2|, because she wants the original text to be shown, after
+all! The trick is to use a slash inside the node name: In order to ``render''
+the node, the text following the slash is used instead of the node name, which
+is the text before the slash. Alternatively, the |as| option can be used, which
+also allows you to specify how a node should be rendered.
+
+It turns out that Ilka does not need to invent a name like |ui2| for a node
+that she will not reference again anyway. In this case, she can just leave out
+the name (write nothing before |/|), which always stands for a ``fresh,
+anonymous'' node name.
+
+Next, Ilka needs to add some coordinates in between of some nodes where the
+back-loops should got and she needs to shift the nodes a bit:
+%
+\begin{codeexample}[
+ preamble={\usetikzlibrary{arrows.meta,graphs,shapes.misc}},
+ pre={\tikzset{
+ skip loop/.style={to path={-- ++(0,##1) -| (\tikztotarget)}},
+ hv path/.style={to path={-| (\tikztotarget)}},
+ vh path/.style={to path={|- (\tikztotarget)}},
+}},
+]
+\begin{tikzpicture}[>={Stealth[round]}, thick, black!50, text=black,
+ every new ->/.style={shorten >=1pt},
+ graphs/every graph/.style={edges=rounded corners}]
+ \graph [grow right sep, branch down=7mm] {
+ / [coordinate] ->
+ unsigned integer [nonterminal] --
+ p1 [coordinate] ->
+ "." [terminal] --
+ p2 [coordinate] ->
+ digit [terminal] --
+ p3 [coordinate] --
+ p4 [coordinate] --
+ p5 [coordinate] ->
+ E [terminal] --
+ q1 [coordinate] ->[vh path]
+ { [nodes={yshift=7mm}]
+ "+" [terminal],
+ q2/ [coordinate],
+ "-" [terminal]
+ } -> [hv path]
+ q3 [coordinate] --
+ /unsigned integer [nonterminal] --
+ p6 [coordinate] ->
+ / [coordinate];
+
+ p1 ->[skip loop=5mm] p4;
+ p3 ->[skip loop=-5mm] p2;
+ p5 ->[skip loop=-11mm] p6;
+ };
+\end{tikzpicture}
+\end{codeexample}
+
+All that remains to be done is to somehow get rid of the strange curves between
+the |E| and the unsigned integer. They are caused by \tikzname's attempt at
+creating an edge that first goes vertical and then horizontal but is actually
+just horizontal. Additionally, the edge should not really be pointed; but it
+seems difficult to get rid of this since the \emph{other} edges from |q1|,
+namely to |plus| and |minus| should be pointed.
+
+It turns out that there is a nice way of solving this problem: You can specify
+that a graph is |simple|. This means that there can be at most one edge between
+any two nodes. Now, if you specify an edge twice, the options of the second
+specification ``win''. Thus, by adding two more lines that ``correct'' these
+edges, we get the final diagram with its complete code:
+%
+\begin{codeexample}[preamble={\usetikzlibrary{arrows.meta,graphs,shapes.misc}}]
+\tikz [>={Stealth[round]}, black!50, text=black, thick,
+ every new ->/.style = {shorten >=1pt},
+ graphs/every graph/.style = {edges=rounded corners},
+ skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}},
+ hv path/.style = {to path={-| (\tikztotarget)}},
+ vh path/.style = {to path={|- (\tikztotarget)}},
+ nonterminal/.style = {
+ rectangle, minimum size=6mm, very thick, draw=red!50!black!50, top color=white,
+ bottom color=red!50!black!20, font=\itshape, text height=1.5ex,text depth=.25ex},
+ terminal/.style = {
+ rounded rectangle, minimum size=6mm, very thick, draw=black!50, top color=white,
+ bottom color=black!20, font=\ttfamily, text height=1.5ex, text depth=.25ex},
+ shape = coordinate
+ ]
+ \graph [grow right sep, branch down=7mm, simple] {
+ / -> unsigned integer[nonterminal] -- p1 -> "." [terminal] -- p2 -> digit[terminal] --
+ p3 -- p4 -- p5 -> E[terminal] -- q1 ->[vh path]
+ {[nodes={yshift=7mm}]
+ "+"[terminal], q2, "-"[terminal]
+ } -> [hv path]
+ q3 -- /unsigned integer [nonterminal] -- p6 -> /;
+
+ p1 ->[skip loop=5mm] p4;
+ p3 ->[skip loop=-5mm] p2;
+ p5 ->[skip loop=-11mm] p6;
+
+ q1 -- q2 -- q3; % make these edges plain
+ };
+\end{codeexample}
+
+
+%% TODOsp: a commented subsection
+% \subsection{Using Chains}
+%
+% Matrices allow Ilka to align the nodes nicely, but the connections are
+% not quite perfect. The problem is that the code does not really
+% reflect the paths that underlie the diagram.
+%
+%
+% For this reason, Ilka decides to try out \emph{chains} by including
+% the |chain| library. Basically, a chain is just a sequence of
+% (usually) connected nodes. The nodes can already have been constructed
+% or they can be constructed as the chain is constructed (or these
+% processes can be mixed).
+%
+% \subsubsection{Creating a Simple Chain}
+%
+%
+% Ilka starts with creating a chain from scratch. For this, she starts a
+% chain using the |start chain| option in a scope. Then, inside the
+% scope, she uses the |on chain| option on nodes to add them to the
+% chain.
+% \begin{codeexample}[]
+% \begin{tikzpicture}[start chain,node distance=5mm]
+% \node [on chain,nonterminal] {unsigned integer};
+% \node [on chain,terminal] {.};
+% \node [on chain,terminal] {digit};
+% \node [on chain,terminal] {E};
+% \node [on chain,nonterminal] {unsigned integer};
+% \end{tikzpicture}
+% \end{codeexample}
+% (Ilka will add the plus and minus nodes later.)
+%
+% As can be seen, the nodes of a chain are placed in a row. This can be
+% changed, for instance by saying |start chain=going below| we get a
+% chain where each node is below the previous one.
+%
+% The next step is to \emph{join} the nodes of the chain. For this, we
+% add the |join| option to each node. This joins the node with the
+% previous node (for the first node nothing happens).
+% \begin{codeexample}[]
+% \begin{tikzpicture}[start chain,node distance=5mm]
+% \node [on chain,join,nonterminal] {unsigned integer};
+% \node [on chain,join,terminal] {.};
+% \node [on chain,join,terminal] {digit};
+% \node [on chain,join,terminal] {E};
+% \node [on chain,join,nonterminal] {unsigned integer};
+% \end{tikzpicture}
+% \end{codeexample}
+% In order to get a arrow tip, we redefine the |every join| style. Also,
+% we move the |join| and |on chain| options to the |every node|
+% style so that we do not have to repeat them so often.
+% \begin{codeexample}[]
+% \begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}]
+% \node [nonterminal] {unsigned integer};
+% \node [terminal] {.};
+% \node [terminal] {digit};
+% \node [terminal] {E};
+% \node [nonterminal] {unsigned integer};
+% \end{tikzpicture}
+% \end{codeexample}
+%
+%
+% \subsubsection{Branching and Joining a Chain}
+%
+% It is now time to add the plus and minus signs. They obviously
+% \emph{branch off} the main chain. For this reason, we start a branch
+% for them using the |start branch| option.
+% \begin{codeexample}[]
+% \begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}]
+% \node [nonterminal] {unsigned integer};
+% \node [terminal] {.};
+% \node [terminal] {digit};
+% \node [terminal] {E};
+% \begin{scope}[start branch=plus]
+% \node (plus) [terminal,on chain=going above right] {+};
+% \end{scope}
+% \begin{scope}[start branch=minus]
+% \node (minus) [terminal,on chain=going below right] {-};
+% \end{scope}
+% \node [nonterminal,join=with plus,join=with minus] {unsigned integer};
+% \end{tikzpicture}
+% \end{codeexample}
+%
+% Let us see, what is going on here. First, the |start branch| begins a
+% branch, starting with the node last created on the current chain,
+% which is the |E| node in our case. This is implicitly also the first
+% node on this branch. A branch is nothing different from a chain, which
+% is why the plus node is put on this branch using the |on chain|
+% option. However, this time we specify the placement of the node
+% explicitly using |going |\meta{direction}. This causes the plus sign
+% to be placed above and right of the |E| node. It is automatically
+% joined to its predecessor on the branch by the implicit |join|
+% option.
+%
+% When the first branch ends, only the plus node has been added and the
+% current chain is the original chain once more and we are back to the
+% |E| node. Now we start a new branch for the minus node. After this
+% branch, the current chain ends at |E| node once more.
+%
+% Finally, the rightmost unsigned integer is added to the (main) chain,
+% which is why it is joined correctly with the |E| node. The two
+% additional |join| options get a special |with| parameter. This allows
+% you to join a node with a node other than the predecessor on the
+% chain. The |with| should be followed by the name of a node.
+%
+% Since Ilka will need scopes more often in the following, she includes
+% the |scopes| library. This allows her to replace |\begin{scope}|
+% simply by an opening brace and |\end{scope}| by the corresponding
+% closing brace. Also, in the following example we reference
+% the nodes |plus| and |minus| using
+% their automatic name: The $i$th node on a chain is called
+% |chain-|\meta{i}. For a branch \meta{branch}, the $i$th node is called
+% |chain/|\meta{branch}|-|\meta{i}. The \meta{i} can be replaced by
+% |begin| and |end| to reference the first and (currently) last node on
+% the chain.
+%
+% \begin{codeexample}[]
+% \begin{tikzpicture}[start chain,node distance=5mm, every on chain/.style={join}, every join/.style={->}]
+% \node [on chain,nonterminal] {unsigned integer};
+% \node [on chain,terminal] {.};
+% \node [on chain,terminal] {digit};
+% \node [on chain,terminal] {E};
+% { [start branch=plus]
+% \node (plus) [terminal,on chain=going above right] {+};
+% }
+% { [start branch=minus]
+% \node (minus) [terminal,on chain=going below right] {-};
+% }
+% \node [nonterminal,on chain,join=with chain/plus-end,join=with chain/minus-end] {unsigned integer};
+% \end{tikzpicture}
+% \end{codeexample}
+%
+%
+% The next step is to add intermediate coordinate nodes in the same
+% manner as Ilka did for the matrix. For them, we change the |join|
+% style slightly, namely for these nodes we do not want an arrow
+% tip. This can be achieved either by (locally) changing the
+% |every join| style or, which is what is done in the below example, by
+% giving the desired style using |join=by ...|, where |...| is the style
+% to be used for the join.
+%
+% \begin{codeexample}[]
+% \begin{tikzpicture}[start chain,node distance=5mm and 2mm,
+% every node/.style={on chain},
+% nonterminal/.append style={join=by ->},
+% terminal/.append style={join=by ->},
+% point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}]
+% \node [point] {}; \node [nonterminal] {unsigned integer};
+% \node [point] {}; \node [terminal] {.};
+% \node [point] {}; \node [terminal] {digit};
+% \node [point] {}; \node [point] {};
+% \node [point] {}; \node [terminal] {E};
+% \node [point] {};
+% { [node distance=5mm and 1cm] % local change in horizontal distance
+% { [start branch=plus]
+% \node (plus) [terminal,on chain=going above right] {+};
+% }
+% { [start branch=minus]
+% \node (minus) [terminal,on chain=going below right] {-};
+% }
+% \node [point,below right=of plus,join=with chain/plus-end by ->,join=with chain/minus-end by ->] {};
+% }
+% \node [nonterminal] {unsigned integer};
+% \node [point] {};
+% \end{tikzpicture}
+% \end{codeexample}
+%
+%
+% \subsubsection{Chaining Together Already Positioned Nodes}
+%
+% The final step is to add the missing arrows. We can also use branches
+% for them (even though we do not have to, but it is good practice and
+% they exhibit the structure of the diagram in the code).
+%
+% Let us start with the repeat loop around the |digit|. This can be
+% thought of as a branch that starts at the point after the digit and
+% that ends at the point before the digit. However, we have already
+% constructed the point before the digit! In such cases, it is possible
+% to ``chain in'' an already positioned node, using the |\chainin|
+% command. This command must be followed by a coordinate that contains a
+% node name and optionally some options. The effect is that the named
+% node is made part of the current chain.
+%
+% \begin{codeexample}[pre={\tikzset{node distance=5mm and 2mm,
+% every node/.style={on chain},
+% terminal/.append style={join=by ->},
+% point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}}}]
+% \begin{tikzpicture}[start chain] % plus some styles that are not shown
+% \node [point] {};
+% \node (before digit) [point] {};
+% \node [terminal] {digit};
+% \node [point] {};
+% { [start branch=digit loop]
+% \chainin (before digit) [join=by {->,skip loop=-5mm}];
+% }
+% \node [point] {};
+% \end{tikzpicture}
+% \end{codeexample}
+%
+%
+% \subsubsection{Combined Use of Matrices and Chains}
+%
+% Ilka's final idea is to combine matrices and chains in the following
+% manner: She will use a matrix to position the nodes. However, to show
+% the logical ``flow structure'' inside the diagram, she will create
+% chains and branches that show what is going on.
+%
+% Ilka starts with the matrix we had earlier, only with slightly adapted
+% styles. Then she writes down the main chain and its branches:
+%
+% \begin{codeexample}[preamble={\usetikzlibrary{arrows.meta}}]
+% \begin{tikzpicture}[point/.style={coordinate},>={Stealth[round]},thick,draw=black!50,
+% tip/.style={->,shorten >=1pt},every join/.style={rounded corners},
+% hv path/.style={to path={-| (\tikztotarget)}},
+% vh path/.style={to path={|- (\tikztotarget)}}]
+% \matrix[column sep=4mm] {
+% % First row:
+% & & & & & & & & & & & \node (plus) [terminal] {+};\\
+% % Second row:
+% \node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; &
+% \node (p2) [point] {}; & \node (dot) [terminal] {.}; &
+% \node (p3) [point] {}; & \node (digit) [terminal] {digit}; &
+% \node (p4) [point] {}; & \node (p5) [point] {}; &
+% \node (p6) [point] {}; & \node (e) [terminal] {E}; &
+% \node (p7) [point] {}; & &
+% \node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; &
+% \node (p9) [point] {}; & \node (p10) [point] {};\\
+% % Third row:
+% & & & & & & & & & & & \node (minus)[terminal] {-};\\
+% };
+%
+% { [start chain]
+% \chainin (p1);
+% \chainin (ui1) [join=by tip];
+% \chainin (p2) [join];
+% \chainin (dot) [join=by tip];
+% \chainin (p3) [join];
+% \chainin (digit) [join=by tip];
+% \chainin (p4) [join];
+% { [start branch=digit loop]
+% \chainin (p3) [join=by {skip loop=-6mm,tip}];
+% }
+% \chainin (p5) [join,join=with p2 by {skip loop=6mm,tip}];
+% \chainin (p6) [join];
+% \chainin (e) [join=by tip];
+% \chainin (p7) [join];
+% { [start branch=plus]
+% \chainin (plus) [join=by {vh path,tip}];
+% \chainin (p8) [join=by {hv path,tip}];
+% }
+% { [start branch=minus]
+% \chainin (minus) [join=by {vh path,tip}];
+% \chainin (p8) [join=by {hv path,tip}];
+% }
+% \chainin (p8) [join];
+% \chainin (ui2) [join=by tip];
+% \chainin (p9) [join,join=with p6 by {skip loop=-11mm,tip}];
+% \chainin (p10) [join=by tip];
+% }
+% \end{tikzpicture}
+% \end{codeexample}