sawine@0
|
1 |
% tikz-qtree.tex
|
sawine@0
|
2 |
% Version 1.11, 25 Dec 2010
|
sawine@0
|
3 |
|
sawine@0
|
4 |
% Copyright (C) 2002, 2009 by David Chiang
|
sawine@0
|
5 |
|
sawine@0
|
6 |
% This program is free software; you can redistribute it and/or modify
|
sawine@0
|
7 |
% it under the terms of the GNU General Public License as published by
|
sawine@0
|
8 |
% the Free Software Foundation; either version 2 of the License, or
|
sawine@0
|
9 |
% (at your option) any later version.
|
sawine@0
|
10 |
|
sawine@0
|
11 |
% This program is distributed in the hope that it will be useful,
|
sawine@0
|
12 |
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
sawine@0
|
13 |
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
sawine@0
|
14 |
% GNU General Public License for more details.
|
sawine@0
|
15 |
|
sawine@0
|
16 |
% You should have received a copy of the GNU General Public License along
|
sawine@0
|
17 |
% with this program; if not, write to the Free Software Foundation, Inc.,
|
sawine@0
|
18 |
% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
sawine@0
|
19 |
|
sawine@0
|
20 |
% New in version 1.11:
|
sawine@0
|
21 |
% - make options compatible with standard tikz trees
|
sawine@0
|
22 |
|
sawine@0
|
23 |
% New in version 1.1:
|
sawine@0
|
24 |
|
sawine@0
|
25 |
% - sideways trees
|
sawine@0
|
26 |
|
sawine@0
|
27 |
%% These macros facilitate building up an object recursively before
|
sawine@0
|
28 |
%% putting it into the input stream.
|
sawine@0
|
29 |
|
sawine@0
|
30 |
\newtoks\@result
|
sawine@0
|
31 |
\def\@call#1#2{\let\@cont=#2\bgroup\@result={}#1}
|
sawine@0
|
32 |
\def\@return{\global\@result=\@result\egroup\@cont}
|
sawine@0
|
33 |
|
sawine@0
|
34 |
\def\@ifequal#1#2{\edef\testa{#1}\edef\testb{#2}\ifx\testa\testb}
|
sawine@0
|
35 |
|
sawine@0
|
36 |
%% scan a tree: this just scans a subtree and then puts it onto the
|
sawine@0
|
37 |
%% input stream
|
sawine@0
|
38 |
|
sawine@0
|
39 |
\def\Tree{\@call\@subtree\@Tree}
|
sawine@0
|
40 |
\def\@Tree{%
|
sawine@0
|
41 |
%\showthe\@result %debug
|
sawine@0
|
42 |
\ifpgfpicture % is there a test for tikzpicture?
|
sawine@0
|
43 |
\pgftree{\the\@result}%
|
sawine@0
|
44 |
\else
|
sawine@0
|
45 |
\tikzpicture[baseline]\pgftree{\the\@result}\endtikzpicture
|
sawine@0
|
46 |
\fi
|
sawine@0
|
47 |
}
|
sawine@0
|
48 |
|
sawine@0
|
49 |
%% scan a subtree
|
sawine@0
|
50 |
\newtoks\child@list
|
sawine@0
|
51 |
\newtoks\root@node
|
sawine@0
|
52 |
|
sawine@0
|
53 |
\def\@subtree[{%
|
sawine@0
|
54 |
\root@node={}%
|
sawine@0
|
55 |
\pgfutil@ifnextchar.{\@call\@interior\@@subtree}{\@@@subtree}}
|
sawine@0
|
56 |
\def\@@subtree{%
|
sawine@0
|
57 |
\root@node=\@result
|
sawine@0
|
58 |
\@@@subtree
|
sawine@0
|
59 |
}
|
sawine@0
|
60 |
\def\@@@subtree{%
|
sawine@0
|
61 |
\@call\@children\@@@@subtree
|
sawine@0
|
62 |
}
|
sawine@0
|
63 |
\def\@@@@subtree]{%
|
sawine@0
|
64 |
\child@list=\@result
|
sawine@0
|
65 |
\pgfutil@ifnextchar.{\@call\@interior\@@@@@subtree}{\@@@@@@subtree}}
|
sawine@0
|
66 |
\def\@@@@@subtree{%
|
sawine@0
|
67 |
%%% Check for mismatch.
|
sawine@0
|
68 |
\@ifequal{\the\root@node}{\pgfutil@empty}%
|
sawine@0
|
69 |
\root@node=\@result
|
sawine@0
|
70 |
\fi
|
sawine@0
|
71 |
\@ifequal{\the\root@node}{\the\@result}\else
|
sawine@0
|
72 |
\message{Warning: mismatched labels, \the\root@node{} and \the\@result.}%
|
sawine@0
|
73 |
\fi
|
sawine@0
|
74 |
\@@@@@@subtree
|
sawine@0
|
75 |
}
|
sawine@0
|
76 |
\def\@@@@@@subtree{%
|
sawine@0
|
77 |
\@ifequal{\the\root@node}{\pgfutil@empty}%
|
sawine@0
|
78 |
\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\path coordinate (\noexpand\nodename);}{\the\child@list}}}%
|
sawine@0
|
79 |
\else
|
sawine@0
|
80 |
\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\the\root@node}{\the\child@list}}}%
|
sawine@0
|
81 |
\fi
|
sawine@0
|
82 |
\act
|
sawine@0
|
83 |
\@return}
|
sawine@0
|
84 |
|
sawine@0
|
85 |
%% scan a sequence of subtrees or leaves
|
sawine@0
|
86 |
|
sawine@0
|
87 |
\newif\ifscanned@edge
|
sawine@0
|
88 |
|
sawine@0
|
89 |
\def\@children{%
|
sawine@0
|
90 |
\scanned@edgefalse
|
sawine@0
|
91 |
\child@list{}%
|
sawine@0
|
92 |
\@@children}
|
sawine@0
|
93 |
\def\@@children{%
|
sawine@0
|
94 |
\pgfutil@ifnextchar]{\@result\child@list\@return}{% end of children
|
sawine@0
|
95 |
\pgfutil@ifnextchar\edge{% explicit edge
|
sawine@0
|
96 |
\ifscanned@edge
|
sawine@0
|
97 |
\message{Warning: more than one edge given for a single child}\let\next\@@children % ignore
|
sawine@0
|
98 |
\else
|
sawine@0
|
99 |
\scanned@edgetrue\let\next\@@@children
|
sawine@0
|
100 |
\fi
|
sawine@0
|
101 |
\@call\@edge\next}{%
|
sawine@0
|
102 |
% else, a real node is next
|
sawine@0
|
103 |
\ifscanned@edge\else % no explicit edge, supply default
|
sawine@0
|
104 |
\expandafter\child@list\expandafter{\the\child@list{\edge@adapter{}}}%
|
sawine@0
|
105 |
\fi
|
sawine@0
|
106 |
\scanned@edgefalse
|
sawine@0
|
107 |
\pgfutil@ifnextchar[{\@call\@subtree\@@@children}% subtree
|
sawine@0
|
108 |
{\@call\@leaf\@@@children}% leaf
|
sawine@0
|
109 |
}}}
|
sawine@0
|
110 |
\def\@@@children{%
|
sawine@0
|
111 |
% wrap child inside curly braces
|
sawine@0
|
112 |
\expandafter\@result\expandafter{\expandafter{\the\@result}}%
|
sawine@0
|
113 |
\edef\act{\noexpand\child@list{\the\child@list \the\@result}}\act
|
sawine@0
|
114 |
\@@children
|
sawine@0
|
115 |
}
|
sawine@0
|
116 |
|
sawine@0
|
117 |
\def\@interior.{\@result{\node[alias=\nodename][every tree node,every internal node]}\@label}
|
sawine@0
|
118 |
|
sawine@0
|
119 |
\def\@leaf{\@call\@label\@@leaf}
|
sawine@0
|
120 |
\def\@@leaf{\edef\act{\noexpand\@result{\noexpand\pgfsubtree{\noexpand\node[alias=\noexpand\nodename][every tree node,every leaf node]\the\@result}{}}}\act\@return}
|
sawine@0
|
121 |
|
sawine@0
|
122 |
\def\@edge\edge #1;{%
|
sawine@0
|
123 |
\@result{\edge@adapter{#1}}%
|
sawine@0
|
124 |
\@return}
|
sawine@0
|
125 |
\def\edge@adapter#1{%
|
sawine@0
|
126 |
\let\tikzparentnode\parentnodename
|
sawine@0
|
127 |
\let\tikzchildnode\nodename
|
sawine@0
|
128 |
\path edge from parent #1;%
|
sawine@0
|
129 |
}
|
sawine@0
|
130 |
|
sawine@0
|
131 |
% a label is either text or PGF/TikZ code starting with \node
|
sawine@0
|
132 |
\def\@label{\pgfutil@ifnextchar\node{\@litlabel}{\@@label}}
|
sawine@0
|
133 |
\def\@@label#1 {%
|
sawine@0
|
134 |
\expandafter\@result\expandafter{\the\@result{#1};}%
|
sawine@0
|
135 |
\@return}
|
sawine@0
|
136 |
|
sawine@0
|
137 |
% try to copy \node command into \@result without stripping braces
|
sawine@0
|
138 |
\def\@litlabel\node{\@@litlabel}
|
sawine@0
|
139 |
\def\@@litlabel{\pgfutil@ifnextchar\bgroup{\@@@litlabel}{\@@@@litlabel}}
|
sawine@0
|
140 |
\def\@@@litlabel#1{\expandafter\@result\expandafter{\the\@result {#1}}\@@litlabel}
|
sawine@0
|
141 |
\def\@@@@litlabel#1;{\expandafter\@result\expandafter{\the\@result #1;}\@return}
|
sawine@0
|
142 |
|
sawine@0
|
143 |
% predefined edges
|
sawine@0
|
144 |
|
sawine@0
|
145 |
\def\tree@edge#1#2{(#1.\pgftree@parentanchor) -- (#2.\pgftree@childanchor)}
|
sawine@0
|
146 |
|
sawine@0
|
147 |
\def\roof@edge#1#2{\csname roof@edge@\leveldirection\endcsname{#1}{#2}}
|
sawine@0
|
148 |
\def\roof@edge@down#1#2{(#1.south) -- (#2.north west) -- (#2.north east) -- cycle}
|
sawine@0
|
149 |
\def\roof@edge@up#1#2{(#1.north) -- (#2.south west) -- (#2.south east) -- cycle}
|
sawine@0
|
150 |
\def\roof@edge@left#1#2{(#1.west) -- (#2.north east) -- (#2.south east) -- cycle}
|
sawine@0
|
151 |
\def\roof@edge@right#1#2{(#1.east) -- (#2.north west) -- (#2.south west) -- cycle}
|
sawine@0
|
152 |
|
sawine@0
|
153 |
%%% Options
|
sawine@0
|
154 |
\pgfkeysgetvalue{/tikz/level distance/.@cmd}{\orig@leveldistance}
|
sawine@0
|
155 |
\tikzoption{level distance}{\pgfmathsetlength\levelsep{#1}\orig@leveldistance#1\pgfeov}
|
sawine@0
|
156 |
\pgfkeysgetvalue{/tikz/sibling distance/.@cmd}{\orig@siblingdistance}
|
sawine@0
|
157 |
\tikzoption{sibling distance}{\pgfmathsetlength\subtreesep{#1}\orig@siblingdistance#1\pgfeov} % different semantics
|
sawine@0
|
158 |
|
sawine@0
|
159 |
% I don't really like this scheme
|
sawine@0
|
160 |
\pgfkeysgetvalue{/tikz/grow/.@cmd}{\orig@grow}
|
sawine@0
|
161 |
\tikzoption{grow}{\csname grow@#1\endcsname\orig@grow#1\pgfeov}
|
sawine@0
|
162 |
\pgfkeysgetvalue{/tikz/grow'/.@cmd}{\orig@growprime}
|
sawine@0
|
163 |
\tikzoption{grow'}{\csname growprime@#1\endcsname\orig@growprime#1\pgfeov}
|
sawine@0
|
164 |
\def\grow@up{\def\leveldirection{up}\def\siblingdirection{left}}
|
sawine@0
|
165 |
\def\grow@down{\def\leveldirection{down}\def\siblingdirection{right}}
|
sawine@0
|
166 |
\def\growprime@up{\def\leveldirection{up}\def\siblingdirection{right}}
|
sawine@0
|
167 |
\def\growprime@down{\def\leveldirection{down}\def\siblingdirection{left}}
|
sawine@0
|
168 |
\def\grow@left{\def\leveldirection{left}\def\siblingdirection{down}}
|
sawine@0
|
169 |
\def\grow@right{\def\leveldirection{right}\def\siblingdirection{up}}
|
sawine@0
|
170 |
\def\growprime@left{\def\leveldirection{left}\def\siblingdirection{up}}
|
sawine@0
|
171 |
\def\growprime@right{\def\leveldirection{right}\def\siblingdirection{down}}
|
sawine@0
|
172 |
|
sawine@0
|
173 |
% defaults appropriate for linguistic trees
|
sawine@0
|
174 |
\tikzset{every tree node/.style={anchor=base}}
|
sawine@0
|
175 |
\tikzset{every leaf node/.style={}}
|
sawine@0
|
176 |
\tikzset{every internal node/.style={}}
|
sawine@0
|
177 |
\def\tikz@edge@to@parent@path{\tree@edge{\tikzparentnode}{\tikzchildnode}}
|
sawine@0
|
178 |
|
sawine@0
|
179 |
% predefined roof style
|
sawine@0
|
180 |
\tikzset{roof/.style={edge from parent path=\roof@edge{\tikzparentnode}{\tikzchildnode}}}
|
sawine@0
|
181 |
|