Updated presentation
[rodrigo-msc.git] / pgftree.tex
blob8173ed13cb8975895cad26a3da183a846d952a66
1 % pgftree.tex
2 % Version 1.1, 25 Dec 2009
4 % Copyright 2009 by David Chiang
6 % This program is free software; you can redistribute it and/or modify
7 % it under the terms of the GNU General Public License as published by
8 % the Free Software Foundation; either version 2 of the License, or
9 % (at your option) any later version.
11 % This program is distributed in the hope that it will be useful,
12 % but WITHOUT ANY WARRANTY; without even the implied warranty of
13 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 % GNU General Public License for more details.
16 % You should have received a copy of the GNU General Public License along
17 % with this program; if not, write to the Free Software Foundation, Inc.,
18 % 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 % New in version 1.1:
21 % - major restructuring to not do arbitrary nesting of subpicture environments
22 % - sideways trees
24 % To do:
25 % - trees with all leaves at same level
26 % - if \nodename does not exist as desired, wrap inside a rectangle node
27 % - don't use pgfsubpic internals
29 \newdimen\levelsep \levelsep=30pt
30 \newdimen\subtreesep \subtreesep=2pt
32 \def\leveldirection{down}
33 \def\siblingdirection{right}
35 % definitions of growing directions
36 \def\pgftree@levelshift{\csname pgftree@levelshift@\leveldirection\endcsname}
37 \def\pgftree@parentanchor{\csname pgftree@parentanchor@\leveldirection\endcsname}
38 \def\pgftree@childanchor{\csname pgftree@childanchor@\leveldirection\endcsname}
39 % these assume that the current subpicture is the child
40 \def\pgftree@presiblingshift{\csname pgftree@presiblingshift@\siblingdirection\endcsname}
41 \def\pgftree@postsiblingshift{\csname pgftree@postsiblingshift@\siblingdirection\endcsname}
43 \def\pgftree@levelshift@down{\pgfpoint{0}{-\levelsep}}
44 \def\pgftree@parentanchor@down{south}
45 \def\pgftree@childanchor@down{north}
47 \def\pgftree@levelshift@up{\pgfpoint{0}{\levelsep}}
48 \def\pgftree@parentanchor@up{north}
49 \def\pgftree@childanchor@up{south}
51 \def\pgftree@levelshift@right{\pgfpoint{\levelsep}{0}}
52 \def\pgftree@parentanchor@right{east}
53 \def\pgftree@childanchor@right{west}
55 \def\pgftree@levelshift@left{\pgfpoint{-\levelsep}{0}}
56 \def\pgftree@parentanchor@left{west}
57 \def\pgftree@childanchor@left{east}
59 \def\pgftree@presiblingshift@right{\pgf@process{\pgf@x-\pgf@subpicminx \advance\pgf@x\subtreesep \pgf@y 0pt}}
60 \def\pgftree@postsiblingshift@right{\pgf@process{\pgf@x\pgf@subpicmaxx \pgf@y 0pt}}
62 \def\pgftree@presiblingshift@left{\pgf@process{\pgf@x-\pgf@subpicmaxx \advance\pgf@x-\subtreesep \pgf@y 0pt}}
63 \def\pgftree@postsiblingshift@left{\pgf@process{\pgf@x\pgf@subpicminx \pgf@y 0pt}}
65 \def\pgftree@presiblingshift@up{\pgf@process{\pgf@x 0pt \pgf@y-\pgf@subpicminy \advance\pgf@y\subtreesep}}
66 \def\pgftree@postsiblingshift@up{\pgf@process{\pgf@x 0pt \pgf@y\pgf@subpicmaxy}}
68 \def\pgftree@presiblingshift@down{\pgf@process{\pgf@x 0pt \pgf@y-\pgf@subpicmaxy \advance\pgf@y-\subtreesep}}
69 \def\pgftree@postsiblingshift@down{\pgf@process{\pgf@x 0pt \pgf@y\pgf@subpicminy}}
71 % for convenience if you are using \pgftree directly
72 \def\drawnode#1{\pgfnode{rectangle}{base}{#1}{\nodename}{\pgfusepath{discard}}}
73 \def\drawedge{%
74 \pgfpathmoveto{\pgfpointanchor{\parentnodename}{\pgftree@parentanchor}}%
75 \pgfpathlineto{\pgfpointanchor{\nodename}{\pgftree@childanchor}}%
76 \pgfusepath{stroke}}
78 % local variables that we need to assign to inside a \pgfforeach
79 \newdimen\pgftree@childx
80 \newdimen\pgftree@savechildx
81 \newdimen\pgftree@childy
82 \newdimen\pgftree@savechildy
83 \newcount\pgftree@childi
84 \newcount\pgftree@savechildi
86 %%% \pgftree{subtree}
88 \def\pgftree#1{%
89 \def\nodename{r}%
90 #1%
91 \pgfplacesubpicture
94 %%% \pgfsubtree{root}{subtrees}
95 % The first argument draws the root node using PGF/TikZ commands.
96 % The node must be named \nodename.
98 % The second argument is an even-length sequence of tokens.
99 % Token 2n-1 in the sequence draws the nth edge. It should draw an edge from \parentnodename to \nodename.
100 % Token 2n in the sequence draws the nth subtree. Its root must be named \nodename.
102 \pgfnewsubpicture{children}
103 \newdimen\pgftree@lastchildx
104 \newdimen\pgftree@lastchildy
106 \def\pgfsubtree#1#2{%
107 \let\parentnodename\nodename
108 \pgftree@savechildx=\pgftree@childx
109 \pgftree@savechildy=\pgftree@childy
110 \pgftree@savechildi=\pgftree@childi
111 % Build subpicture with all the children and their subtrees
112 {\pgftree@childx=0pt%
113 \pgftree@childy=0pt%
114 \pgftree@childi=0%
115 \process@children #2}%
116 \begin{pgfsubpicture}%
117 % Create node
119 \ifnum\pgftree@childi>0%
120 % Place children
121 % move down \levelsep
122 {\pgftransformshift{\pgftree@levelshift}%
123 % center so that parent is midway between origins of first and last children
124 \pgftransformshift{\pgfpointscale{-0.5}{\pgfqpoint{\the\pgftree@childx}{\the\pgftree@childy}}}%
125 \pgfplacesubpicture}%
126 % Draw the edges
127 {\pgftree@childi=0%
128 \process@edges #2}%
130 \end{pgfsubpicture}%
131 \global\pgftree@childi=\pgftree@savechildi
132 \global\pgftree@childx=\pgftree@savechildx
133 \global\pgftree@childy=\pgftree@savechildy
136 \def\process@children{%
137 \pgfutil@ifnextchar\egroup
138 {% No more children, step back to origin of last child
139 \global\pgftree@childx\pgftree@lastchildx
140 \global\pgftree@childy\pgftree@lastchildy
141 \global\pgftree@childi\pgftree@childi
142 \ifnum\pgftree@childi>0%
143 \pgfrestoresubpicture{children}% pass children back to caller
146 {\@process@children}%
148 \def\@process@children#1#2{% #1 is the edge, #2 is the child
149 % Build the current child
150 {\edef\nodename{\parentnodename-\the\pgftree@childi}%
151 #2}%
152 \begin{pgfsubpicture}%
153 % Place current child
154 \ifnum\pgftree@childi>0% the first child is always at 0
155 \pgftree@presiblingshift \global\advance\pgftree@childx\pgf@x \global\advance\pgftree@childy\pgf@y
157 {\pgftransformshift{\pgfqpoint{\the\pgftree@childx}{\the\pgftree@childy}}%
158 \pgfplacesubpicture}%
159 \global\pgftree@lastchildx\pgftree@childx
160 \global\pgftree@lastchildy\pgftree@childy
161 \pgftree@postsiblingshift \global\advance\pgftree@childx\pgf@x \global\advance\pgftree@childy\pgf@y
162 % Save the augmented row of children back into "children"
163 \end{pgfsubpicture}
164 \ifnum\pgftree@childi>0%
165 \pgfmergesubpicture{children}
166 \else
167 \pgfsavesubpicture{children}%
169 \advance\pgftree@childi by 1%
170 \process@children
173 \def\process@edges{%
174 \pgfutil@ifnextchar\egroup
176 {\@process@edges}%
178 \def\@process@edges#1#2{%
179 \edef\nodename{\parentnodename-\the\pgftree@childi}%
181 \advance\pgftree@childi by 1%
182 \process@edges
185 \def\subtreeof#1{%
186 % the subpicture which contains a node also contains exactly its subtree
187 \csname pgf@sh@pi@#1\endcsname