From 528bd7b580ff2dfe64ef77df5963655a60aa32de Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 31 Oct 2012 21:46:48 +0000 Subject: new pgf/tikz package forest (31oct12) git-svn-id: svn://tug.org/texlive/trunk@28142 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/forest/forest.sty | 4678 +++++++++++++++++++++++++ 1 file changed, 4678 insertions(+) create mode 100644 Master/texmf-dist/tex/latex/forest/forest.sty (limited to 'Master/texmf-dist/tex/latex/forest') diff --git a/Master/texmf-dist/tex/latex/forest/forest.sty b/Master/texmf-dist/tex/latex/forest/forest.sty new file mode 100644 index 00000000000..1759c5d94d3 --- /dev/null +++ b/Master/texmf-dist/tex/latex/forest/forest.sty @@ -0,0 +1,4678 @@ +%% +%% This is file `forest.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% forest.dtx +%% +%% `forest' is a `pgf/tikz'-based package for drawing (linguistic) trees. +%% +%% Copyright (c) 2012 Saso Zivanovic +%% (Sa\v{s}o \v{Z}ivanovi\'{c}) +%% saso.zivanovic@guest.arnes.si +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Saso Zivanovic. +%% +%% This work consists of the files forest.dtx and forest.ins +%% and the derived file forest.sty. +%% +\ProvidesPackage{forest}[2012/10/31 v1.0 Drawing (linguistic) trees] + +\RequirePackage{tikz} +\usetikzlibrary{shapes} +\usetikzlibrary{fit} +\usetikzlibrary{calc} +\usepgflibrary{intersections} + +\RequirePackage{pgfopts} +\RequirePackage{etoolbox} +\RequirePackage{environ} + + %\usepackage[trace]{trace-pgfkeys} +\pgfkeys{/forest/.is family} +\def\forestset#1{\pgfqkeys{/forest}{#1}} +\long\def\forest@original@pgfkeysdefnargs@#1#2#3#4{% + \ifcase#2\relax + \pgfkeyssetvalue{#1/.@args}{}% + \or + \pgfkeyssetvalue{#1/.@args}{##1}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% + \else + \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% + \fi + \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs + \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% + \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% + % eliminate the \pgfeov at the end such that TeX gobbles spaces + % by using + % \pgfkeysdef{#1}{\pgfkeysvalueof{#1/.@@body}##1} + % (with expansion of '#1'): + \edef\pgfkeys@tempargs{\noexpand\pgfkeysvalueof{#1/.@@body}}% + \def\pgfkeys@temp{\pgfkeysdef{#1}}% + \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs##1}% + \pgfkeyssetvalue{#1/.@body}{#3}% +} + +\long\def\forest@patched@pgfkeysdefnargs@#1#2#3#4{% + \ifcase#2\relax + \pgfkeyssetvalue{#1/.@args}{}% + \or + \pgfkeyssetvalue{#1/.@args}{##1}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + %%%%% removed: + %%%%% \or + %%%%% \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% + \or + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% + \else + \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% + \fi + \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs + \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% + \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% + % eliminate the \pgfeov at the end such that TeX gobbles spaces + % by using + % \pgfkeysdef{#1}{\pgfkeysvalueof{#1/.@@body}##1} + % (with expansion of '#1'): + \edef\pgfkeys@tempargs{\noexpand\pgfkeysvalueof{#1/.@@body}}% + \def\pgfkeys@temp{\pgfkeysdef{#1}}% + \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs##1}% + \pgfkeyssetvalue{#1/.@body}{#3}% +} +\ifx\pgfkeysdefnargs@\forest@original@pgfkeysdefnargs@ + \let\pgfkeysdefnargs@\forest@patched@pgfkeysdefnargs@ +\fi +\def\forest@original@pgfpointintersectionoflines#1#2#3#4{% + { + % + % Compute orthogonal vector to #1--#2 + % + \pgf@process{#2}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#1}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \pgf@ya=-\pgf@ya% + % Normalise a bit + \c@pgf@counta=\pgf@xa% + \ifnum\c@pgf@counta<0\relax% + \c@pgf@counta=-\c@pgf@counta\relax% + \fi% + \c@pgf@countb=\pgf@ya% + \ifnum\c@pgf@countb<0\relax% + \c@pgf@countb=-\c@pgf@countb\relax% + \fi% + \advance\c@pgf@counta by\c@pgf@countb\relax% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta>0\relax% + \divide\pgf@xa by\c@pgf@counta\relax% + \divide\pgf@ya by\c@pgf@counta\relax% + \fi% + % + % Compute projection + % + \pgf@xc=\pgf@sys@tonumber{\pgf@ya}\pgf@x% + \advance\pgf@xc by\pgf@sys@tonumber{\pgf@xa}\pgf@y% + % + % The orthogonal vector is (\pgf@ya,\pgf@xa) + % + % + % Compute orthogonal vector to #3--#4 + % + \pgf@process{#4}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{#3}% + \advance\pgf@xb by-\pgf@x% + \advance\pgf@yb by-\pgf@y% + \pgf@yb=-\pgf@yb% + % Normalise a bit + \c@pgf@counta=\pgf@xb% + \ifnum\c@pgf@counta<0\relax% + \c@pgf@counta=-\c@pgf@counta\relax% + \fi% + \c@pgf@countb=\pgf@yb% + \ifnum\c@pgf@countb<0\relax% + \c@pgf@countb=-\c@pgf@countb\relax% + \fi% + \advance\c@pgf@counta by\c@pgf@countb\relax% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta>0\relax% + \divide\pgf@xb by\c@pgf@counta\relax% + \divide\pgf@yb by\c@pgf@counta\relax% + \fi% + % + % Compute projection + % + \pgf@yc=\pgf@sys@tonumber{\pgf@yb}\pgf@x% + \advance\pgf@yc by\pgf@sys@tonumber{\pgf@xb}\pgf@y% + % + % The orthogonal vector is (\pgf@yb,\pgf@xb) + % + % Setup transformation matrx (this is just to use the matrix + % inversion) + % + \pgfsettransform{{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{0pt}{0pt}}% + \pgftransforminvert% + \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xc}{\pgf@yc}}}% + }% +} +\def\forest@patched@pgfpointintersectionoflines#1#2#3#4{% + {% added the percent sign in this line + % + % Compute orthogonal vector to #1--#2 + % + \pgf@process{#2}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{#1}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \pgf@ya=-\pgf@ya% + % Normalise a bit + \c@pgf@counta=\pgf@xa% + \ifnum\c@pgf@counta<0\relax% + \c@pgf@counta=-\c@pgf@counta\relax% + \fi% + \c@pgf@countb=\pgf@ya% + \ifnum\c@pgf@countb<0\relax% + \c@pgf@countb=-\c@pgf@countb\relax% + \fi% + \advance\c@pgf@counta by\c@pgf@countb\relax% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta>0\relax% + \divide\pgf@xa by\c@pgf@counta\relax% + \divide\pgf@ya by\c@pgf@counta\relax% + \fi% + % + % Compute projection + % + \pgf@xc=\pgf@sys@tonumber{\pgf@ya}\pgf@x% + \advance\pgf@xc by\pgf@sys@tonumber{\pgf@xa}\pgf@y% + % + % The orthogonal vector is (\pgf@ya,\pgf@xa) + % + % + % Compute orthogonal vector to #3--#4 + % + \pgf@process{#4}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{#3}% + \advance\pgf@xb by-\pgf@x% + \advance\pgf@yb by-\pgf@y% + \pgf@yb=-\pgf@yb% + % Normalise a bit + \c@pgf@counta=\pgf@xb% + \ifnum\c@pgf@counta<0\relax% + \c@pgf@counta=-\c@pgf@counta\relax% + \fi% + \c@pgf@countb=\pgf@yb% + \ifnum\c@pgf@countb<0\relax% + \c@pgf@countb=-\c@pgf@countb\relax% + \fi% + \advance\c@pgf@counta by\c@pgf@countb\relax% + \divide\c@pgf@counta by 65536\relax% + \ifnum\c@pgf@counta>0\relax% + \divide\pgf@xb by\c@pgf@counta\relax% + \divide\pgf@yb by\c@pgf@counta\relax% + \fi% + % + % Compute projection + % + \pgf@yc=\pgf@sys@tonumber{\pgf@yb}\pgf@x% + \advance\pgf@yc by\pgf@sys@tonumber{\pgf@xb}\pgf@y% + % + % The orthogonal vector is (\pgf@yb,\pgf@xb) + % + % Setup transformation matrx (this is just to use the matrix + % inversion) + % + \pgfsettransform{{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{0pt}{0pt}}% + \pgftransforminvert% + \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xc}{\pgf@yc}}}% + }% +} + +\ifx\pgfpointintersectionoflines\forest@original@pgfpointintersectionoflines + \let\pgfpointintersectionoflines\forest@patched@pgfpointintersectionoflines +\fi +\long\def\@escapeif#1#2\fi{\fi#1} +\long\def\@escapeifif#1#2\fi#3\fi{\fi\fi#1} +\def\newloop#1{% + \count@=\escapechar + \escapechar=-1 + \expandafter\newloop@parse@loopname\string#1\newloop@end + \escapechar=\count@ +}% +{\lccode`7=`l \lccode`8=`o \lccode`9=`p + \lowercase{\gdef\newloop@parse@loopname#17889#2\newloop@end{% + \edef\newloop@marshal{% + \noexpand\csdef{#1loop#2}####1\expandafter\noexpand\csname #1repeat#2\endcsname{% + \noexpand\csdef{#1iterate#2}{####1\relax\noexpand\expandafter\expandafter\noexpand\csname#1iterate#2\endcsname\noexpand\fi}% + \expandafter\noexpand\csname#1iterate#2\endcsname + \let\expandafter\noexpand\csname#1iterate#2\endcsname\relax + }% + }% + \newloop@marshal + }% + }% +}% +\newloop\forest@loop +\newloop\forest@loopa +\newloop\forest@loopb +\newloop\forest@loopc +\newloop\forest@sort@loop +\newloop\forest@sort@loopA +\newdimen\forest@temp@dimen +\newcount\forest@temp@count +\newcount\forest@n +\newif\ifforest@temp +\newcount\forest@temp@global@count +\def\apptotoks#1#2{\expandafter#1\expandafter{\the#1#2}} +\long\def\lapptotoks#1#2{\expandafter#1\expandafter{\the#1#2}} +\def\eapptotoks#1#2{\edef\pot@temp{#2}\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\expandafter\the\expandafter#1\pot@temp}} +\def\pretotoks#1#2{\toks@={#2}\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\expandafter\the\expandafter\toks@\the#1}} +\def\epretotoks#1#2{\edef\pot@temp{#2}\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\pot@temp\the#1}} +\def\gapptotoks#1#2{\expandafter\global\expandafter#1\expandafter{\the#1#2}} +\def\xapptotoks#1#2{\edef\pot@temp{#2}\expandafter\expandafter\expandafter\global\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\expandafter\the\expandafter#1\pot@temp}} +\def\gpretotoks#1#2{\toks@={#2}\expandafter\expandafter\expandafter\global\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\expandafter\the\expandafter\toks@\the#1}} +\def\xpretotoks#1#2{\edef\pot@temp{#2}\expandafter\expandafter\expandafter\global\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\pot@temp\the#1}} +\def\expandnumberarg#1#2{\expandafter#1\expandafter{\number#2}} +\def\expandtwonumberargs#1#2#3{% + \expandafter\expandtwonumberargs@\expandafter#1\expandafter{\number#3}{#2}} +\def\expandtwonumberargs@#1#2#3{% + \expandafter#1\expandafter{\number#3}{#2}} +\def\expandthreenumberargs#1#2#3#4{% + \expandafter\expandthreenumberargs@\expandafter#1\expandafter{\number#4}{#2}{#3}} +\def\expandthreenumberargs@#1#2#3#4{% + \expandafter\expandthreenumberargs@@\expandafter#1\expandafter{\number#4}{#2}{#3}} +\def\expandthreenumberargs@@#1#2#3#4{% + \expandafter#1\expandafter{\number#4}{#2}{#3}} +\def\forest@convert@others@to@underscores#1#2{% + \def\forest@cotu@result{}% + \forest@cotu#1\forest@end + \let#2\forest@cotu@result +} +\def\forest@cotu{% + \futurelet\forest@cotu@nextchar\forest@cotu@checkforspace +} +\def\forest@cotu@checkforspace{% + \expandafter\ifx\space\forest@cotu@nextchar + \let\forest@cotu@next\forest@cotu@havespace + \else + \let\forest@cotu@next\forest@cotu@nospace + \fi + \forest@cotu@next +} +\def\forest@cotu@havespace#1{% + \appto\forest@cotu@result{_}% + \forest@cotu#1% +} +\def\forest@cotu@nospace{% + \ifx\forest@cotu@nextchar\forest@end + \@escapeif\@gobble + \else + \@escapeif\forest@cotu@nospaceB + \fi +} +\def\forest@cotu@nospaceB{% + \ifcat\forest@cotu@nextchar a% + \let\forest@cotu@next\forest@cotu@have@alphanum + \else + \ifcat\forest@cotu@nextchar 0% + \let\forest@cotu@next\forest@cotu@have@alphanum + \else + \let\forest@cotu@next\forest@cotu@haveother + \fi + \fi + \forest@cotu@next +} +\def\forest@cotu@have@alphanum#1{% + \appto\forest@cotu@result{#1}% + \forest@cotu +} +\def\forest@cotu@haveother#1{% + \appto\forest@cotu@result{_}% + \forest@cotu +} +\def\forest@listedel#1#2{% #1 = list, #2 = item + \edef\forest@marshal{\noexpand\forest@listdel\noexpand#1{#2}}% + \forest@marshal +} +\def\forest@listcsdel#1#2{% + \expandafter\forest@listdel\csname #1\endcsname{#2}% +} +\def\forest@listcsedel#1#2{% + \expandafter\forest@listedel\csname #1\endcsname{#2}% +} +\edef\forest@restorelistsepcatcode{\noexpand\catcode`|\the\catcode`|\relax}% +\catcode`\|=3 +\gdef\forest@listdel#1#2{% + \def\forest@listedel@A##1|#2|##2\forest@END{% + \forest@listedel@B##1|##2\forest@END%| + }% + \def\forest@listedel@B|##1\forest@END{%| + \def#1{##1}% + }% + \expandafter\forest@listedel@A\expandafter|#1\forest@END%| +} +\forest@restorelistsepcatcode +\def\forest@strip@braces#1{% + \forest@strip@braces@A#1\forest@strip@braces@preend\forest@strip@braces@end +} +\def\forest@strip@braces@A#1#2\forest@strip@braces@end{% + #1\ifx\forest@strip@braces@preend#2\else\@escapeif{\forest@strip@braces@A#2\forest@strip@braces@end}\fi +} +\def\forest@sort#1#2#3#4#5{% + \let\forest@sort@cmp#1\relax + \let\forest@sort@let#2\relax + \let\forest@sort@direction#3\relax + \forest@@sort{#4}{#5}% +} +\def\forest@quicksort@minarraylength{10000} +\def\forest@@sort#1#2{% + \ifnum#1<#2\relax\@escapeif{% + \forest@sort@m=#2 + \advance\forest@sort@m -#1 + \ifnum\forest@sort@m>\forest@quicksort@minarraylength\relax\@escapeif{% + \forest@quicksort{#1}{#2}% + }\else\@escapeif{% + \forest@insertionsort{#1}{#2}% + }\fi + }\fi +} +\newcount\forest@sort@m\newcount\forest@sort@k\newcount\forest@sort@p +\def\forest@sort@ascending{>} +\def\forest@sort@descending{<} +\def\forest@sort@cmp{% + \PackageError{sort}{You must define forest@sort@cmp function before calling + sort}{The macro must take two arguments, indices of the array + elements to be compared, and return '=' if the elements are equal + and '>'/'<' if the first is greater /less than the secong element.}% +} +\def\forest@sort@cmp@gt{\def\forest@sort@cmp@result{>}} +\def\forest@sort@cmp@lt{\def\forest@sort@cmp@result{<}} +\def\forest@sort@cmp@eq{\def\forest@sort@cmp@result{=}} +\def\forest@sort@let{% + \PackageError{sort}{You must define forest@sort@let function before calling + sort}{The macro must take two arguments, indices of the array: + element 2 must be copied onto element 1.}% +} +\def\forest@quicksort#1#2{% + \forest@sort@m=#2 + \advance\forest@sort@m -#1 + \ifodd\forest@sort@m\relax\advance\forest@sort@m1 \fi + \divide\forest@sort@m 2 + \advance\forest@sort@m #1 + \forest@sort@cmp{#1}{#2}% + \if\forest@sort@cmp@result=% + \forest@sort@p=#1 + \else + \if\forest@sort@cmp@result>% + \forest@sort@p=#1\relax + \else + \forest@sort@p=#2\relax + \fi + \forest@sort@cmp{\the\forest@sort@p}{\the\forest@sort@m}% + \if\forest@sort@cmp@result<% + \else + \forest@sort@p=\the\forest@sort@m + \fi + \fi + \forest@sort@xch{#1}{\the\forest@sort@p}% + \forest@sort@m=#1\relax + \forest@sort@k=#1\relax + \forest@sort@loop + \ifnum\forest@sort@k<#2\relax + \advance\forest@sort@k 1 + \forest@sort@cmp{#1}{\the\forest@sort@k}% + \ifx\forest@sort@direction\forest@sort@cmp@result + \advance\forest@sort@m 1 + \forest@sort@xch{\the\forest@sort@m}{\the\forest@sort@k} + \fi + \forest@sort@repeat + \forest@sort@xch{#1}{\the\forest@sort@m}% + \forest@sort@k=\forest@sort@m + \advance\forest@sort@k -1 + \advance\forest@sort@m 1 + \edef\forest@sort@marshal{% + \noexpand\forest@@sort{#1}{\the\forest@sort@k}% + \noexpand\forest@@sort{\the\forest@sort@m}{#2}% + }% + \forest@sort@marshal +} +\def\forest@sort@xch#1#2{% + \forest@sort@let{aux}{#1}% + \forest@sort@let{#1}{#2}% + \forest@sort@let{#2}{aux}% +} +\def\forest@insertionsort#1#2{% + \forest@sort@m=#1 + \edef\forest@insertionsort@low{#1}% + \forest@sort@loopA + \ifnum\forest@sort@m<#2 + \advance\forest@sort@m 1 + \forest@insertionsort@Qbody + \forest@sort@repeatA +} +\newif\ifforest@insertionsort@loop +\def\forest@insertionsort@Qbody{% + \forest@sort@let{aux}{\the\forest@sort@m}% + \forest@sort@k\forest@sort@m + \advance\forest@sort@k -1 + \forest@insertionsort@looptrue + \forest@sort@loop + \ifforest@insertionsort@loop + \forest@insertionsort@qbody + \forest@sort@repeat + \advance\forest@sort@k 1 + \forest@sort@let{\the\forest@sort@k}{aux}% +} +\def\forest@insertionsort@qbody{% + \forest@sort@cmp{\the\forest@sort@k}{aux}% + \ifx\forest@sort@direction\forest@sort@cmp@result\relax + \forest@sort@p=\forest@sort@k + \advance\forest@sort@p 1 + \forest@sort@let{\the\forest@sort@p}{\the\forest@sort@k}% + \advance\forest@sort@k -1 + \ifnum\forest@sort@k<\forest@insertionsort@low\relax + \forest@insertionsort@loopfalse + \fi + \else + \forest@insertionsort@loopfalse + \fi +} +\def\forest@sort@cmpnumcs#1#2{% + \ifnum\csname#1\endcsname>\csname#2\endcsname\relax + \forest@sort@cmp@gt + \else + \ifnum\csname#1\endcsname<\csname#2\endcsname\relax + \forest@sort@cmp@lt + \else + \forest@sort@cmp@eq + \fi + \fi +} +\def\forest@sort@cmpdimcs#1#2{% + \ifdim\csname#1\endcsname>\csname#2\endcsname\relax + \forest@sort@cmp@gt + \else + \ifdim\csname#1\endcsname<\csname#2\endcsname\relax + \forest@sort@cmp@lt + \else + \forest@sort@cmp@eq + \fi + \fi +} +\def\forest@sort@cmptwodimcs#1#2#3#4{% + \ifdim\csname#1\endcsname>\csname#3\endcsname\relax + \forest@sort@cmp@gt + \else + \ifdim\csname#1\endcsname<\csname#3\endcsname\relax + \forest@sort@cmp@lt + \else + \ifdim\csname#2\endcsname>\csname#4\endcsname\relax + \forest@sort@cmp@gt + \else + \ifdim\csname#2\endcsname<\csname#4\endcsname\relax + \forest@sort@cmp@lt + \else + \forest@sort@cmp@eq + \fi + \fi + \fi + \fi +} +\def\forest@reversearray#1#2#3{% + \let\forest@sort@let#1% + \c@pgf@countc=#2 + \c@pgf@countd=#3 + \advance\c@pgf@countd -1 + \forest@loopa + \ifnum\c@pgf@countc<\c@pgf@countd\relax + \forest@sort@xch{\the\c@pgf@countc}{\the\c@pgf@countd}% + \advance\c@pgf@countc 1 + \advance\c@pgf@countd -1 + \forest@repeata +} +\def\bracketset#1{\pgfqkeys{/bracket}{#1}}% +\bracketset{% + /bracket/.is family, + /handlers/.let/.style={\pgfkeyscurrentpath/.code={\let#1##1}}, + opening bracket/.let=\bracket@openingBracket, + closing bracket/.let=\bracket@closingBracket, + action character/.let=\bracket@actionCharacter, + opening bracket=[, + closing bracket=], + action character, + new node/.code n args={3}{% #1=preamble, #2=node spec, #3=cs receiving the id + \forest@node@new#3% + \forestOset{#3}{given options}{content'=#2}% + \ifblank{#1}{}{% + \forestOpreto{#3}{given options}{#1,}% + }% + }, + set afterthought/.code 2 args={% #1=node id, #2=afterthought + \ifblank{#2}{}{\forestOappto{#1}{given options}{,afterthought={#2}}}% + } +} +\newtoks\bracket@content +\newtoks\bracket@afterthought +\def\bracketParse#1#2={% + \def\bracketEndParsingHook{#1}% + \def\bracket@saveRootNodeTo{#2}% + \bracket@content={}% + \bracket@afterthought={}% + \let\bracket@state\bracket@state@starting + \bracket@ignorespacestrue + \bracket@expandtokensfalse + \def\bracket@parentNode{0}% + \def\bracket@rootNode{0}% + \def\bracket@newNode{0}% + \def\bracket@afterthoughtNode{0}% + \bracket@Parse +} +\def\bracketResume{\bracket@Parse}% +\def\bracket@Parse{% + \futurelet\bracket@next@token\bracket@Parse@checkForSpace +} +\def\bracket@Parse@checkForSpace{% + \expandafter\ifx\space\bracket@next@token\@escapeif{% + \ifbracket@ignorespaces\else + \bracket@haveSpacetrue + \fi + \expandafter\bracket@Parse\romannumeral-`0% + }\else\@escapeif{% + \bracket@Parse@maybeexpand + }\fi +} +\newif\ifbracket@expandtokens +\def\bracket@Parse@maybeexpand{% + \ifbracket@expandtokens\@escapeif{% + \expandafter\bracket@Parse@peekAhead\romannumeral-`0% + }\else\@escapeif{% + \bracket@Parse@peekAhead + }\fi +} +\def\bracket@Parse@peekAhead{% + \futurelet\bracket@next@token\bracket@Parse@checkForTeXGroup +} +\def\bracket@Parse@checkForTeXGroup{% + \ifx\bracket@next@token\bgroup% + \@escapeif{\bracket@Parse@appendGroup}% + \else + \@escapeif{\bracket@Parse@token}% + \fi +} +\long\def\bracket@Parse@token#1{% + \ifx#1\bracket@openingBracket + \@escapeif{\bracket@Parse@openingBracketFound}% + \else + \@escapeif{% + \ifx#1\bracket@closingBracket + \@escapeif{\bracket@Parse@closingBracketFound}% + \else + \@escapeif{% + \ifx#1\bracket@actionCharacter + \@escapeif{\futurelet\bracket@next@token\bracket@Parse@actionCharacterFound}% + \else + \@escapeif{\bracket@Parse@appendToken#1}% + \fi + }% + \fi + }% + \fi +} +\newif\ifbracket@haveSpace +\newif\ifbracket@ignorespaces +\def\bracket@Parse@appendSpace{% + \ifbracket@haveSpace + \ifcase\bracket@state\relax + \eapptotoks\bracket@content\space + \or + \eapptotoks\bracket@afterthought\space + \or + \eapptotoks\bracket@afterthought\space + \fi + \bracket@haveSpacefalse + \fi +} +\long\def\bracket@Parse@appendToken#1{% + \bracket@Parse@appendSpace + \ifcase\bracket@state\relax + \lapptotoks\bracket@content{#1}% + \or + \lapptotoks\bracket@afterthought{#1}% + \or + \lapptotoks\bracket@afterthought{#1}% + \fi + \bracket@ignorespacesfalse + \bracket@Parse +} +\def\bracket@Parse@appendGroup#1{% + \ifcase\bracket@state\relax + \apptotoks\bracket@content{{#1}}% + \or + \apptotoks\bracket@afterthought{{#1}}% + \or + \apptotoks\bracket@afterthought{{#1}}% + \fi + \bracket@ignorespacesfalse + \bracket@Parse +} +\def\bracket@state@inContent{0} +\def\bracket@state@inAfterthought{1} +\def\bracket@state@starting{2} +\def\bracket@Parse@openingBracketFound{% + \bracket@haveSpacefalse + \ifcase\bracket@state\relax% in content [ ... [ + \@escapeif{% + \bracket@createNode + \ifnum\bracket@parentNode=0 \else + \forest@node@Append{\bracket@parentNode}{\bracket@newNode}% + \fi + \let\bracket@parentNode\bracket@newNode + \bracket@Parse + }% + \or % in afterthought ] ... [ + \@escapeif{% + \bracket@addAfterthought + \let\bracket@state\bracket@state@inContent + \bracket@Parse + }% + \else % starting + \@escapeif{% + \let\bracket@state\bracket@state@inContent + \bracket@Parse + }% + \fi +} +\def\bracket@Parse@closingBracketFound{% + \bracket@haveSpacefalse + \ifcase\bracket@state\relax % in content [ ... ] + \@escapeif{% + \bracket@createNode + \ifnum\bracket@parentNode=0 + \@escapeif\bracketEndParsingHook + \else + \@escapeif{% + \let\bracket@afterthoughtNode\bracket@newNode + \let\bracket@state\bracket@state@inAfterthought + \forest@node@Append{\bracket@parentNode}{\bracket@newNode}% + \bracket@Parse + }% + \fi + }% + \or % in afterthought ] ... ] + \@escapeif{% + \bracket@addAfterthought + \let\bracket@afterthoughtNode\bracket@parentNode + \edef\bracket@parentNode{\forestOve{\bracket@parentNode}{@parent}}% + \ifnum\bracket@parentNode=0 + \expandafter\bracketEndParsingHook + \else + \expandafter\bracket@Parse + \fi + }% + \else % starting + \PackageError{forest}{You're attempting to start a bracket representation + with a closing bracket}{}% + \fi +} +\def\bracket@Parse@actionCharacterFound{% + \ifx\bracket@next@token\bgroup\@escapeif{% + \bracket@Parse@action@expandgroup + }\else\@escapeif{% + \bracket@Parse@action@notagroup + }\fi +} +\def\bracket@Parse@action@expandgroup#1{% + \edef\bracket@Parse@action@expandgroup@macro{#1}% + \expandafter\bracket@Parse\bracket@Parse@action@expandgroup@macro +} +\let\bracket@action@fullyexpandCharacter+ +\let\bracket@action@dontexpandCharacter- +\let\bracket@action@executeCharacter! +\def\bracket@Parse@action@notagroup#1{% + \ifx#1\bracket@action@fullyexpandCharacter\@escapeif{% + \bracket@expandtokenstrue\bracket@Parse + }\else\@escapeif{% + \ifx#1\bracket@action@dontexpandCharacter\@escapeif{% + \bracket@expandtokensfalse\bracket@Parse + }\else\@escapeif{% + \ifx#10\@escapeif{% + \bracket@Parse@appendToken + }\else\@escapeif{% + \ifx#1\bracket@actionCharacter + \else\@escapeif{% + \expandafter\bracket@Parse#1% + }\fi + }\fi + }\fi + }\fi +} +\def\bracket@createNode{% + \ifnum\bracket@rootNode=0 + % root node + \bracketset{new node/.expanded=% + {\the\bracket@afterthought}% + {\the\bracket@content}% + \noexpand\bracket@newNode + }% + \bracket@afterthought={}% + \let\bracket@rootNode\bracket@newNode + \expandafter\let\bracket@saveRootNodeTo\bracket@newNode + \else + % other nodes + \bracketset{new node/.expanded=% + {}% + {\the\bracket@content}% + \noexpand\bracket@newNode + }% + \fi + \bracket@content={}% +} +\def\bracket@addAfterthought{% + \bracketset{% + set afterthought/.expanded={\bracket@afterthoughtNode}{\the\bracket@afterthought}% + }% + \bracket@afterthought={}% +} + % full expansion expands precisely to the value +\def\forestov#1{\expandafter\expandafter\expandafter\expandonce + \pgfkeysvalueof{/forest/@node/\forest@cn/#1}} + % full expansion expands all the way +\def\forestove#1{\pgfkeysvalueof{/forest/@node/\forest@cn/#1}} + % full expansion expands to the cs holding the value +\def\forestom#1{\expandafter\expandonce\expandafter{\pgfkeysvalueof{/forest/@node/\forest@cn/#1}}}\def\forestoget#1#2{\pgfkeysgetvalue{/forest/@node/\forest@cn/#1}{#2}} +\def\forestoget#1#2{\pgfkeysgetvalue{/forest/@node/\forest@cn/#1}{#2}} +\def\forestolet#1#2{\pgfkeyslet{/forest/@node/\forest@cn/#1}{#2}} +\def\forestoset#1#2{\pgfkeyssetvalue{/forest/@node/\forest@cn/#1}{#2}} +\def\forestoeset#1#2{% + \edef\forest@option@temp{% + \noexpand\pgfkeyssetvalue{/forest/@node/\forest@cn/#1}{#2}% + }\forest@option@temp +} +\def\forestoappto#1#2{% + \forestoeset{#1}{\forestov{#1}\unexpanded{#2}}% +} +\def\forestoifdefined#1#2#3{% + \pgfkeysifdefined{/forest/@node/\forest@cn/#1}{#2}{#3}% +} +\let\forestoption\forestov +\let\foresteoption\forestove +\def\forestOv#1#2{\expandafter\expandafter\expandafter\expandonce + \pgfkeysvalueof{/forest/@node/#1/#2}} +\def\forestOve#1#2{\pgfkeysvalueof{/forest/@node/#1/#2}} + % full expansion expands to the cs holding the value +\def\forestOm#1#2{\expandafter\expandonce\expandafter{\pgfkeysvalueof{/forest/@node/#1/#2}}} +\def\forestOget#1#2#3{\pgfkeysgetvalue{/forest/@node/#1/#2}{#3}} +\def\forestOget#1#2#3{\pgfkeysgetvalue{/forest/@node/#1/#2}{#3}} +\def\forestOlet#1#2#3{\pgfkeyslet{/forest/@node/#1/#2}{#3}} +\def\forestOset#1#2#3{\pgfkeyssetvalue{/forest/@node/#1/#2}{#3}} +\def\forestOeset#1#2#3{% + \edef\forestoption@temp{% + \noexpand\pgfkeyssetvalue{/forest/@node/#1/#2}{#3}% + }\forestoption@temp +} +\def\forestOappto#1#2#3{% + \forestOeset{#1}{#2}{\forestOv{#1}{#2}\unexpanded{#3}}% +} +\def\forestOeappto#1#2#3{% + \forestOeset{#1}{#2}{\forestOv{#1}{#2}#3}% +} +\def\forestOpreto#1#2#3{% + \forestOeset{#1}{#2}{\unexpanded{#3}\forestOv{#1}{#2}}% +} +\def\forestOepreto#1#2#3{% + \forestOeset{#1}{#2}{#3\forestOv{#1}{#2}}% +} +\def\forestOifdefined#1#2#3#4{% + \pgfkeysifdefined{/forest/@node/#1/#2}{#3}{#4}% +} +\def\forestOletO#1#2#3#4{% option #2 of node #1 <-- option #4 of node #3 + \forestOget{#3}{#4}\forestoption@temp + \forestOlet{#1}{#2}\forestoption@temp} +\def\forestOleto#1#2#3{% + \forestoget{#3}\forestoption@temp + \forestOlet{#1}{#2}\forestoption@temp} +\def\forestoletO#1#2#3{% + \forestOget{#2}{#3}\forestoption@temp + \forestolet{#1}\forestoption@temp} +\def\forestoleto#1#2{% + \forestoget{#2}\forestoption@temp + \forestolet{#1}\forestoption@temp} +\def\forest@node@init{% + \forestoset{@parent}{0}% + \forestoset{@previous}{0}% previous sibling + \forestoset{@next}{0}% next sibling + \forestoset{@first}{0}% primary child + \forestoset{@last}{0}% last child +} +\def\forestoinit#1{% + \pgfkeysgetvalue{/forest/#1}\forestoinit@temp + \forestolet{#1}\forestoinit@temp +} +\newcount\forest@node@maxid +\def\forest@node@new#1{% #1 = cs receiving the new node id + \advance\forest@node@maxid1 + \forest@fornode{\the\forest@node@maxid}{% + \forest@node@init + \forest@node@setname{node@\forest@cn}% + \forest@initializefromstandardnode + \edef#1{\forest@cn}% + }% +} +\let\forestoinit@orig\forestoinit +\def\forest@node@copy#1#2{% #1=from node id, cs receiving the new node id + \advance\forest@node@maxid1 + \def\forestoinit##1{\forestoletO{##1}{#1}{##1}}% + \forest@fornode{\the\forest@node@maxid}{% + \forest@node@init + \forest@node@setname{\forest@copy@name@template{\forestOve{#1}{name}}}% + \edef#2{\forest@cn}% + }% + \let\forestoinit\forestoinit@orig +} +\forestset{ + copy name template/.code={\def\forest@copy@name@template##1{#1}}, + copy name template/.default={node@\the\forest@node@maxid}, + copy name template +} +\def\forest@tree@copy#1#2{% #1=from node id, #2=cs receiving the new node id + \forest@node@copy{#1}\forest@node@copy@temp@id + \forest@fornode{\forest@node@copy@temp@id}{% + \expandafter\forest@tree@copy@\expandafter{\forest@node@copy@temp@id}{#1}% + \edef#2{\forest@cn}% + }% +} +\def\forest@tree@copy@#1#2{% + \forest@node@Foreachchild{#2}{% + \expandafter\forest@tree@copy\expandafter{\forest@cn}\forest@node@copy@temp@childid + \forest@node@Append{#1}{\forest@node@copy@temp@childid}% + }% +} +\def\forest@cn{0} +\forest@node@init +\def\forest@node@append#1{\expandtwonumberargs\forest@node@Append{\forest@cn}{#1}} +\def\forest@node@prepend#1{\expandtwonumberargs\forest@node@Insertafter{\forest@cn}{#1}{0}} +\def\forest@node@insertafter#1#2{% + \expandthreenumberargs\forest@node@Insertafter{\forest@cn}{#1}{#2}} +\def\forest@node@insertbefore#1#2{% + \expandthreenumberargs\forest@node@Insertafter{\forest@cn}{#1}{\forestOve{#2}{@previous}}% +} +\def\forest@node@remove{\expandnumberarg\forest@node@Remove{\forest@cn}} +\def\forest@node@Append#1#2{\expandtwonumberargs\forest@node@Append@{#1}{#2}} +\def\forest@node@Prepend#1#2{\expandtwonumberargs\forest@node@Insertafter{#1}{#2}{0}} +\def\forest@node@Insertafter#1#2#3{% #2 is inserted after #3 + \expandthreenumberargs\forest@node@Insertafter@{#1}{#2}{#3}% +} +\def\forest@node@Insertbefore#1#2#3{% #2 is inserted before #3 + \expandthreenumberargs\forest@node@Insertafter{#1}{#2}{\forestOve{#3}{@previous}}% +} +\def\forest@node@Remove#1{\expandnumberarg\forest@node@Remove@{#1}} +\def\forest@node@Insertafter@#1#2#3{% + \ifnum\forestOve{#2}{@parent}=0 + \else + \PackageError{forest}{Insertafter(#1,#2,#3): + node #2 already has a parent (\forestOve{#2}{@parent})}{}% + \fi + \ifnum#3=0 + \else + \ifnum#1=\forestOve{#3}{@parent} + \else + \PackageError{forest}{Insertafter(#1,#2,#3): node #1 is not the parent of the + intended sibling #3 (with parent \forestOve{#3}{@parent})}{}% + \fi + \fi + \forestOeset{#2}{@parent}{#1}% + \forestOeset{#2}{@previous}{#3}% + \ifnum#3=0 + \forestOget{#1}{@first}\forest@node@temp + \forestOeset{#1}{@first}{#2}% + \else + \forestOget{#3}{@next}\forest@node@temp + \forestOeset{#3}{@next}{#2}% + \fi + \forestOeset{#2}{@next}{\forest@node@temp}% + \ifnum\forest@node@temp=0 + \forestOeset{#1}{@last}{#2}% + \else + \forestOeset{\forest@node@temp}{@previous}{#2}% + \fi +} +\def\forest@node@Append@#1#2{% + \ifnum\forestOve{#2}{@parent}=0 + \else + \PackageError{forest}{Append(#1,#2): + node #2 already has a parent (\forestOve{#2}{@parent})}{}% + \fi + \forestOeset{#2}{@parent}{#1}% + \forestOget{#1}{@last}\forest@node@temp + \forestOeset{#1}{@last}{#2}% + \forestOeset{#2}{@previous}{\forest@node@temp}% + \ifnum\forest@node@temp=0 + \forestOeset{#1}{@first}{#2}% + \else + \forestOeset{\forest@node@temp}{@next}{#2}% + \fi +} +\def\forest@node@Remove@#1{% + \forestOget{#1}{@parent}\forest@node@temp@parent + \ifnum\forest@node@temp@parent=0 + \else + \forestOget{#1}{@previous}\forest@node@temp@previous + \forestOget{#1}{@next}\forest@node@temp@next + \ifnum\forest@node@temp@previous=0 + \forestOeset{\forest@node@temp@parent}{@first}{\forest@node@temp@next}% + \else + \forestOeset{\forest@node@temp@previous}{@next}{\forest@node@temp@next}% + \fi + \ifnum\forest@node@temp@next=0 + \forestOeset{\forest@node@temp@parent}{@last}{\forest@node@temp@previous}% + \else + \forestOeset{\forest@node@temp@next}{@previous}{\forest@node@temp@previous}% + \fi + \forestOset{#1}{@parent}{0}% + \forestOset{#1}{@previous}{0}% + \forestOset{#1}{@next}{0}% + \fi +} +\def\forest@forthis#1{% + \edef\forest@node@marshal{\unexpanded{#1}\def\noexpand\forest@cn}% + \expandafter\forest@node@marshal\expandafter{\forest@cn}% +} +\def\forest@fornode#1#2{% + \edef\forest@node@marshal{\edef\noexpand\forest@cn{#1}\unexpanded{#2}\def\noexpand\forest@cn}% + \expandafter\forest@node@marshal\expandafter{\forest@cn}% +} +\def\forest@fornode@ifexists#1#2{% + \edef\forest@node@temp{#1}% + \ifnum\forest@node@temp=0 + \else + \@escapeif{\expandnumberarg\forest@fornode{\forest@node@temp}{#2}}% + \fi +} +\def\forest@node@foreachchild#1{\forest@node@Foreachchild{\forest@cn}{#1}} +\def\forest@node@Foreachchild#1#2{% + \forest@fornode{\forestOve{#1}{@first}}{\forest@node@@forselfandfollowingsiblings{#2}}% +} +\def\forest@node@@forselfandfollowingsiblings#1{% + \ifnum\forest@cn=0 + \else + \forest@forthis{#1}% + \@escapeif{% + \edef\forest@cn{\forestove{@next}}% + \forest@node@@forselfandfollowingsiblings{#1}% + }% + \fi +} +\def\forest@node@foreach#1{\forest@node@Foreach{\forest@cn}{#1}} +\def\forest@node@Foreach#1#2{% + \forest@fornode{#1}{\forest@node@@foreach{#2}}% +} +\def\forest@node@@foreach#1{% + \forest@forthis{#1}% + \ifnum\forestove{@first}=0 + \else\@escapeif{% + \edef\forest@cn{\forestove{@first}}% + \forest@node@@forselfandfollowingsiblings{\forest@node@@foreach{#1}}% + }% + \fi +} +\def\forest@node@foreachdescendant#1{\forest@node@Foreachdescendant{\forest@cn}{#1}} +\def\forest@node@Foreachdescendant#1#2{% + \forest@node@Foreachchild{#1}{% + \forest@node@foreach{#2}% + }% +} +\def\forest@node@Compute@numeric@ts@info@#1{% + \forest@node@Foreach{#1}{\forest@node@@compute@numeric@ts@info}% + \ifnum\forestOve{#1}{@parent}=0 + \else + \fornode{#1}{\forest@node@@compute@numeric@ts@info@nbar}% + \fi + \forest@node@Foreachdescendant{#1}{\forest@node@@compute@numeric@ts@info@nbar}% +} +\def\forest@node@@compute@numeric@ts@info{% + \forestoset{n children}{0}% + % + \edef\forest@node@temp{\forestove{@previous}}% + \ifnum\forest@node@temp=0 + \forestoset{n}{1}% + \else + \forestoeset{n}{\number\numexpr\forestOve{\forest@node@temp}{n}+1}% + \fi + % + \edef\forest@node@temp{\forestove{@parent}}% + \ifnum\forest@node@temp=0 + \forestoset{n}{0}% + \forestoset{n'}{0}% + \forestoset{level}{0}% + \else + \forestOeset{\forest@node@temp}{n children}{% + \number\numexpr\forestOve{\forest@node@temp}{n children}+1% + }% + \forestoeset{level}{% + \number\numexpr\forestOve{\forest@node@temp}{level}+1% + }% + \fi +} +\def\forest@node@@compute@numeric@ts@info@nbar{% + \forestoeset{n'}{\number\numexpr\forestOve{\forestove{@parent}}{n children}-\forestove{n}+1}% +} +\def\forest@node@compute@numeric@ts@info#1{% + \expandnumberarg\forest@node@Compute@numeric@ts@info@{\forest@cn}% +} +\def\forest@node@Compute@numeric@ts@info#1{% + \expandnumberarg\forest@node@Compute@numeric@ts@info@{#1}% +} +\def\forest@node@rootid{% + \expandnumberarg\forest@node@Rootid{\forest@cn}% +} +\def\forest@node@Rootid#1{% #1=node + \ifnum\forestOve{#1}{@parent}=0 + #1% + \else + \@escapeif{\expandnumberarg\forest@node@Rootid{\forestOve{#1}{@parent}}}% + \fi +} +\def\forest@node@nthchildid#1{% #1=n + \ifnum#1<1 + 0% + \else + \expandnumberarg\forest@node@nthchildid@{\number\forestove{@first}}{#1}% + \fi +} +\def\forest@node@nthchildid@#1#2{% + \ifnum#1=0 + 0% + \else + \ifnum#2>1 + \@escapeifif{\expandtwonumberargs + \forest@node@nthchildid@{\forestOve{#1}{@next}}{\numexpr#2-1}}% + \else + #1% + \fi + \fi +} +\def\forest@node@nbarthchildid#1{% #1=n + \expandnumberarg\forest@node@nbarthchildid@{\number\forestove{@last}}{#1}% +} +\def\forest@node@nbarthchildid@#1#2{% + \ifnum#1=0 + 0% + \else + \ifnum#2>1 + \@escapeifif{\expandtwonumberargs + \forest@node@nbarthchildid@{\forestOve{#1}{@previous}}{\numexpr#2-1}}% + \else + #1% + \fi + \fi +} +\def\forest@node@nornbarthchildid#1{% + \ifnum#1>0 + \forest@node@nthchildid{#1}% + \else + \ifnum#1<0 + \forest@node@nbarthchildid{-#1}% + \else + \forest@node@nornbarthchildid@error + \fi + \fi +} +\def\forest@node@nornbarthchildid@error{% + \PackageError{forest}{In \string\forest@node@nornbarthchildid, n should !=0}{}% +} +\def\forest@node@previousleafid{% + \expandnumberarg\forest@node@Previousleafid{\forest@cn}% +} +\def\forest@node@Previousleafid#1{% + \ifnum\forestOve{#1}{@previous}=0 + \@escapeif{\expandnumberarg\forest@node@previousleafid@Goup{#1}}% + \else + \expandnumberarg\forest@node@previousleafid@Godown{\forestOve{#1}{@previous}}% + \fi +} +\def\forest@node@previousleafid@Goup#1{% + \ifnum\forestOve{#1}{@parent}=0 + \PackageError{forest}{get previous leaf: this is the first leaf}{}% + \else + \@escapeif{\expandnumberarg\forest@node@Previousleafid{\forestOve{#1}{@parent}}}% + \fi +} +\def\forest@node@previousleafid@Godown#1{% + \ifnum\forestOve{#1}{@last}=0 + #1% + \else + \@escapeif{\expandnumberarg\forest@node@previousleafid@Godown{\forestOve{#1}{@last}}}% + \fi +} +\def\forest@node@nextleafid{% + \expandnumberarg\forest@node@Nextleafid{\forest@cn}% +} +\def\forest@node@Nextleafid#1{% + \ifnum\forestOve{#1}{@next}=0 + \@escapeif{\expandnumberarg\forest@node@nextleafid@Goup{#1}}% + \else + \expandnumberarg\forest@node@nextleafid@Godown{\forestOve{#1}{@next}}% + \fi +} +\def\forest@node@nextleafid@Goup#1{% + \ifnum\forestOve{#1}{@parent}=0 + \PackageError{forest}{get next leaf: this is the last leaf}{}% + \else + \@escapeif{\expandnumberarg\forest@node@Nextleafid{\forestOve{#1}{@parent}}}% + \fi +} +\def\forest@node@nextleafid@Godown#1{% + \ifnum\forestOve{#1}{@first}=0 + #1% + \else + \@escapeif{\expandnumberarg\forest@node@nextleafid@Godown{\forestOve{#1}{@first}}}% + \fi +} +\def\forest@node@linearnextid{% + \ifnum\forestove{@first}=0 + \expandafter\forest@node@linearnextnotdescendantid + \else + \forestove{@first}% + \fi +} +\def\forest@node@linearnextnotdescendantid{% + \expandnumberarg\forest@node@Linearnextnotdescendantid{\forest@cn}% +} +\def\forest@node@Linearnextnotdescendantid#1{% + \ifnum\forestOve{#1}{@next}=0 + \@escapeif{\expandnumberarg\forest@node@Linearnextnotdescendantid{\forestOve{#1}{@parent}}}% + \else + \forestOve{#1}{@next}% + \fi +} +\def\forest@node@linearpreviousid{% + \ifnum\forestove{@previous}=0 + \forestove{@parent}% + \else + \forest@node@previousleafid + \fi +} +\def\forest@ifancestorof#1{% is the current node an ancestor of #1? Yes: #2, no: #3 + \expandnumberarg\forest@ifancestorof@{\forestOve{#1}{@parent}}% +} +\def\forest@ifancestorof@#1#2#3{% + \ifnum#1=0 + \def\forest@ifancestorof@next{\@secondoftwo}% + \else + \ifnum\forest@cn=#1 + \def\forest@ifancestorof@next{\@firstoftwo}% + \else + \def\forest@ifancestorof@next{\expandnumberarg\forest@ifancestorof@{\forestOve{#1}{@parent}}}% + \fi + \fi + \forest@ifancestorof@next{#2}{#3}% +} +\newloop\forest@nodewalk@loop +\forestset{ + @handlers@save@currentpath/.code={% + \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% + \let\forest@currentkey\pgfkeyscurrentkey + \pgfkeys@split@path + \edef\forest@currentpath{\pgfkeyscurrentpath}% + \let\forest@currentname\pgfkeyscurrentname + }, + /handlers/.step 0 args/.style={ + /forest/@handlers@save@currentpath, + \forest@currentkey/.code={#1\forestset{node walk/every step}}, + /forest/for \forest@currentname/.style/.expanded={% + for={\forest@currentname}{####1}% + } + }, + /handlers/.step 1 arg/.style={% + /forest/@handlers@save@currentpath, + \forest@currentkey/.code={#1\forestset{node walk/every step}}, + /forest/for \forest@currentname/.style 2 args/.expanded={% + for={\forest@currentname=####1}{####2}% + } + }, + node walk/.code={% + \forestset{% + node walk/before walk,% + node walk/.cd, + #1,% + /forest/.cd, + node walk/after walk + }% + }, + for/.code 2 args={% + \forest@forthis{% + \pgfkeysalso{% + node walk/before walk/.style={},% + node walk/every step/.style={},% + node walk/after walk/.style={/forest,if id=0{}{#2}},% + %node walk/after walk/.style={#2},% + node walk={#1}% + }% + }% + }, + node walk/.cd, + before walk/.code={}, + every step/.code={}, + after walk/.code={}, + current/.step 0 args={}, + current/.default=1, + next/.step 0 args={\edef\forest@cn{\forestove{@next}}}, + next/.default=1, + previous/.step 0 args={\edef\forest@cn{\forestove{@previous}}}, + previous/.default=1, + parent/.step 0 args={\edef\forest@cn{\forestove{@parent}}}, + parent/.default=1, + first/.step 0 args={\edef\forest@cn{\forestove{@first}}}, + first/.default=1, + last/.step 0 args={\edef\forest@cn{\forestove{@last}}}, + last/.default=1, + n/.step 1 arg={% + \def\forest@nodewalk@temp{#1}% + \ifx\forest@nodewalk@temp\pgfkeysnovalue@text + \edef\forest@cn{\forestove{@next}}% + \else + \edef\forest@cn{\forest@node@nthchildid{#1}}% + \fi + }, + n'/.step 1 arg={\edef\forest@cn{\forest@node@nbarthchildid{#1}}}, + sibling/.step 0 args={% + \edef\forest@cn{% + \ifnum\forestove{@previous}=0 + \forestove{@next}% + \else + \forestove{@previous}% + \fi + }% + }, + previous leaf/.step 0 args={\edef\forest@cn{\forest@node@previousleafid}}, + previous leaf/.default=1, + next leaf/.step 0 args={\edef\forest@cn{\forest@node@nextleafid}}, + next leaf/.default=1, + linear next/.step 0 args={\edef\forest@cn{\forest@node@linearnextid}}, + linear previous/.step 0 args={\edef\forest@cn{\forest@node@linearpreviousid}}, + first leaf/.step 0 args={% + \forest@nodewalk@loop + \edef\forest@cn{\forestove{@first}}% + \unless\ifnum\forestove{@first}=0 + \forest@nodewalk@repeat + }, + last leaf/.step 0 args={% + \forest@nodewalk@loop + \edef\forest@cn{\forestove{@last}}% + \unless\ifnum\forestove{@last}=0 + \forest@nodewalk@repeat + }, + to tier/.step 1 arg={% + \def\forest@nodewalk@giventier{#1}% + \forest@nodewalk@loop + \forestoget{tier}\forest@nodewalk@tier + \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier + \forestoget{@parent}\forest@cn + \forest@nodewalk@repeat + }, + next on tier/.step 0 args={\forest@nodewalk@nextontier}, + next on tier/.default=1, + previous on tier/.step 0 args={\forest@nodewalk@previousontier}, + previous on tier/.default=1, + name/.step 1 arg={\edef\forest@cn{\forest@node@Nametoid{#1}}}, + root/.step 0 args={\edef\forest@cn{\forest@node@rootid}}, + root'/.step 0 args={\edef\forest@cn{\forest@root}}, + id/.step 1 arg={\edef\forest@cn{#1}}, + % maybe it's not wise to have short-step sequences and names potentially clashing + % .unknown/.code={% + % \forest@node@Ifnamedefined{\pgfkeyscurrentname}% + % {\pgfkeysalso{name=\pgfkeyscurrentname}}% + % {\expandafter\forest@nodewalk@shortsteps\pgfkeyscurrentname\forest@nodewalk@endshortsteps}% + % }, + .unknown/.code={% + \expandafter\forest@nodewalk@shortsteps\pgfkeyscurrentname\forest@nodewalk@endshortsteps + }, + node walk/.style={/forest/node walk={#1}}, + trip/.code={\forest@forthis{\pgfkeysalso{#1}}}, + group/.code={\forest@go{#1}\forestset{node walk/every step}}, + % repeat is taken later from /forest/repeat + p/.style={previous=1}, + %n/.style={next=1}, % defined in "long" n + u/.style={parent=1}, + s/.style={sibling}, + c/.style={current=1}, + r/.style={root}, + P/.style={previous leaf=1}, + N/.style={next leaf=1}, + F/.style={first leaf=1}, + L/.style={last leaf=1}, + >/.style={next on tier=1}, + 1 \pgfmathparse{#2}\let\forest@wrap@arg@ii\pgfmathresult\fi + \ifnum#9>2 \pgfmathparse{#3}\let\forest@wrap@arg@iii\pgfmathresult\fi + \ifnum#9>3 \pgfmathparse{#4}\let\forest@wrap@arg@iv\pgfmathresult\fi + \ifnum#9>4 \pgfmathparse{#5}\let\forest@wrap@arg@v\pgfmathresult\fi + \ifnum#9>5 \pgfmathparse{#6}\let\forest@wrap@arg@vi\pgfmathresult\fi + \ifnum#9>6 \pgfmathparse{#7}\let\forest@wrap@arg@vii\pgfmathresult\fi + \ifnum#9>7 \pgfmathparse{#8}\let\forest@wrap@arg@viii\pgfmathresult\fi + \edef\forest@wrap@args{% + {\expandonce\forest@wrap@arg@i} + \ifnum#9>1 {\expandonce\forest@wrap@arg@ii}\fi + \ifnum#9>2 {\expandonce\forest@wrap@arg@iii}\fi + \ifnum#9>3 {\expandonce\forest@wrap@arg@iv}\fi + \ifnum#9>4 {\expandonce\forest@wrap@arg@v}\fi + \ifnum#9>5 {\expandonce\forest@wrap@arg@vi}\fi + \ifnum#9>6 {\expandonce\forest@wrap@arg@vii}\fi + \ifnum#9>7 {\expandonce\forest@wrap@arg@viii}\fi + }% +} +\def\forest@wrap@n@pgfmath@do#1#2{% + \ifcase#2\relax + \or\def\forest@wrap@code##1{#1}% + \or\def\forest@wrap@code##1##2{#1}% + \or\def\forest@wrap@code##1##2##3{#1}% + \or\def\forest@wrap@code##1##2##3##4{#1}% + \or\def\forest@wrap@code##1##2##3##4##5{#1}% + \or\def\forest@wrap@code##1##2##3##4##5##6{#1}% + \or\def\forest@wrap@code##1##2##3##4##5##6##7{#1}% + \or\def\forest@wrap@code##1##2##3##4##5##6##7##8{#1}% + \fi + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\forest@wrapped\expandafter\expandafter\expandafter{\expandafter\forest@wrap@code\forest@wrap@args}% + \pgfkeysalso{\pgfkeyscurrentpath/.expand once=\forest@wrapped}% +} +\def\forest@node@setname#1{% + \forestoeset{name}{#1}% + \csedef{forest@id@of@#1}{\forest@cn}% +} +\def\forest@node@Nametoid#1{% #1 = name + \csname forest@id@of@#1\endcsname +} +\def\forest@node@Ifnamedefined#1{% #1 = name, #2=true,#3=false + \ifcsname forest@id@of@#1\endcsname + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} +\def\forest@node@setalias#1{% + \csedef{forest@id@of@#1}{\forest@cn}% +} +\def\forest@node@Setalias#1#2{% + \csedef{forest@id@of@#2}{#1}% +} +\forestset{ + TeX/.code={#1}, + TeX'/.code={\appto\forest@externalize@loadimages{#1}#1}, + TeX''/.code={\appto\forest@externalize@loadimages{#1}}, + declare toks={name}{}, + name/.code={% override the default setter + \forest@node@setname{#1}% + }, + alias/.code={\forest@node@setalias{#1}}, + declare autowrapped toks={content}{}, + declare count={grow}{270}, + TeX={% a hack for grow-reversed connection, and compass-based grow specification + \pgfkeysgetvalue{/forest/grow/.@cmd}\forest@temp + \pgfkeyslet{/forest/grow@@/.@cmd}\forest@temp + }, + grow/.style={grow@={#1},reversed=0}, + grow'/.style={grow@={#1},reversed=1}, + grow''/.style={grow@={#1}}, + grow@/.is choice, + grow@/east/.style={/forest/grow@@=0}, + grow@/north east/.style={/forest/grow@@=45}, + grow@/north/.style={/forest/grow@@=90}, + grow@/north west/.style={/forest/grow@@=135}, + grow@/west/.style={/forest/grow@@=180}, + grow@/south west/.style={/forest/grow@@=225}, + grow@/south/.style={/forest/grow@@=270}, + grow@/south east/.style={/forest/grow@@=315}, + grow@/.unknown/.code={\let\forest@temp@grow\pgfkeyscurrentname + \pgfkeysalso{/forest/grow@@/.expand once=\forest@temp@grow}}, + declare boolean={reversed}{0}, + declare toks={parent anchor}{}, + declare toks={child anchor}{}, + declare toks={anchor}{base}, + declare toks={calign}{midpoint}, + TeX={% + \pgfkeysgetvalue{/forest/calign/.@cmd}\forest@temp + \pgfkeyslet{/forest/calign'/.@cmd}\forest@temp + }, + calign/.is choice, + calign/child/.style={calign'=child}, + calign/first/.style={calign'=child,calign primary child=1}, + calign/last/.style={calign'=child,calign primary child=-1}, + calign with current/.style={for parent/.wrap pgfmath arg={calign=child,calign primary child=##1}{n}}, + calign with current edge/.style={for parent/.wrap pgfmath arg={calign=child edge,calign primary child=##1}{n}}, + calign/child edge/.style={calign'=child edge}, + calign/midpoint/.style={calign'=midpoint}, + calign/center/.style={calign'=midpoint,calign primary child=1,calign secondary child=-1}, + calign/edge midpoint/.style={calign'=edge midpoint}, + calign/fixed angles/.style={calign'=fixed angles}, + calign/fixed edge angles/.style={calign'=fixed edge angles}, + calign/.unknown/.code={\PackageError{forest}{unknown calign '\pgfkeyscurrentname'}{}}, + declare count={calign primary child}{1}, + declare count={calign secondary child}{-1}, + declare count={calign primary angle}{-35}, + declare count={calign secondary angle}{35}, + calign child/.style={calign primary child={#1}}, + calign angle/.style={calign primary angle={-#1},calign secondary angle={#1}}, + declare toks={tier}{}, + declare toks={fit}{tight}, + declare boolean={ignore}{0}, + declare boolean={ignore edge}{0}, + no edge/.style={edge'={},ignore edge}, + declare keylist={edge}{draw}, + declare toks={edge path}{% + \noexpand\path[\forestoption{edge}]% + (\forestOve{\forestove{@parent}}{name}.parent anchor)--(\forestove{name}.child anchor)\forestoption{edge label};}, + triangle/.style={edge path={% + \noexpand\path[\forestoption{edge}]% + (\forestove{name}.north east)--(\forestOve{\forestove{@parent}}{name}.south)--(\forestove{name}.north west)--(\forestove{name}.north east)\forestoption{edge label};}}, + declare toks={edge label}{}, + declare boolean={phantom}{0}, + baseline/.style={alias={forest@baseline@node}}, + declare readonly count={n}, + declare readonly count={n'}, + declare readonly count={n children}, + declare readonly count={level}, + declare dimen=x{}, + declare dimen=y{}, + declare dimen={s}{0pt}, + declare dimen={l}{6ex}, % just in case: should be set by the calibration + declare dimen={s sep}{0.6666em}, + declare dimen={l sep}{1ex}, % just in case: calibration! + declare keylist={node options}{}, + declare toks={tikz}{}, + afterthought/.style={tikz+={#1}}, + declare toks={tikz preamble}{}, + label/.style={tikz={\path[late options={% + name=\forestoption{name},label={#1}}];}}, + pin/.style={tikz={\path[late options={% + name=\forestoption{name},pin={#1}}];}}, + declare toks={content format}{\forestoption{content}}, + declare toks={node format}{% + \noexpand\node + [\forestoption{node options},anchor=\forestoption{anchor}]% + (\forestoption{name})% + {\foresteoption{content format}};% + }, + tabular@environment/.style={content format={% + \noexpand\begin{tabular}[\forestoption{base}]{\forestoption{align}}% + \forestoption{content}% + \noexpand\end{tabular}% + }}, + declare toks={align}{}, + TeX={\pgfkeysgetvalue{/forest/align/.@cmd}\forest@temp + \pgfkeyslet{/forest/align'/.@cmd}\forest@temp}, + align/.is choice, + align/.unknown/.code={% + \edef\forest@marshal{% + \noexpand\pgfkeysalso{% + align'={\pgfkeyscurrentname},% + tabular@environment + }% + }\forest@marshal + }, + align/center/.style={align'={@{}c@{}},tabular@environment}, + align/left/.style={align'={@{}l@{}},tabular@environment}, + align/right/.style={align'={@{}r@{}},tabular@environment}, + declare toks={base}{t}, + TeX={\pgfkeysgetvalue{/forest/base/.@cmd}\forest@temp + \pgfkeyslet{/forest/base'/.@cmd}\forest@temp}, + base/.is choice, + base/top/.style={base'=t}, + base/bottom/.style={base'=b}, + base/.unknown/.style={base'/.expand once=\pgfkeyscurrentname}, + .unknown/.code={% + \expandafter\pgfutil@in@\expandafter.\expandafter{\pgfkeyscurrentname}% + \ifpgfutil@in@ + \expandafter\forest@relatednode@option@setter\pgfkeyscurrentname=#1\forest@END + \else + \edef\forest@marshal{% + \noexpand\pgfkeysalso{node options={\pgfkeyscurrentname=\unexpanded{#1}}}% + }\forest@marshal + \fi + }, + get node boundary/.code={% + \forestoget{boundary}\forest@node@boundary + \def#1{}% + \forest@extendpath#1\forest@node@boundary{\pgfpoint{\forestove{x}}{\forestove{y}}}% + }, + % get min l tree boundary/.code={% + % \forest@get@tree@boundary{negative}{\the\numexpr\forestove{grow}-90\relax}#1}, + % get max l tree boundary/.code={% + % \forest@get@tree@boundary{positive}{\the\numexpr\forestove{grow}-90\relax}#1}, + get min s tree boundary/.code={% + \forest@get@tree@boundary{negative}{\forestove{grow}}#1}, + get max s tree boundary/.code={% + \forest@get@tree@boundary{positive}{\forestove{grow}}#1}, + fit to tree/.code={% + \pgfkeysalso{% + /forest/get min s tree boundary=\forest@temp@negative@boundary, + /forest/get max s tree boundary=\forest@temp@positive@boundary + }% + \edef\forest@temp@boundary{\expandonce{\forest@temp@negative@boundary}\expandonce{\forest@temp@positive@boundary}}% + \forest@path@getboundingrectangle@xy\forest@temp@boundary + \pgfkeysalso{inner sep=0,fit/.expanded={(\the\pgf@xa,\the\pgf@ya)(\the\pgf@xb,\the\pgf@yb)}}% + }, + use as bounding box/.style={% + before drawing tree={ + tikz+/.expanded={% + \noexpand\pgfresetboundingbox + \noexpand\useasboundingbox + ($(.anchor)+(\forestoption{min x},\forestoption{min y})$) + rectangle + ($(.anchor)+(\forestoption{max x},\forestoption{max y})$) + ; + } + } + }, + use as bounding box'/.style={% + before drawing tree={ + tikz+/.expanded={% + \noexpand\pgfresetboundingbox + \noexpand\useasboundingbox + ($(.anchor)+(\forestoption{min x}+\pgfkeysvalueof{/pgf/outer xsep}/2+\pgfkeysvalueof{/pgf/inner xsep},\forestoption{min y}+\pgfkeysvalueof{/pgf/outer ysep}/2+\pgfkeysvalueof{/pgf/inner ysep})$) + rectangle + ($(.anchor)+(\forestoption{max x}-\pgfkeysvalueof{/pgf/outer xsep}/2-\pgfkeysvalueof{/pgf/inner xsep},\forestoption{max y}-\pgfkeysvalueof{/pgf/outer ysep}/2-\pgfkeysvalueof{/pgf/inner ysep})$) + ; + } + } + }, +}% +\def\forest@get@tree@boundary#1#2#3{%#1=pos/neg,#2=grow,#3=receiving cs + \def#3{}% + \forest@node@getedge{#1}{#2}\forest@temp@boundary + \forest@extendpath#3\forest@temp@boundary{\pgfpoint{\forestove{x}}{\forestove{y}}}% +} +\def\forest@setter@node{\forest@cn}% +\def\forest@relatednode@option@setter#1.#2=#3\forest@END{% + \forest@forthis{% + \forest@nameandgo{#1}% + \let\forest@setter@node\forest@cn + }% + \pgfkeysalso{#2={#3}}% + \def\forest@setter@node{\forest@cn}% +}% +\forestset{ + for tree/.code={\forest@node@foreach{\pgfkeysalso{#1}}}, + if/.code n args={3}{% + \pgfmathparse{#1}% + \ifnum\pgfmathresult=0 \pgfkeysalso{#3}\else\pgfkeysalso{#2}\fi + }, + where/.style n args={3}{for tree={if={#1}{#2}{#3}}}, + for descendants/.code={\forest@node@foreachdescendant{\pgfkeysalso{#1}}}, + for all next/.style={for next={#1,for all next={#1}}}, + for all previous/.style={for previous={#1,for all previous={#1}}}, + for siblings/.style={for all previous={#1},for all next={#1}}, + for ancestors/.style={for parent={#1,for ancestors={#1}}}, + for ancestors'/.style={#1,for ancestors={#1}}, + for children/.code={\forest@node@foreachchild{\pgfkeysalso{#1}}}, + for c-commanded={for sibling={for tree={#1}}}, + for c-commanders={for sibling={#1},for parent={for c-commanders={#1}}} +} +\newcount\forest@repeat@key@depth +\forestset{% + repeat/.code 2 args={% + \advance\forest@repeat@key@depth1 + \pgfmathparse{int(#1)}% + \csedef{forest@repeat@key@\the\forest@repeat@key@depth}{\pgfmathresult}% + \expandafter\newloop\csname forest@repeat@key@loop@\the\forest@repeat@key@depth\endcsname + \def\forest@marshal{% + \csname forest@repeat@key@loop@\the\forest@repeat@key@depth\endcsname + \forest@temp@count=\csname forest@repeat@key@\the\forest@repeat@key@depth\endcsname\relax + \ifnum\forest@temp@count>0 + \advance\forest@temp@count-1 + \csedef{forest@repeat@key@\the\forest@repeat@key@depth}{\the\forest@temp@count}% + \pgfkeysalso{#2}% + }% + \expandafter\forest@marshal\csname forest@repeat@key@repeat@\the\forest@repeat@key@depth\endcsname + \advance\forest@repeat@key@depth-1 + }, +} +\pgfkeysgetvalue{/forest/repeat/.@cmd}\forest@temp +\pgfkeyslet{/forest/node walk/repeat/.@cmd}\forest@temp +\pgfmathdeclarefunction{strequal}{2}{% + \ifstrequal{#1}{#2}{\def\pgfmathresult{1}}{\def\pgfmathresult{0}}% +} +\pgfmathdeclarefunction{instr}{2}{% + \pgfutil@in@{#1}{#2}% + \ifpgfutil@in@\def\pgfmathresult{1}\else\def\pgfmathresult{0}\fi +} +\pgfmathdeclarefunction{strcat}{...}{% + \edef\pgfmathresult{\forest@strip@braces{#1}}% +} +\def\forest@pgfmathhelper@attribute@toks#1#2{% + \forest@forthis{% + \forest@nameandgo{#1}% + \forestoget{#2}\pgfmathresult + }% +} +\def\forest@pgfmathhelper@attribute@dimen#1#2{% + \forest@forthis{% + \forest@nameandgo{#1}% + \forestoget{#2}\forest@temp + \pgfmathparse{+\forest@temp}% + }% +} +\def\forest@pgfmathhelper@attribute@count#1#2{% + \forest@forthis{% + \forest@nameandgo{#1}% + \forestoget{#2}\forest@temp + \pgfmathtruncatemacro\pgfmathresult{\forest@temp}% + }% +} +\pgfmathdeclarefunction{id}{1}{% + \forest@forthis{% + \forest@nameandgo{#1}% + \let\pgfmathresult\forest@cn + }% +} +\forestset{% + if id/.code n args={3}{% + \ifnum#1=\forest@cn\relax + \pgfkeysalso{#2}% + \else + \pgfkeysalso{#3}% + \fi + }, + where id/.style n args={3}{for tree={if id={#1}{#2}{#3}}} +} +\def\forest@last@node{0} +\def\forest@nodehandleby@name@nodewalk@or@bracket#1{% + \ifx\pgfkeysnovalue#1% + \edef\forest@last@node{\forest@node@Nametoid{forest@last@node}}% + \else + \forest@nodehandleby@nnb@checkfirst#1\forest@END + \fi +} +\def\forest@nodehandleby@nnb@checkfirst#1#2\forest@END{% + \ifx[#1%] + \forest@create@node{#1#2}% + \else + \forest@forthis{% + \forest@nameandgo{#1#2}% + \let\forest@last@node\forest@cn + }% + \fi +} +\def\forest@create@node#1{% #1=bracket representation + \bracketParse{\forest@create@collectafterthought}% + \forest@last@node=#1\forest@end@create@node +} +\def\forest@create@collectafterthought#1\forest@end@create@node{% + \forestOletO{\forest@last@node}{delay}{\forest@last@node}{given options}% + \forestOset{\forest@last@node}{given options}{}% + \forestOeappto{\forest@last@node}{delay}{,\unexpanded{#1}}% +} +\def\forest@remove@node#1{% + \forest@node@Remove{#1}% +} +\def\forest@append@node#1#2{% + \forest@node@Remove{#2}% + \forest@node@Append{#1}{#2}% +} +\def\forest@prepend@node#1#2{% + \forest@node@Remove{#2}% + \forest@node@Prepend{#1}{#2}% +} +\def\forest@insertafter@node#1#2{% + \forest@node@Remove{#2}% + \forest@node@Insertafter{\forestOve{#1}{@parent}}{#2}{#1}% +} +\def\forest@insertbefore@node#1#2{% + \forest@node@Remove{#2}% + \forest@node@Insertbefore{\forestOve{#1}{@parent}}{#2}{#1}% +} +\def\forest@appto@do@dynamics#1#2{% + \forest@nodehandleby@name@nodewalk@or@bracket{#2}% + \ifcase\forest@dynamics@copyhow\relax\or + \forest@tree@copy{\forest@last@node}\forest@last@node + \or + \forest@node@copy{\forest@last@node}\forest@last@node + \fi + \forest@node@Ifnamedefined{forest@last@node}{% + \forestOepreto{\forest@last@node}{delay} + {for id={\forest@node@Nametoid{forest@last@node}}{alias=forest@last@node},}% + }{}% + \forest@havedelayedoptionstrue + \edef\forest@marshal{% + \noexpand\apptotoks\noexpand\forest@do@dynamics{% + \noexpand#1{\forest@cn}{\forest@last@node}}% + }\forest@marshal +} +\forestset{% + create/.code={\forest@create@node{#1}}, + append/.code={\def\forest@dynamics@copyhow{0}\forest@appto@do@dynamics\forest@append@node{#1}}, + prepend/.code={\def\forest@dynamics@copyhow{0}\forest@appto@do@dynamics\forest@prepend@node{#1}}, + insert after/.code={\def\forest@dynamics@copyhow{0}\forest@appto@do@dynamics\forest@insertafter@node{#1}}, + insert before/.code={\def\forest@dynamics@copyhow{0}\forest@appto@do@dynamics\forest@insertbefore@node{#1}}, + append'/.code={\def\forest@dynamics@copyhow{1}\forest@appto@do@dynamics\forest@append@node{#1}}, + prepend'/.code={\def\forest@dynamics@copyhow{1}\forest@appto@do@dynamics\forest@prepend@node{#1}}, + insert after'/.code={\def\forest@dynamics@copyhow{1}\forest@appto@do@dynamics\forest@insertafter@node{#1}}, + insert before'/.code={\def\forest@dynamics@copyhow{1}\forest@appto@do@dynamics\forest@insertbefore@node{#1}}, + append''/.code={\def\forest@dynamics@copyhow{2}\forest@appto@do@dynamics\forest@append@node{#1}}, + prepend''/.code={\def\forest@dynamics@copyhow{2}\forest@appto@do@dynamics\forest@prepend@node{#1}}, + insert after''/.code={\def\forest@dynamics@copyhow{2}\forest@appto@do@dynamics\forest@insertafter@node{#1}}, + insert before''/.code={\def\forest@dynamics@copyhow{2}\forest@appto@do@dynamics\forest@insertbefore@node{#1}}, + remove/.code={% + \pgfkeysalso{alias=forest@last@node}% + \expandafter\apptotoks\expandafter\forest@do@dynamics\expandafter{% + \expandafter\forest@remove@node\expandafter{\forest@cn}}% + }, + set root/.code={% + \forest@nodehandleby@name@nodewalk@or@bracket{#1}% + \edef\forest@marshal{% + \noexpand\apptotoks\noexpand\forest@do@dynamics{% + \def\noexpand\forest@root{\forest@last@node}% + }% + }\forest@marshal + }, + replace by/.code={\forest@replaceby@code{#1}{insert after}}, + replace by'/.code={\forest@replaceby@code{#1}{insert after'}}, + replace by''/.code={\forest@replaceby@code{#1}{insert after''}}, +} +\def\forest@replaceby@code#1#2{%#1=node spec,#2=insert after[']['] + \ifnum\forestove{@parent}=0 + \pgfkeysalso{set root={#1}}% + \else + \pgfkeysalso{alias=forest@last@node,#2={#1}}% + \eapptotoks\forest@do@dynamics{% + \noexpand\ifnum\noexpand\forestOve{\forest@cn}{@parent}=\forestove{@parent} + \noexpand\forest@remove@node{\forest@cn}% + \noexpand\fi + }% + \fi +} +\forestset{ + stages/.style={ + before typesetting nodes hook, + typeset nodes, + after typesetting nodes hook, + before packing hook, + pack, + after packing hook, + before computing xy hook, + compute xy, + after computing xy hook, + before drawing tree hook, + draw tree, + after drawing tree hook, + }, + before typesetting nodes hook/.style={process keylist=before typesetting nodes}, + after typesetting nodes hook/.style={}, + before packing hook/.style={process keylist=before packing}, + after packing hook/.style={}, + before computing xy hook/.style={process keylist=before computing xy}, + after computing xy hook/.style={}, + before drawing tree hook/.style={process keylist=before drawing tree}, + after drawing tree hook/.style={}, + process keylist/.code={\forest@process@hook@keylist{#1}}, + declare keylist={given options}{}, + declare keylist={before typesetting nodes}{}, + declare keylist={before packing}{}, + declare keylist={before computing xy}{}, + declare keylist={before drawing tree}{}, + declare keylist={delay}{}, + delay/.append code={\forest@havedelayedoptionstrue}, + typeset nodes/.code={% + \forest@drawtree@preservenodeboxes@false + \forest@node@Foreach{\forest@root}{\forest@node@typeset}}, + typeset nodes'/.code={% + \forest@drawtree@preservenodeboxes@true + \forest@node@Foreach{\forest@root}{\forest@node@typeset}}, + typeset node/.code={% + \forest@drawtree@preservenodeboxes@false + \forest@node@typeset + }, + pack/.code={% + \forest@fornode{\forest@root}{\forest@pack}}, + compute xy/.code={% + \forest@fornode{\forest@root}{\forest@node@computeabsolutepositions}}, + draw tree box/.store in=\forest@drawtreebox, + draw tree box, + draw tree/.code={% + \forest@drawtree@preservenodeboxes@false + \forest@fornode{\forest@root}{\forest@node@drawtree}% + }, + draw tree'/.code={% + \forest@drawtree@preservenodeboxes@true + \forest@fornode{\forest@root}{\forest@node@drawtree}% + }, +} +\newtoks\forest@do@dynamics +\newif\ifforest@havedelayedoptions +\def\forest@process@hook@keylist#1{% + \forest@loopa + \forest@havedelayedoptionsfalse + \forest@do@dynamics={}% + \forest@fornode{\forest@root}{\forest@process@hook@keylist@{#1}}% + \expandafter\ifstrempty\expandafter{\the\forest@do@dynamics}{}{% + \the\forest@do@dynamics + \forest@node@Compute@numeric@ts@info{\forest@root}% + \forest@havedelayedoptionstrue + }% + \ifforest@havedelayedoptions + \forest@node@Foreach{\forest@root}{% + \forestoget{delay}\forest@temp@delayed + \forestolet{#1}\forest@temp@delayed + \forestoset{delay}{}% + }% + \forest@repeata +} +\def\forest@process@hook@keylist@#1{% + \forest@node@foreach{% + \forestoget{#1}\forest@temp@keys + \ifdefvoid\forest@temp@keys{}{% + \forestoset{#1}{}% + \expandafter\forestset\expandafter{\forest@temp@keys}% + }% + }% +} +\def\forest@node@typeset{% + \let\forest@next\forest@node@typeset@ + \forestoifdefined{box}{% + \ifforest@drawtree@preservenodeboxes@ + \let\forest@next\relax + \fi + }{% + \locbox\forest@temp@box + \forestolet{box}\forest@temp@box + }% + \forest@next +} +\newbox\forest@box +\def\forest@node@typeset@{% + \forestoget{name}\forest@nodename + \edef\forest@temp@nodeformat{\forestove{node format}}% + \gdef\forest@smuggle{}% + \setbox0=\hbox{% + \begin{tikzpicture}% + \pgfpositionnodelater{\forest@positionnodelater@save}% + \forest@temp@nodeformat + \pgfinterruptpath + \pgfpointanchor{not yet positioned@\forest@nodename}{forestcomputenodeboundary}% + \endpgfinterruptpath + %\forest@compute@node@boundary\forest@temp + %\xappto\forest@smuggle{\noexpand\forestoset{boundary}{\expandonce\forest@temp}}% + \if\relax\forestove{parent anchor}\relax + \pgfpointanchor{not yet positioned@\forest@nodename}{center}% + \else + \pgfpointanchor{not yet positioned@\forest@nodename}{\forestove{parent anchor}}% + \fi + \xappto\forest@smuggle{% + \noexpand\forestoset{parent@anchor}{% + \noexpand\noexpand\noexpand\pgf@x=\the\pgf@x\relax + \noexpand\noexpand\noexpand\pgf@y=\the\pgf@y\relax}}% + \if\relax\forestove{child anchor}\relax + \pgfpointanchor{not yet positioned@\forest@nodename}{center}% + \else + \pgfpointanchor{not yet positioned@\forest@nodename}{\forestove{child anchor}}% + \fi + \xappto\forest@smuggle{% + \noexpand\forestoeset{child@anchor}{% + \noexpand\noexpand\noexpand\pgf@x=\the\pgf@x\relax + \noexpand\noexpand\noexpand\pgf@y=\the\pgf@y\relax}}% + \if\relax\forestove{anchor}\relax + \pgfpointanchor{not yet positioned@\forest@nodename}{center}% + \else + \pgfpointanchor{not yet positioned@\forest@nodename}{\forestove{anchor}}% + \fi + \xappto\forest@smuggle{% + \noexpand\forestoeset{@anchor}{% + \noexpand\noexpand\noexpand\pgf@x=\the\pgf@x\relax + \noexpand\noexpand\noexpand\pgf@y=\the\pgf@y\relax}}% + \end{tikzpicture}% + }% + \setbox\forestove{box}=\box\forest@box % smuggle the box + \forestolet{boundary}\forest@global@boundary + \forest@smuggle % ... and the rest +} +\forestset{ + declare readonly dimen={min x}, + declare readonly dimen={min y}, + declare readonly dimen={max x}, + declare readonly dimen={max y}, +} +\def\forest@patch@enormouscoordinateboxbounds@plus#1{% + \expandafter\ifstrequal\expandafter{#1}{16000.0pt}{\def#1{0.0pt}}{}% +} +\def\forest@patch@enormouscoordinateboxbounds@minus#1{% + \expandafter\ifstrequal\expandafter{#1}{-16000.0pt}{\def#1{0.0pt}}{}% +} +\def\forest@positionnodelater@save{% + \global\setbox\forest@box=\box\pgfpositionnodelaterbox + \xappto\forest@smuggle{\noexpand\forestoset{later@name}{\pgfpositionnodelatername}}% + % a bug in pgf? ---well, here's a patch + \forest@patch@enormouscoordinateboxbounds@plus\pgfpositionnodelaterminx + \forest@patch@enormouscoordinateboxbounds@plus\pgfpositionnodelaterminy + \forest@patch@enormouscoordinateboxbounds@minus\pgfpositionnodelatermaxx + \forest@patch@enormouscoordinateboxbounds@minus\pgfpositionnodelatermaxy + % end of patch + \xappto\forest@smuggle{\noexpand\forestoset{min x}{\pgfpositionnodelaterminx}}% + \xappto\forest@smuggle{\noexpand\forestoset{min y}{\pgfpositionnodelaterminy}}% + \xappto\forest@smuggle{\noexpand\forestoset{max x}{\pgfpositionnodelatermaxx}}% + \xappto\forest@smuggle{\noexpand\forestoset{max y}{\pgfpositionnodelatermaxy}}% +} +\def\forest@node@forest@positionnodelater@restore{% + \ifforest@drawtree@preservenodeboxes@ + \let\forest@boxorcopy\copy + \else + \let\forest@boxorcopy\box + \fi + \forestoget{box}\forest@temp + \setbox\pgfpositionnodelaterbox=\forest@boxorcopy\forest@temp + \edef\pgfpositionnodelatername{\forestove{later@name}}% + \edef\pgfpositionnodelaterminx{\forestove{min x}}% + \edef\pgfpositionnodelaterminy{\forestove{min y}}% + \edef\pgfpositionnodelatermaxx{\forestove{max x}}% + \edef\pgfpositionnodelatermaxy{\forestove{max y}}% +} +\def\forest@pack{% + \forest@pack@computetiers + \forest@pack@computegrowthuniformity + \forest@@pack +} +\def\forest@@pack{% + \ifnum\forestove{n children}>0 + \ifnum\forestove{uniform growth}>0 + \forest@pack@level@uniform + \forest@pack@aligntiers@ofsubtree + \forest@pack@sibling@uniform@recursive + \else + \forest@node@foreachchild{\forest@@pack}% + \forest@pack@level@nonuniform + \forest@pack@aligntiers + \forest@pack@sibling@uniform@applyreversed + \fi + \fi +} +\def\forest@pack@computegrowthuniformity{% + \forest@node@foreachchild{\forest@pack@computegrowthuniformity}% + \edef\forest@pack@cgu@uniformity{% + \ifnum\forestove{n children}=0 + 2\else 1\fi + }% + \forestoget{grow}\forest@pack@cgu@parentgrow + \forest@node@foreachchild{% + \ifnum\forestove{uniform growth}=0 + \def\forest@pack@cgu@uniformity{0}% + \else + \ifnum\forestove{uniform growth}=1 + \ifnum\forestove{grow}=\forest@pack@cgu@parentgrow\relax\else + \def\forest@pack@cgu@uniformity{0}% + \fi + \fi + \fi + }% + \forestolet{uniform growth}\forest@pack@cgu@uniformity +} +\def\forest@pack@level@uniform{% + \let\forest@plu@minchildl\relax + \forestoget{grow}\forest@plu@grow + \forest@node@foreachchild{% + \forest@node@getboundingrectangle@ls{\forest@plu@grow}% + \advance\pgf@xa\forestove{l}\relax + \ifx\forest@plu@minchildl\relax + \edef\forest@plu@minchildl{\the\pgf@xa}% + \else + \ifdim\pgf@xa<\forest@plu@minchildl\relax + \edef\forest@plu@minchildl{\the\pgf@xa}% + \fi + \fi + }% + \forest@node@getboundingrectangle@ls{\forest@plu@grow}% + \pgfutil@tempdima=\pgf@xb\relax + \advance\pgfutil@tempdima -\forest@plu@minchildl\relax + \advance\pgfutil@tempdima \forestove{l sep}\relax + \ifdim\pgfutil@tempdima>0pt + \forest@node@foreachchild{% + \forestoeset{l}{\the\dimexpr\forestove{l}+\the\pgfutil@tempdima}% + }% + \fi + \forest@node@foreachchild{% + \ifnum\forestove{n children}>0 + \forest@pack@level@uniform + \fi + }% +} +\def\forest@pack@level@nonuniform{% + \let\forest@plu@minchildl\relax + \forestoget{grow}\forest@plu@grow + \forest@node@foreachchild{% + \forest@node@getedge{negative}{\forest@plu@grow}{\forest@plnu@negativechildedge}% + \forest@node@getedge{positive}{\forest@plu@grow}{\forest@plnu@positivechildedge}% + \def\forest@plnu@childedge{\forest@plnu@negativechildedge\forest@plnu@positivechildedge}% + \forest@path@getboundingrectangle@ls\forest@plnu@childedge{\forest@plu@grow}% + \advance\pgf@xa\forestove{l}\relax + \ifx\forest@plu@minchildl\relax + \edef\forest@plu@minchildl{\the\pgf@xa}% + \else + \ifdim\pgf@xa<\forest@plu@minchildl\relax + \edef\forest@plu@minchildl{\the\pgf@xa}% + \fi + \fi + }% + \forest@node@getboundingrectangle@ls{\forest@plu@grow}% + \pgfutil@tempdima=\pgf@xb\relax + \advance\pgfutil@tempdima -\forest@plu@minchildl\relax + \advance\pgfutil@tempdima \forestove{l sep}\relax + \ifdim\pgfutil@tempdima>0pt + \forest@node@foreachchild{% + \forestoeset{l}{\the\dimexpr\the\pgfutil@tempdima+\forestove{l}}% + }% + \fi +} +\def\forest@pack@aligntiers{% + \forestoget{grow}\forest@temp@parentgrow + \forestoget{@tiers}\forest@temp@tiers + \forlistloop\forest@pack@aligntier@\forest@temp@tiers +} +\def\forest@pack@aligntiers@ofsubtree{% + \forest@node@foreach{\forest@pack@aligntiers}% +} +\def\forest@pack@aligntiers@computeabsl{% + \forestoleto{abs@l}{l}% + \forest@node@foreachdescendant{\forest@pack@aligntiers@computeabsl@}% +} +\def\forest@pack@aligntiers@computeabsl@{% + \forestoeset{abs@l}{\the\dimexpr\forestove{l}+\forestOve{\forestove{@parent}}{abs@l}}% +} +\def\forest@pack@aligntier@#1{% + \forest@pack@aligntiers@computeabsl + \pgfutil@tempdima=-\maxdimen\relax + \def\forest@temp@currenttier{#1}% + \forest@node@foreach{% + \forestoget{tier}\forest@temp@tier + \ifx\forest@temp@currenttier\forest@temp@tier + \ifdim\pgfutil@tempdima<\forestove{abs@l}\relax + \pgfutil@tempdima=\forestove{abs@l}\relax + \fi + \fi + }% + \ifdim\pgfutil@tempdima=-\maxdimen\relax\else + \forest@node@foreach{% + \forestoget{tier}\forest@temp@tier + \ifx\forest@temp@currenttier\forest@temp@tier + \forestoeset{l}{\the\dimexpr\pgfutil@tempdima-\forestove{abs@l}+\forestove{l}}% + \fi + }% + \fi +} +\def\forest@pack@sibling@uniform@recursive{% + \forest@node@foreachchild{\forest@pack@sibling@uniform@recursive}% + \forest@pack@sibling@uniform@applyreversed +} +\def\forest@pack@sibling@uniform@applyreversed{% + \ifnum\forestove{n children}>1 + \ifnum\forestove{reversed}=0 + \pack@sibling@uniform@main{first}{last}{next}{previous}% + \else + \pack@sibling@uniform@main{last}{first}{previous}{next}% + \fi + \fi +} +\def\pack@sibling@uniform@main#1#2#3#4{% + \forestoget{@#1}\forest@child + \edef\forest@temp{% + \noexpand\forest@fornode{\forestove{@#1}}{% + \noexpand\forest@node@getedge + {positive} + {\forestove{grow}} + \noexpand\forest@temp@edge + }% + }\forest@temp + \forest@pack@pgfpoint@childsposition\forest@child + \let\forest@previous@positive@edge\pgfutil@empty + \forest@extendpath\forest@previous@positive@edge\forest@temp@edge{}% + \forestOget{\forest@child}{@#3}\forest@child + \edef\forest@previous@child@s{0pt}% + \forest@loopb + \unless\ifnum\forest@child=0 + \edef\forest@temp{% + \noexpand\forest@fornode{\forest@child}{% + \noexpand\forest@node@getedge + {negative} + {\forestove{grow}} + \noexpand\forest@temp@edge + }% + }\forest@temp + \forest@pack@pgfpoint@childsposition\forest@child + \let\forest@child@negative@edge\pgfutil@empty + \forest@extendpath\forest@child@negative@edge\forest@temp@edge{}% + \forest@setupgrowline{\forestove{grow}}% + \forest@distance@between@edge@paths\forest@previous@positive@edge\forest@child@negative@edge\forest@csdistance + \ifx\forest@csdistance\relax + %\forestOeset{\forest@child}{s}{\forest@previous@child@s}% + \else + \advance\pgfutil@tempdimb-\forest@csdistance\relax + \advance\pgfutil@tempdimb\forestove{s sep}\relax + \forestOeset{\forest@child}{s}{\the\dimexpr\forestove{s}-\forest@csdistance+\forestove{s sep}}% + \fi + \ifdim\forestOve{\forest@child}{s}<\forest@previous@child@s\relax + \forestOeset{\forest@child}{s}{\forest@previous@child@s}% + \fi + \forestOget{\forest@child}{s}\forest@child@s + \edef\forest@previous@child@s{\forest@child@s}% + \edef\forest@temp{% + \noexpand\forest@fornode{\forest@child}{% + \noexpand\forest@node@getedge + {positive} + {\forestove{grow}} + \noexpand\forest@temp@edge + }% + }\forest@temp + \forest@pack@pgfpoint@childsposition\forest@child + \forest@extendpath\forest@previous@positive@edge\forest@temp@edge{}% + \forest@getpositivetightedgeofpath\forest@previous@positive@edge\forest@previous@positive@edge + \forestOget{\forest@child}{@#3}\forest@child + \forest@repeatb + \csname forest@calign@\forestove{calign}\endcsname +} +\def\forest@pack@pgfpoint@childsposition#1{% + {% + \pgftransformreset + \pgftransformrotate{\forestove{grow}}% + \forest@fornode{#1}{% + \pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}% + }% + }% +} +\def\forest@pack@pgfpoint@positioningrow#1{% + {% + \pgftransformreset + \pgftransformrotate{#1}% + \pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}% + }% +} +\def\forest@calign@s@shift#1{% + \pgfutil@tempdima=#1\relax + \forest@node@foreachchild{% + \forestoeset{s}{\the\dimexpr\forestove{s}+\pgfutil@tempdima}% + }% +} +\def\forest@calign@child{% + \forest@calign@s@shift{-\forestOve{\forest@node@nornbarthchildid{\forestove{calign primary child}}}{s}}% +} +\csdef{forest@calign@child edge}{% + {% + \edef\forest@temp@child{\forest@node@nornbarthchildid{\forestove{calign primary child}}}% + \pgftransformreset + \pgftransformrotate{\forestove{grow}}% + \pgfpointtransformed{\pgfqpoint{\forestOve{\forest@temp@child}{l}}{\forestOve{\forest@temp@child}{s}}}% + \pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax + \forestOve{\forest@temp@child}{child@anchor}% + \advance\pgf@xa\pgf@x\relax\advance\pgf@ya\pgf@y\relax + \forestove{parent@anchor}% + \advance\pgf@xa-\pgf@x\relax\advance\pgf@ya-\pgf@y\relax + \edef\forest@marshal{% + \noexpand\pgftransformreset + \noexpand\pgftransformrotate{-\forestove{grow}}% + \noexpand\pgfpointtransformed{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + }\forest@marshal + }% + \forest@calign@s@shift{\the\dimexpr-\the\pgf@y}% +} +\csdef{forest@calign@midpoint}{% + \forest@calign@s@shift{\the\dimexpr 0pt -% + (\forestOve{\forest@node@nornbarthchildid{\forestove{calign primary child}}}{s}% + +\forestOve{\forest@node@nornbarthchildid{\forestove{calign secondary child}}}{s}% + )/2\relax + }% +} +\csdef{forest@calign@edge midpoint}{% + {% + \edef\forest@temp@firstchild{\forest@node@nornbarthchildid{\forestove{calign primary child}}}% + \edef\forest@temp@secondchild{\forest@node@nornbarthchildid{\forestove{calign secondary child}}}% + \pgftransformreset + \pgftransformrotate{\forestove{grow}}% + \pgfpointtransformed{\pgfqpoint{\forestOve{\forest@temp@firstchild}{l}}{\forestOve{\forest@temp@firstchild}{s}}}% + \pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax + \forestOve{\forest@temp@firstchild}{child@anchor}% + \advance\pgf@xa\pgf@x\relax\advance\pgf@ya\pgf@y\relax + \edef\forest@marshal{% + \noexpand\pgfpointtransformed{\noexpand\pgfqpoint{\forestOve{\forest@temp@secondchild}{l}}{\forestOve{\forest@temp@secondchild}{s}}}% + }\forest@marshal + \advance\pgf@xa\pgf@x\relax\advance\pgf@ya\pgf@y\relax + \forestOve{\forest@temp@secondchild}{child@anchor}% + \advance\pgf@xa\pgf@x\relax\advance\pgf@ya\pgf@y\relax + \divide\pgf@xa2 \divide\pgf@ya2 + \edef\forest@marshal{% + \noexpand\pgftransformreset + \noexpand\pgftransformrotate{-\forestove{grow}}% + \noexpand\pgfpointtransformed{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + }\forest@marshal + }% + \forest@calign@s@shift{\the\dimexpr-\the\pgf@y}% +} +\csdef{forest@calign@fixed angles}{% + \edef\forest@ca@first@child{\forest@node@nornbarthchildid{\forestove{calign primary child}}}% + \edef\forest@ca@second@child{\forest@node@nornbarthchildid{\forestove{calign secondary child}}}% + \ifnum\forestove{reversed}=1 + \let\forest@temp\forest@ca@first@child + \let\forest@ca@first@child\forest@ca@second@child + \let\forest@ca@second@child\forest@temp + \fi + \forestOget{\forest@ca@first@child}{l}\forest@ca@first@l + \forestOget{\forest@ca@second@child}{l}\forest@ca@second@l + \pgfmathsetlengthmacro\forest@ca@desired@s@distance{% + tan(\forestove{calign secondary angle})*\forest@ca@second@l + -tan(\forestove{calign primary angle})*\forest@ca@first@l + }% + \forestOget{\forest@ca@first@child}{s}\forest@ca@first@s + \forestOget{\forest@ca@second@child}{s}\forest@ca@second@s + \pgfmathsetlengthmacro\forest@ca@actual@s@distance{% + \forest@ca@second@s-\forest@ca@first@s}% + \ifdim\forest@ca@desired@s@distance>\forest@ca@actual@s@distance\relax + \ifdim\forest@ca@actual@s@distance=0pt + \pgfmathsetlength\pgfutil@tempdima{tan(\forestove{calign primary angle})*\forest@ca@second@l}% + \pgfmathsetlength\pgfutil@tempdimb{\forest@ca@desired@s@distance/(\forestove{n children}-1)}% + \forest@node@foreachchild{% + \forestoeset{s}{\the\pgfutil@tempdima}% + \advance\pgfutil@tempdima\pgfutil@tempdimb + }% + \def\forest@calign@anchor{0pt}% + \else + \pgfmathsetmacro\forest@ca@ratio{% + \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}% + \forest@node@foreachchild{% + \pgfmathsetlengthmacro\forest@temp{\forest@ca@ratio*\forestove{s}}% + \forestolet{s}\forest@temp + }% + \pgfmathsetlengthmacro\forest@calign@anchor{% + -tan(\forestove{calign primary angle})*\forest@ca@first@l}% + \fi + \else + \ifdim\forest@ca@desired@s@distance<\forest@ca@actual@s@distance\relax + \pgfmathsetlengthmacro\forest@ca@ratio{% + \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}% + \forest@node@foreachchild{% + \pgfmathsetlengthmacro\forest@temp{\forest@ca@ratio*\forestove{l}}% + \forestolet{l}\forest@temp + }% + \forestOget{\forest@ca@first@child}{l}\forest@ca@first@l + \pgfmathsetlengthmacro\forest@calign@anchor{% + -tan(\forestove{calign primary angle})*\forest@ca@first@l}% + \fi + \fi + \forest@calign@s@shift{-\forest@calign@anchor}% +} +\csdef{forest@calign@fixed edge angles}{% + \edef\forest@ca@first@child{\forest@node@nornbarthchildid{\forestove{calign primary child}}}% + \edef\forest@ca@second@child{\forest@node@nornbarthchildid{\forestove{calign secondary child}}}% + \ifnum\forestove{reversed}=1 + \let\forest@temp\forest@ca@first@child + \let\forest@ca@first@child\forest@ca@second@child + \let\forest@ca@second@child\forest@temp + \fi + \forestOget{\forest@ca@first@child}{l}\forest@ca@first@l + \forestOget{\forest@ca@second@child}{l}\forest@ca@second@l + \forestoget{parent@anchor}\forest@ca@parent@anchor + \forest@ca@parent@anchor + \edef\forest@ca@parent@anchor@s{\the\pgf@x}% + \edef\forest@ca@parent@anchor@l{\the\pgf@y}% + \forestOget{\forest@ca@first@child}{child@anchor}\forest@ca@first@child@anchor + \forest@ca@first@child@anchor + \edef\forest@ca@first@child@anchor@s{\the\pgf@x}% + \edef\forest@ca@first@child@anchor@l{\the\pgf@y}% + \forestOget{\forest@ca@second@child}{child@anchor}\forest@ca@second@child@anchor + \forest@ca@second@child@anchor + \edef\forest@ca@second@child@anchor@s{\the\pgf@x}% + \edef\forest@ca@second@child@anchor@l{\the\pgf@y}% + \pgfmathsetlengthmacro\forest@ca@desired@second@edge@s{tan(\forestove{calign secondary angle})*% + (\forest@ca@second@l-\forest@ca@second@child@anchor@l+\forest@ca@parent@anchor@l)}% + \pgfmathsetlengthmacro\forest@ca@desired@first@edge@s{tan(\forestove{calign primary angle})*% + (\forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l)} + \pgfmathsetlengthmacro\forest@ca@desired@s@distance{\forest@ca@desired@second@edge@s-\forest@ca@desired@first@edge@s}% + \forestOget{\forest@ca@first@child}{s}\forest@ca@first@s + \forestOget{\forest@ca@second@child}{s}\forest@ca@second@s + \pgfmathsetlengthmacro\forest@ca@actual@s@distance{% + \forest@ca@second@s+\forest@ca@second@child@anchor@s + -\forest@ca@first@s-\forest@ca@first@child@anchor@s}% + \ifdim\forest@ca@desired@s@distance>\forest@ca@actual@s@distance\relax + \ifdim\forest@ca@actual@s@distance=0pt + \forestoget{n children}\forest@temp@n@children + \forest@node@foreachchild{% + \forestoget{child@anchor}\forest@temp@child@anchor + \forest@temp@child@anchor + \edef\forest@temp@child@anchor@s{\the\pgf@x}% + \pgfmathsetlengthmacro\forest@temp{% + \forest@ca@desired@first@edge@s+(\forestove{n}-1)*\forest@ca@desired@s@distance/(\forest@temp@n@children-1)+\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}% + \forestolet{s}\forest@temp + }% + \def\forest@calign@anchor{0pt}% + \else + \pgfmathsetmacro\forest@ca@ratio{% + \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}% + \forest@node@foreachchild{% + \forestoget{child@anchor}\forest@temp@child@anchor + \forest@temp@child@anchor + \edef\forest@temp@child@anchor@s{\the\pgf@x}% + \pgfmathsetlengthmacro\forest@temp{% + \forest@ca@ratio*(% + \forestove{s}-\forest@ca@first@s + +\forest@temp@child@anchor@s-\forest@ca@first@child@anchor@s)% + +\forest@ca@first@s + +\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}% + \forestolet{s}\forest@temp + }% + \pgfmathsetlengthmacro\forest@calign@anchor{% + -tan(\forestove{calign primary angle})*(\forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l)% + +\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s + }% + \fi + \else + \ifdim\forest@ca@desired@s@distance<\forest@ca@actual@s@distance\relax + \pgfmathsetlengthmacro\forest@ca@ratio{% + \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}% + \forest@node@foreachchild{% + \forestoget{child@anchor}\forest@temp@child@anchor + \forest@temp@child@anchor + \edef\forest@temp@child@anchor@l{\the\pgf@y}% + \pgfmathsetlengthmacro\forest@temp{% + \forest@ca@ratio*(% + \forestove{l}+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l) + -\forest@ca@parent@anchor@l+\forest@temp@child@anchor@l}% + \forestolet{l}\forest@temp + }% + \forestOget{\forest@ca@first@child}{l}\forest@ca@first@l + \pgfmathsetlengthmacro\forest@calign@anchor{% + -tan(\forestove{calign primary angle})*(\forest@ca@first@l+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l)% + +\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s + }% + \fi + \fi + \forest@calign@s@shift{-\forest@calign@anchor}% +} +\def\forest@node@getedge#1#2#3{% + \forestoget{#1@edge@#2}#3% + \ifx#3\relax + \forest@node@foreachchild{% + \forest@node@getedge{#1}{#2}{\forest@temp@edge}% + }% + \forest@forthis{\forest@node@getedges{#2}}% + \forestoget{#1@edge@#2}#3% + \fi +} +\def\forest@node@getedges#1{% + %{% + \forest@setupgrowline{#1}% + \ifnum\forestove{ignore}=0 + \forestoget{boundary}\forest@node@boundary + \else + \def\forest@node@boundary{}% + \fi + \csname forest@getboth\forestove{fit}edgesofpath\endcsname + \forest@node@boundary\forest@negative@node@edge\forest@positive@node@edge + \forestolet{negative@edge@#1}\forest@negative@node@edge + \forestolet{positive@edge@#1}\forest@positive@node@edge + \get@edges@merge{negative}{#1}% + \get@edges@merge{positive}{#1}% + %}% +} +\def\get@edges@merge#1#2{% + \ifnum\forestove{n children}>0 + \forestoget{#1@edge@#2}\forest@node@edge + \forestove{parent@anchor}% + \edef\forest@getedge@pa@l{\the\pgf@x}% + \edef\forest@getedge@pa@s{\the\pgf@y}% + \eappto\forest@node@edge{\noexpand\pgfsyssoftpath@movetotoken{\forest@getedge@pa@l}{\forest@getedge@pa@s}}% + \pgftransformreset + \pgftransformrotate{\forestove{grow}}% + \def\forest@all@edges{}% + \forest@node@foreachchild{% + \forestoget{#1@edge@#2}\forest@temp@edge + \pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}% + \forest@extendpath\forest@node@edge\forest@temp@edge{}% + \ifnum\forestove{ignore edge}=0 + \pgfpointadd + {\pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}}% + {\forestove{child@anchor}}% + \pgfgetlastxy{\forest@getedge@ca@l}{\forest@getedge@ca@s}% + \eappto\forest@all@edges{% + \noexpand\pgfsyssoftpath@movetotoken{\forest@getedge@pa@l}{\forest@getedge@pa@s}% + \noexpand\pgfsyssoftpath@linetotoken{\forest@getedge@ca@l}{\forest@getedge@ca@s}% + }% + % this deals with potential overlap of the edges: + \eappto\forest@node@edge{\noexpand\pgfsyssoftpath@movetotoken{\forest@getedge@ca@l}{\forest@getedge@ca@s}}% + \fi + }% + \ifdefempty{\forest@all@edges}{}{% + \pgfintersectionofpaths{\pgfsetpath\forest@all@edges}{\pgfsetpath\forest@node@edge}% + \def\forest@edgenode@intersections{}% + \forest@merge@intersectionloop + \eappto\forest@node@edge{\expandonce{\forest@all@edges}\expandonce{\forest@edgenode@intersections}}% + }% + \csname forest@get#1\forestove{fit}edgeofpath\endcsname\forest@node@edge\forest@node@edge + \forestolet{#1@edge@#2}\forest@node@edge + \fi +} +\newloop\forest@merge@loop +\def\forest@merge@intersectionloop{% + \c@pgf@counta=0 + \forest@merge@loop + \ifnum\c@pgf@counta<\pgfintersectionsolutions\relax + \advance\c@pgf@counta1 + \pgfpointintersectionsolution{\the\c@pgf@counta}% + \eappto\forest@edgenode@intersections{\noexpand\pgfsyssoftpath@movetotoken + {\the\pgf@x}{\the\pgf@y}}% + \forest@merge@repeat +} +\def\forest@node@getboundingrectangle@ls#1{% + \forestoget{boundary}\forest@node@boundary + \forest@path@getboundingrectangle@ls\forest@node@boundary{#1}% +} +\def\forest@pgfpathtransformed#1{% + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@pgfpathtransformed@moveto + \let\pgfsyssoftpath@linetotoken\forest@pgfpathtransformed@lineto + \pgfsyssoftpath@setcurrentpath\pgfutil@empty + #1% + \forest@restore@pgfsyssoftpath@tokendefs +} +\def\forest@pgfpathtransformed@moveto#1#2{% + \forest@pgfpathtransformed@op\pgfsyssoftpath@moveto{#1}{#2}% +} +\def\forest@pgfpathtransformed@lineto#1#2{% + \forest@pgfpathtransformed@op\pgfsyssoftpath@lineto{#1}{#2}% +} +\def\forest@pgfpathtransformed@op#1#2#3{% + \pgfpointtransformed{\pgfqpoint{#2}{#3}}% + \edef\forest@temp{% + \noexpand#1{\the\pgf@x}{\the\pgf@y}% + }% + \forest@temp +} +\def\forest@pack@computetiers{% + {% + \forest@pack@tiers@getalltiersinsubtree + \forest@pack@tiers@computetierhierarchy + \forest@pack@tiers@findcontainers + \forest@pack@tiers@raisecontainers + \forest@pack@tiers@computeprocessingorder + \gdef\forest@smuggle{}% + \forest@pack@tiers@write + }% + \forest@node@foreach{\forestoset{@tiers}{}}% + \forest@smuggle +} +\def\forest@pack@tiers@getalltiersinsubtree{% + \ifnum\forestove{n children}>0 + \forest@node@foreachchild{\forest@pack@tiers@getalltiersinsubtree}% + \fi + \forestoget{tier}\forest@temp@mytier + \def\forest@temp@mytiers{}% + \ifdefempty\forest@temp@mytier{}{% + \listeadd\forest@temp@mytiers\forest@temp@mytier + }% + \ifnum\forestove{n children}>0 + \forest@node@foreachchild{% + \forestoget{tiers}\forest@temp@tiers + \forlistloop\forest@pack@tiers@forhandlerA\forest@temp@tiers + }% + \fi + \forestolet{tiers}\forest@temp@mytiers +} +\def\forest@pack@tiers@forhandlerA#1{% + \ifinlist{#1}\forest@temp@mytiers{}{% + \listeadd\forest@temp@mytiers{#1}% + }% +} +\def\forest@pack@tiers@computetierhierarchy{% + \def\forest@tiers@ancestors{}% + \forestoget{tiers}\forest@temp@mytiers + \forlistloop\forest@pack@tiers@cth@init\forest@temp@mytiers + \forest@pack@tiers@computetierhierarchy@ +} +\def\forest@pack@tiers@cth@init#1{% + \csdef{forest@tiers@higher@#1}{}% + \csdef{forest@tiers@lower@#1}{}% +} +\def\forest@pack@tiers@computetierhierarchy@{% + \forestoget{tier}\forest@temp@mytier + \ifdefempty\forest@temp@mytier{}{% + \forlistloop\forest@pack@tiers@forhandlerB\forest@tiers@ancestors + \listeadd\forest@tiers@ancestors\forest@temp@mytier + }% + \forest@node@foreachchild{% + \forest@pack@tiers@computetierhierarchy@ + }% + \forestoget{tier}\forest@temp@mytier + \ifdefempty\forest@temp@mytier{}{% + \forest@listedel\forest@tiers@ancestors\forest@temp@mytier + }% +} +\def\forest@pack@tiers@forhandlerB#1{% + \def\forest@temp@tier{#1}% + \ifx\forest@temp@tier\forest@temp@mytier + \PackageError{forest}{Circular tier hierarchy (tier \forest@temp@mytier)}{}% + \fi + \ifinlistcs{#1}{forest@tiers@higher@\forest@temp@mytier}{}{% + \listcsadd{forest@tiers@higher@\forest@temp@mytier}{#1}}% + \xifinlistcs\forest@temp@mytier{forest@tiers@lower@#1}{}{% + \listcseadd{forest@tiers@lower@#1}{\forest@temp@mytier}}% +} +\def\forest@pack@tiers@findcontainers{% + \forestoget{tiers}\forest@temp@tiers + \forlistloop\forest@pack@tiers@findcontainer\forest@temp@tiers +} +\def\forest@pack@tiers@findcontainer#1{% + \def\forest@temp@tier{#1}% + \forestoget{tier}\forest@temp@mytier + \ifx\forest@temp@tier\forest@temp@mytier + \csedef{forest@tiers@container@#1}{\forest@cn}% + \else\@escapeif{% + \forest@pack@tiers@findcontainerA{#1}% + }\fi% +} +\def\forest@pack@tiers@findcontainerA#1{% + \c@pgf@counta=0 + \forest@node@foreachchild{% + \forestoget{tiers}\forest@temp@tiers + \ifinlist{#1}\forest@temp@tiers{% + \advance\c@pgf@counta 1 + \let\forest@temp@child\forest@cn + }{}% + }% + \ifnum\c@pgf@counta>1 + \csedef{forest@tiers@container@#1}{\forest@cn}% + \else\@escapeif{% surely =1 + \forest@fornode{\forest@temp@child}{% + \forest@pack@tiers@findcontainer{#1}% + }% + }\fi +} +\def\forest@pack@tiers@raisecontainers{% + \forestoget{tiers}\forest@temp@mytiers + \forlistloop\forest@pack@tiers@rc@forhandlerA\forest@temp@mytiers +} +\def\forest@pack@tiers@rc@forhandlerA#1{% + \edef\forest@tiers@temptier{#1}% + \letcs\forest@tiers@containernodeoftier{forest@tiers@container@#1}% + \letcs\forest@temp@lowertiers{forest@tiers@lower@#1}% + \forlistloop\forest@pack@tiers@rc@forhandlerB\forest@temp@lowertiers +} +\def\forest@pack@tiers@rc@forhandlerB#1{% + \letcs\forest@tiers@containernodeoflowertier{forest@tiers@container@#1}% + \forestOget{\forest@tiers@containernodeoflowertier}{content}\lowercontent + \forestOget{\forest@tiers@containernodeoftier}{content}\uppercontent + \forest@fornode{\forest@tiers@containernodeoflowertier}{% + \forest@ifancestorof + {\forest@tiers@containernodeoftier} + {\csletcs{forest@tiers@container@\forest@tiers@temptier}{forest@tiers@container@#1}}% + {}% + }% +} +\def\forest@pack@tiers@computeprocessingorder{% + \def\forest@tiers@processingorder{}% + \forestoget{tiers}\forest@tiers@cpo@tierstodo + \forest@loopa + \ifdefempty\forest@tiers@cpo@tierstodo{\forest@tempfalse}{\forest@temptrue}% + \ifforest@temp + \def\forest@tiers@cpo@tiersremaining{}% + \def\forest@tiers@cpo@tiersindependent{}% + \forlistloop\forest@pack@tiers@cpo@forhandlerA\forest@tiers@cpo@tierstodo + \ifdefempty\forest@tiers@cpo@tiersindependent{% + \PackageError{forest}{Circular tiers!}{}}{}% + \forlistloop\forest@pack@tiers@cpo@forhandlerB\forest@tiers@cpo@tiersremaining + \let\forest@tiers@cpo@tierstodo\forest@tiers@cpo@tiersremaining + \forest@repeata +} +\def\forest@pack@tiers@cpo@forhandlerA#1{% + \ifcsempty{forest@tiers@higher@#1}{% + \listadd\forest@tiers@cpo@tiersindependent{#1}% + \listadd\forest@tiers@processingorder{#1}% + }{% + \listadd\forest@tiers@cpo@tiersremaining{#1}% + }% +} +\def\forest@pack@tiers@cpo@forhandlerB#1{% + \def\forest@pack@tiers@cpo@aremainingtier{#1}% + \forlistloop\forest@pack@tiers@cpo@forhandlerC\forest@tiers@cpo@tiersindependent +} +\def\forest@pack@tiers@cpo@forhandlerC#1{% + \ifinlistcs{#1}{forest@tiers@higher@\forest@pack@tiers@cpo@aremainingtier}{% + \forest@listcsdel{forest@tiers@higher@\forest@pack@tiers@cpo@aremainingtier}{#1}% + }{}% +} +\def\forest@pack@tiers@write{% + \forlistloop\forest@pack@tiers@write@forhandler\forest@tiers@processingorder +} +\def\forest@pack@tiers@write@forhandler#1{% + \forest@fornode{\csname forest@tiers@container@#1\endcsname}{% + \forest@pack@tiers@check{#1}% + }% + \xappto\forest@smuggle{% + \noexpand\listadd + \forestOm{\csname forest@tiers@container@#1\endcsname}{@tiers}% + {#1}% + }% +} + % checks if the tier is compatible with growth changes and calign=node/edge angle +\def\forest@pack@tiers@check#1{% + \def\forest@temp@currenttier{#1}% + \forest@node@foreachdescendant{% + \ifnum\forestove{grow}=\forestOve{\forestove{@parent}}{grow} + \else + \forest@pack@tiers@check@grow + \fi + \ifnum\forestove{n children}>1 + \forestoget{calign}\forest@temp + \ifx\forest@temp\forest@pack@tiers@check@nodeangle + \forest@pack@tiers@check@calign + \fi + \ifx\forest@temp\forest@pack@tiers@check@edgeangle + \forest@pack@tiers@check@calign + \fi + \fi + }% +} +\def\forest@pack@tiers@check@nodeangle{node angle}% +\def\forest@pack@tiers@check@edgeangle{edge angle}% +\def\forest@pack@tiers@check@grow{% + \forestoget{content}\forest@temp@content + \let\forest@temp@currentnode\forest@cn + \forest@node@foreachdescendant{% + \forestoget{tier}\forest@temp + \ifx\forest@temp@currenttier\forest@temp + \forest@pack@tiers@check@grow@error + \fi + }% +} +\def\forest@pack@tiers@check@grow@error{% + \PackageError{forest}{Tree growth direction changes in node \forest@temp@currentnode\space + (content: \forest@temp@content), while tier '\forest@temp' is specified for nodes both + out- and inside the subtree rooted in node \forest@temp@currentnode. This will not work.}{}% +} +\def\forest@pack@tiers@check@calign{% + \forest@node@foreachchild{% + \forestoget{tier}\forest@temp + \ifx\forest@temp@currenttier\forest@temp + \forest@pack@tiers@check@calign@warning + \fi + }% +} +\def\forest@pack@tiers@check@calign@warning{% + \PackageWarning{forest}{Potential option conflict: node \forestove{@parent} (content: + '\forestOve{\forestove{@parent}}{content}') was given 'calign=\forestove{calign}', while its + child \forest@cn\space (content: '\forestove{content}') was given 'tier=\forestove{tier}'. + The parent's 'calign' will only work if the child was the lowest node on its tier before the + alignment.}{} +} +\pgfdeclaregenericanchor{forestcomputenodeboundary}{% + \letcs\forest@temp@boundary@macro{forest@compute@node@boundary@#1}% + \ifcsname forest@compute@node@boundary@#1\endcsname + \csname forest@compute@node@boundary@#1\endcsname + \else + \forest@compute@node@boundary@rectangle + \fi + \pgfsyssoftpath@getcurrentpath\forest@temp + \global\let\forest@global@boundary\forest@temp +} +\def\forest@mt#1{% + \expandafter\pgfpointanchor\expandafter{\pgfreferencednodename}{#1}% + \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% +}% +\def\forest@lt#1{% + \expandafter\pgfpointanchor\expandafter{\pgfreferencednodename}{#1}% + \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% +}% +\def\forest@compute@node@boundary@coordinate{% + \forest@mt{center}% +} +\def\forest@compute@node@boundary@circle{% + \forest@mt{east}% + \forest@lt{north east}% + \forest@lt{north}% + \forest@lt{north west}% + \forest@lt{west}% + \forest@lt{south west}% + \forest@lt{south}% + \forest@lt{south east}% + \forest@lt{east}% +} +\def\forest@compute@node@boundary@rectangle{% + \forest@mt{south west}% + \forest@lt{south east}% + \forest@lt{north east}% + \forest@lt{north west}% + \forest@lt{south west}% +} +\def\forest@compute@node@boundary@diamond{% + \forest@mt{east}% + \forest@lt{north}% + \forest@lt{west}% + \forest@lt{south}% + \forest@lt{east}% +} +\let\forest@compute@node@boundary@ellipse\forest@compute@node@boundary@circle +\def\forest@compute@node@boundary@trapezium{% + \forest@mt{top right corner}% + \forest@lt{top left corner}% + \forest@lt{bottom left corner}% + \forest@lt{bottom right corner}% + \forest@lt{top right corner}% +} +\def\forest@compute@node@boundary@semicircle{% + \forest@mt{arc start}% + \forest@lt{north}% + \forest@lt{east}% + \forest@lt{north east}% + \forest@lt{apex}% + \forest@lt{north west}% + \forest@lt{west}% + \forest@lt{arc end}% + \forest@lt{arc start}% +} +\newloop\forest@computenodeboundary@loop +\csdef{forest@compute@node@boundary@regular polygon}{% + \forest@mt{corner 1}% + \c@pgf@counta=\sides\relax + \forest@computenodeboundary@loop + \ifnum\c@pgf@counta>0 + \forest@lt{corner \the\c@pgf@counta}% + \advance\c@pgf@counta-1 + \forest@computenodeboundary@repeat +}% +\def\forest@compute@node@boundary@star{% + \forest@mt{outer point 1}% + \c@pgf@counta=\totalstarpoints\relax + \divide\c@pgf@counta2 + \forest@computenodeboundary@loop + \ifnum\c@pgf@counta>0 + \forest@lt{inner point \the\c@pgf@counta}% + \forest@lt{outer point \the\c@pgf@counta}% + \advance\c@pgf@counta-1 + \forest@computenodeboundary@repeat +}% +\csdef{forest@compute@node@boundary@isosceles triangle}{% + \forest@mt{apex}% + \forest@lt{left corner}% + \forest@lt{right corner}% + \forest@lt{apex}% +} +\def\forest@compute@node@boundary@kite{% + \forest@mt{upper vertex}% + \forest@lt{left vertex}% + \forest@lt{lower vertex}% + \forest@lt{right vertex}% + \forest@lt{upper vertex}% +} +\def\forest@compute@node@boundary@dart{% + \forest@mt{tip}% + \forest@lt{left tail}% + \forest@lt{tail center}% + \forest@lt{right tail}% + \forest@lt{tip}% +} +\csdef{forest@compute@node@boundary@circular sector}{% + \forest@mt{sector center}% + \forest@lt{arc start}% + \forest@lt{arc center}% + \forest@lt{arc end}% + \forest@lt{sector center}% +} +\def\forest@compute@node@boundary@cylinder{% + \forest@mt{top}% + \forest@lt{after top}% + \forest@lt{before bottom}% + \forest@lt{bottom}% + \forest@lt{after bottom}% + \forest@lt{before top}% + \forest@lt{top}% +} +\cslet{forest@compute@node@boundary@forbidden sign}\forest@compute@node@boundary@circle +\cslet{forest@compute@node@boundary@magnifying glass}\forest@compute@node@boundary@circle +\def\forest@compute@node@boundary@cloud{% + \getradii + \forest@mt{puff 1}% + \c@pgf@counta=\puffs\relax + \forest@computenodeboundary@loop + \ifnum\c@pgf@counta>0 + \forest@lt{puff \the\c@pgf@counta}% + \advance\c@pgf@counta-1 + \forest@computenodeboundary@repeat +} +\def\forest@compute@node@boundary@starburst{ + \calculatestarburstpoints + \forest@mt{outer point 1}% + \c@pgf@counta=\totalpoints\relax + \divide\c@pgf@counta2 + \forest@computenodeboundary@loop + \ifnum\c@pgf@counta>0 + \forest@lt{inner point \the\c@pgf@counta}% + \forest@lt{outer point \the\c@pgf@counta}% + \advance\c@pgf@counta-1 + \forest@computenodeboundary@repeat +}% +\def\forest@compute@node@boundary@signal{% + \forest@mt{east}% + \forest@lt{south east}% + \forest@lt{south west}% + \forest@lt{west}% + \forest@lt{north west}% + \forest@lt{north east}% + \forest@lt{east}% +} +\def\forest@compute@node@boundary@tape{% + \forest@mt{north east}% + \forest@lt{60}% + \forest@lt{north}% + \forest@lt{120}% + \forest@lt{north west}% + \forest@lt{south west}% + \forest@lt{240}% + \forest@lt{south}% + \forest@lt{310}% + \forest@lt{south east}% + \forest@lt{north east}% +} +\csdef{forest@compute@node@boundary@single arrow}{% + \forest@mt{tip}% + \forest@lt{after tip}% + \forest@lt{after head}% + \forest@lt{before tail}% + \forest@lt{after tail}% + \forest@lt{before head}% + \forest@lt{before tip}% + \forest@lt{tip}% +} +\csdef{forest@compute@node@boundary@double arrow}{% + \forest@mt{tip 1}% + \forest@lt{after tip 1}% + \forest@lt{after head 1}% + \forest@lt{before head 2}% + \forest@lt{before tip 2}% + \forest@mt{tip 2}% + \forest@lt{after tip 2}% + \forest@lt{after head 2}% + \forest@lt{before head 1}% + \forest@lt{before tip 1}% + \forest@lt{tip 1}% +} +\csdef{forest@compute@node@boundary@arrow box}{% + \forest@mt{before north arrow}% + \forest@lt{before north arrow head}% + \forest@lt{before north arrow tip}% + \forest@lt{north arrow tip}% + \forest@lt{after north arrow tip}% + \forest@lt{after north arrow head}% + \forest@lt{after north arrow}% + \forest@lt{north east}% + \forest@lt{before east arrow}% + \forest@lt{before east arrow head}% + \forest@lt{before east arrow tip}% + \forest@lt{east arrow tip}% + \forest@lt{after east arrow tip}% + \forest@lt{after east arrow head}% + \forest@lt{after east arrow}% + \forest@lt{south east}% + \forest@lt{before south arrow}% + \forest@lt{before south arrow head}% + \forest@lt{before south arrow tip}% + \forest@lt{south arrow tip}% + \forest@lt{after south arrow tip}% + \forest@lt{after south arrow head}% + \forest@lt{after south arrow}% + \forest@lt{south west}% + \forest@lt{before west arrow}% + \forest@lt{before west arrow head}% + \forest@lt{before west arrow tip}% + \forest@lt{west arrow tip}% + \forest@lt{after west arrow tip}% + \forest@lt{after west arrow head}% + \forest@lt{after west arrow}% + \forest@lt{north west}% + \forest@lt{before north arrow}% +} +\cslet{forest@compute@node@boundary@circle split}\forest@compute@node@boundary@circle +\cslet{forest@compute@node@boundary@circle solidus}\forest@compute@node@boundary@circle +\cslet{forest@compute@node@boundary@ellipse split}\forest@compute@node@boundary@ellipse +\cslet{forest@compute@node@boundary@rectangle split}\forest@compute@node@boundary@rectangle +\def\forest@compute@node@boundary@@callout{% + \beforecalloutpointer + \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% + \calloutpointeranchor + \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% + \aftercalloutpointer + \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% +} +\csdef{forest@compute@node@boundary@rectangle callout}{% + \forest@compute@node@boundary@rectangle + \rectanglecalloutpoints + \forest@compute@node@boundary@@callout +} +\csdef{forest@compute@node@boundary@ellipse callout}{% + \forest@compute@node@boundary@ellipse + \ellipsecalloutpoints + \forest@compute@node@boundary@@callout +} +\csdef{forest@compute@node@boundary@cloud callout}{% + \forest@compute@node@boundary@cloud + % at least a first approx... + \forest@mt{center}% + \forest@lt{pointer}% +}% +\csdef{forest@compute@node@boundary@cross out}{% + \forest@mt{south east}% + \forest@lt{north west}% + \forest@mt{south west}% + \forest@lt{north east}% +}% +\csdef{forest@compute@node@boundary@strike out}{% + \forest@mt{north east}% + \forest@lt{south west}% +}% +\cslet{forest@compute@node@boundary@rounded rectangle}\forest@compute@node@boundary@rectangle +\csdef{forest@compute@node@boundary@chamfered rectangle}{% + \forest@mt{before south west}% + \forest@mt{after south west}% + \forest@lt{before south east}% + \forest@lt{after south east}% + \forest@lt{before north east}% + \forest@lt{after north east}% + \forest@lt{before north west}% + \forest@lt{after north west}% + \forest@lt{before south west}% +}% +\def\forest@node@computeabsolutepositions{% + \forestoset{x}{0pt}% + \forestoset{y}{0pt}% + \edef\forest@marshal{% + \noexpand\forest@node@foreachchild{% + \noexpand\forest@node@computeabsolutepositions@{0pt}{0pt}{\forestove{grow}}% + }% + }\forest@marshal +} +\def\forest@node@computeabsolutepositions@#1#2#3{% + \pgfpointadd{\pgfpoint{#1}{#2}}{% + \pgfpointadd{\pgfpolar{#3}{\forestove{l}}}{\pgfpolar{90 + #3}{\forestove{s}}}}% + \pgfgetlastxy\forest@temp@x\forest@temp@y + \forestolet{x}\forest@temp@x + \forestolet{y}\forest@temp@y + \edef\forest@marshal{% + \noexpand\forest@node@foreachchild{% + \noexpand\forest@node@computeabsolutepositions@{\forest@temp@x}{\forest@temp@y}{\forestove{grow}}% + }% + }\forest@marshal +} +\newif\ifforest@drawtree@preservenodeboxes@ +\def\forest@node@drawtree{% + \expandafter\ifstrequal\expandafter{\forest@drawtreebox}{\pgfkeysnovalue}{% + \let\forest@drawtree@beginbox\relax + \let\forest@drawtree@endbox\relax + }{% + \edef\forest@drawtree@beginbox{\global\setbox\forest@drawtreebox=\hbox\bgroup}% + \let\forest@drawtree@endbox\egroup + }% + \ifforest@external@ + \ifforest@externalize@tree@ + \forest@temptrue + \else + \tikzifexternalizing{% + \ifforest@was@tikzexternalwasenable + \forest@temptrue + \pgfkeys{/tikz/external/optimize=false}% + \let\forest@drawtree@beginbox\relax + \let\forest@drawtree@endbox\relax + \else + \forest@tempfalse + \fi + }{% + \forest@tempfalse + }% + \fi + \ifforest@temp + \advance\forest@externalize@inner@n 1 + \edef\forest@externalize@filename{% + \tikzexternalrealjob-forest-\forest@externalize@outer@n + \ifnum\forest@externalize@inner@n=0 \else.\the\forest@externalize@inner@n\fi}% + \expandafter\tikzsetnextfilename\expandafter{\forest@externalize@filename}% + \tikzexternalenable + \pgfkeysalso{/tikz/external/remake next,/tikz/external/export next}% + \fi + \ifforest@externalize@tree@ + \typeout{forest: Invoking a recursive call to generate the external picture + '\forest@externalize@filename' for the following context+code: + '\expandafter\detokenize\expandafter{\forest@externalize@id}'}% + \fi + \fi + % + \ifforesttikzcshack + \let\forest@original@tikz@parse@node\tikz@parse@node + \let\tikz@parse@node\forest@tikz@parse@node + \fi + \forest@drawtree@beginbox + \tikz{% + \forestove{tikz preamble}% + \forest@node@drawtree@ + }% + \forest@drawtree@endbox + \ifforesttikzcshack + \let\tikz@parse@node\forest@original@tikz@parse@node + \fi + % + \ifforest@external@ + \ifforest@externalize@tree@ + \tikzexternaldisable + \eappto\forest@externalize@checkimages{% + \noexpand\forest@includeexternal@check{\forest@externalize@filename}% + }% + \expandafter\ifstrequal\expandafter{\forest@drawtreebox}{\pgfkeysnovalue}{% + \eappto\forest@externalize@loadimages{% + \noexpand\forest@includeexternal{\forest@externalize@filename}% + }% + }{% + \eappto\forest@externalize@loadimages{% + \noexpand\forest@includeexternal@box\forest@drawtreebox{\forest@externalize@filename}% + }% + }% + \fi + \fi +} +\def\forest@node@drawtree@{% + \forest@node@foreach{\forest@draw@node}% + \forest@node@Ifnamedefined{forest@baseline@node}{% + \edef\forest@temp{% + \noexpand\pgfsetbaselinepointlater{% + \noexpand\pgfpointanchor + {\forestOve{\forest@node@Nametoid{forest@baseline@node}}{name}} + {\forestOve{\forest@node@Nametoid{forest@baseline@node}}{anchor}} + }% + }\forest@temp + }{}% + \forest@node@foreachdescendant{\forest@draw@edge}% + \forest@node@foreach{\forest@draw@tikz}% +} +\def\forest@draw@node{% + \ifnum\forestove{phantom}=0 + \forest@node@forest@positionnodelater@restore + \ifforest@drawtree@preservenodeboxes@ + \pgfnodealias{forest@temp}{\forestove{later@name}}% + \fi + \pgfpositionnodenow{\pgfqpoint{\forestove{x}}{\forestove{y}}}% + \ifforest@drawtree@preservenodeboxes@ + \pgfnodealias{\forestove{later@name}}{forest@temp}% + \fi + \fi +} +\def\forest@draw@edge{% + \ifnum\forestove{phantom}=0 + \ifnum\forestOve{\forestove{@parent}}{phantom}=0 + \edef\forest@temp{\forestove{edge path}}% + \forest@temp + \fi + \fi +} +\def\forest@draw@tikz{% + \forestove{tikz}% +} +\def\forest@tikz@parse@node#1(#2){% + \pgfutil@in@.{#2}% + \ifpgfutil@in@ + \expandafter\forest@tikz@parse@node@checkiftikzname@withdot + \else% + \expandafter\forest@tikz@parse@node@checkiftikzname@withoutdot + \fi% + #1(#2)\forest@end +} +\def\forest@tikz@parse@node@checkiftikzname@withdot#1(#2.#3)\forest@end{% + \forest@tikz@parse@node@checkiftikzname#1{#2}{.#3}} +\def\forest@tikz@parse@node@checkiftikzname@withoutdot#1(#2)\forest@end{% + \forest@tikz@parse@node@checkiftikzname#1{#2}{}} +\def\forest@tikz@parse@node@checkiftikzname#1#2#3{% + \expandafter\ifx\csname pgf@sh@ns@#2\endcsname\relax + \forest@forthis{% + \forest@nameandgo{#2}% + \edef\forest@temp@relativenodename{\forestove{name}}% + }% + \else + \def\forest@temp@relativenodename{#2}% + \fi + \expandafter\forest@original@tikz@parse@node\expandafter#1\expandafter(\forest@temp@relativenodename#3)% +} +\def\forest@nameandgo#1{% + \pgfutil@in@!{#1}% + \ifpgfutil@in@ + \forest@nameandgo@(#1)% + \else + \ifstrempty{#1}{}{\edef\forest@cn{\forest@node@Nametoid{#1}}}% + \fi +} +\def\forest@nameandgo@(#1!#2){% + \ifstrempty{#1}{}{\edef\forest@cn{\forest@node@Nametoid{#1}}}% + \forest@go{#2}% +} +\pgfdeclaregenericanchor{parent anchor}{% + \forest@generic@parent@child@anchor{parent }{#1}} +\pgfdeclaregenericanchor{child anchor}{% + \forest@generic@parent@child@anchor{child }{#1}} +\pgfdeclaregenericanchor{anchor}{% + \forest@generic@parent@child@anchor{}{#1}} +\def\forest@generic@parent@child@anchor#1#2{% + \forestOget{\forest@node@Nametoid{\pgfreferencednodename}}{#1anchor}\forest@temp@parent@anchor + \ifdefempty\forest@temp@parent@anchor{% + \pgf@sh@reanchor{#2}{center}% + \xdef\forest@hack@tikzshapeborder{% + \noexpand\tikz@shapebordertrue + \def\noexpand\tikz@shapeborder@name{\pgfreferencednodename}% + }\aftergroup\forest@hack@tikzshapeborder + }{% + \pgf@sh@reanchor{#2}{\forest@temp@parent@anchor}% + }% +} +\newdimen\forest@xg +\newdimen\forest@yg +\newdimen\forest@xs +\newdimen\forest@ys +\def\forest@setupgrowline#1{% + \edef\forest@grow{#1}% + \pgfpointpolar\forest@grow{1pt}% + \forest@xg=\pgf@x + \forest@yg=\pgf@y + \forest@xs=-\pgf@y + \forest@ys=\pgf@x +} +\def\forest@pgfpointprojectiontogrowline#1{{% + \pgf@process{#1}% + \pgfutil@tempdima=\pgf@sys@tonumber{\pgf@x}\forest@xg% + \advance\pgfutil@tempdima by\pgf@sys@tonumber{\pgf@y}\forest@yg% + \global\pgf@x=\pgf@sys@tonumber{\pgfutil@tempdima}\forest@xg% + \global\pgf@y=\pgf@sys@tonumber{\pgfutil@tempdima}\forest@yg% +}} +\def\forest@distancetogrowline#1#2{% + \pgf@process{#2}% + #1=\pgf@sys@tonumber{\pgf@x}\forest@xs\relax + \advance#1 by\pgf@sys@tonumber{\pgf@y}\forest@ys\relax +} +\let\forest@pp@n\relax +\def\forest@projectpathtogrowline#1#2{% + \edef\forest@pp@prefix{#2}% + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@projectpath@processpoint + \let\pgfsyssoftpath@linetotoken\forest@projectpath@processpoint + \c@pgf@counta=0 + #1% + \csedef{#2n}{\the\c@pgf@counta}% + \forest@restore@pgfsyssoftpath@tokendefs +} +\def\forest@projectpath@processpoint#1#2{% + \pgfqpoint{#1}{#2}% + \expandafter\edef\csname\forest@pp@prefix\the\c@pgf@counta xo\endcsname{\the\pgf@x}% + \expandafter\edef\csname\forest@pp@prefix\the\c@pgf@counta yo\endcsname{\the\pgf@y}% + \forest@pgfpointprojectiontogrowline{}% + \expandafter\edef\csname\forest@pp@prefix\the\c@pgf@counta xp\endcsname{\the\pgf@x}% + \expandafter\edef\csname\forest@pp@prefix\the\c@pgf@counta yp\endcsname{\the\pgf@y}% + \advance\c@pgf@counta 1\relax +} +\def\forest@sortprojections#1{% + % todo: optimize in cases when we know that the array is actually a + % merger of sorted arrays; when does this happen? in + % distance_between_paths, and when merging the edges of the parent + % and its children in a uniform growth tree + \edef\forest@ppi@inputprefix{#1}% + \c@pgf@counta=\csname#1n\endcsname\relax + \advance\c@pgf@counta -1 + \forest@sort\forest@ppiraw@cmp\forest@ppiraw@let\forest@sort@ascending{0}{\the\c@pgf@counta}% +} +\def\forest@processprojectioninfo#1#2{% + \edef\forest@ppi@inputprefix{#1}% + \c@pgf@counta=0 + \c@pgf@countb=-1 + \loop + \ifnum\c@pgf@counta<\csname#1n\endcsname\relax + \letcs\forest@xo{#1\the\c@pgf@counta xo}% + \letcs\forest@yo{#1\the\c@pgf@counta yo}% + \letcs\forest@xp{#1\the\c@pgf@counta xp}% + \letcs\forest@yp{#1\the\c@pgf@counta yp}% + \ifnum\c@pgf@countb<0 + \forest@equaltotolerancefalse + \else + \forest@equaltotolerance + {\pgfqpoint\forest@xp\forest@yp}% + {\pgfqpoint + {\csname#2\the\c@pgf@countb x\endcsname}% + {\csname#2\the\c@pgf@countb y\endcsname}% + }% + \fi + \ifforest@equaltotolerance\else + \advance\c@pgf@countb 1 + \cslet{#2\the\c@pgf@countb x}\forest@xp + \cslet{#2\the\c@pgf@countb y}\forest@yp + \csdef{#2\the\c@pgf@countb @n}{0}% + \fi + % todo: this is ugly! + \ifdefined\forest@xo\ifx\forest@xo\relax\else + \ifdefined\forest@yo\ifx\forest@yo\relax\else + \forest@append@point@to@inner@array + \forest@xo\forest@yo + {#2\the\c@pgf@countb @}% + \csedef{#2(\forest@xo,\forest@yo)}{\the\c@pgf@countb}% + \fi\fi + \fi\fi + \cslet{#1\the\c@pgf@counta xo}\relax + \cslet{#1\the\c@pgf@counta yo}\relax + \cslet{#1\the\c@pgf@counta xp}\relax + \cslet{#1\the\c@pgf@counta yp}\relax + \advance\c@pgf@counta 1 + \repeat + \cslet{#1n}\relax + \advance\c@pgf@countb 1 + \csedef{#2n}{\the\c@pgf@countb}% +} +\def\forest@ppiraw@let#1#2{% + \csletcs{\forest@ppi@inputprefix#1xo}{\forest@ppi@inputprefix#2xo}% + \csletcs{\forest@ppi@inputprefix#1yo}{\forest@ppi@inputprefix#2yo}% + \csletcs{\forest@ppi@inputprefix#1xp}{\forest@ppi@inputprefix#2xp}% + \csletcs{\forest@ppi@inputprefix#1yp}{\forest@ppi@inputprefix#2yp}% +} +\def\forest@ppiraw@cmp#1#2{% + \forest@sort@cmptwodimcs + {\forest@ppi@inputprefix#1xp}{\forest@ppi@inputprefix#1yp}% + {\forest@ppi@inputprefix#2xp}{\forest@ppi@inputprefix#2yp}% +} +\def\forest@append@point@to@inner@array#1#2#3{% + \c@pgf@countc=\csname#3n\endcsname\relax + \csedef{#3\the\c@pgf@countc x}{#1}% + \csedef{#3\the\c@pgf@countc y}{#2}% + \forest@distancetogrowline\pgfutil@tempdima{\pgfqpoint#1#2}% + \csedef{#3\the\c@pgf@countc d}{\the\pgfutil@tempdima}% + \advance\c@pgf@countc 1 + \csedef{#3n}{\the\c@pgf@countc}% +} +\def\forest@breakpath#1#2#3{% + \edef\forest@bp@prefix{#2}% + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@breakpath@processfirstpoint + \let\pgfsyssoftpath@linetotoken\forest@breakpath@processfirstpoint + %\pgfusepath{}% empty the current path. ok? + #1% + \forest@restore@pgfsyssoftpath@tokendefs + \pgfsyssoftpath@getcurrentpath#3% +} +\def\forest@breakpath@processfirstpoint#1#2{% + \forest@breakpath@processmoveto{#1}{#2}% + \let\pgfsyssoftpath@movetotoken\forest@breakpath@processmoveto + \let\pgfsyssoftpath@linetotoken\forest@breakpath@processlineto +} +\def\forest@breakpath@processmoveto#1#2{% + \pgfsyssoftpath@moveto{#1}{#2}% + \def\forest@previous@x{#1}% + \def\forest@previous@y{#2}% + \expandafter\let\expandafter\forest@previous@i + \csname\forest@bp@prefix(#1,#2)\endcsname + \expandafter\let\expandafter\forest@previous@px + \csname\forest@bp@prefix\forest@previous@i x\endcsname + \expandafter\let\expandafter\forest@previous@py + \csname\forest@bp@prefix\forest@previous@i y\endcsname +} +\def\forest@breakpath@processlineto#1#2{% + \let\forest@breakpath@op\pgfsyssoftpath@lineto + \expandafter\let\expandafter\forest@i + \csname\forest@bp@prefix(#1,#2)\endcsname + \expandafter\let\expandafter\forest@px + \csname\forest@bp@prefix\forest@i x\endcsname + \expandafter\let\expandafter\forest@py + \csname\forest@bp@prefix\forest@i y\endcsname + \forest@equaltotolerance + {\pgfqpoint{\forest@previous@px}{\forest@previous@py}}% + {\pgfqpoint{\forest@px}{\forest@py}}% + \ifforest@equaltotolerance + \let\forest@breakpath@op\pgfsyssoftpath@moveto + \else + \forest@temp@count=\forest@previous@i\relax + \ifnum\forest@previous@i<\forest@i\relax + \def\forest@breakpath@step{1}% + \def\forest@breakpath@test{\forest@temp@count<\forest@i\relax}% + \else + \def\forest@breakpath@step{-1}% + \def\forest@breakpath@test{\forest@temp@count>\forest@i\relax}% + \fi + \loop + \advance\forest@temp@count\forest@breakpath@step\relax + \expandafter\ifnum\forest@breakpath@test + \pgfpointintersectionoflines + {\pgfqpoint + {\csname\forest@bp@prefix\the\forest@temp@count x\endcsname}% + {\csname\forest@bp@prefix\the\forest@temp@count y\endcsname}% + }% + {\pgfpointadd + {\pgfqpoint + {\csname\forest@bp@prefix\the\forest@temp@count x\endcsname}% + {\csname\forest@bp@prefix\the\forest@temp@count y\endcsname}% + }% + {\pgfqpoint{\forest@xs}{\forest@ys}}% + }% + {\pgfqpoint{\forest@previous@x}{\forest@previous@y}}% + {\pgfqpoint{#1}{#2}}% + \pgfgetlastxy\forest@last@x\forest@last@y + \pgfsyssoftpath@lineto\forest@last@x\forest@last@y + \forest@append@point@to@inner@array + \forest@last@x\forest@last@y + {\forest@bp@prefix\the\forest@temp@count @}% + \csedef{\forest@bp@prefix(\the\pgf@x,\the\pgf@y)}{\the\forest@temp@count}% + \repeat + \fi + \forest@breakpath@op{#1}{#2}% + \def\forest@previous@x{#1}% + \def\forest@previous@y{#2}% + \let\forest@previous@i\forest@i + \let\forest@previous@px\forest@px + \let\forest@previous@py\forest@py +} +\def\forest@getnegativetightedgeofpath#1#2{% + \forest@get@onetightedgeofpath#1\forest@sort@ascending#2} +\def\forest@getpositivetightedgeofpath#1#2{% + \forest@get@onetightedgeofpath#1\forest@sort@descending#2} +\def\forest@get@onetightedgeofpath#1#2#3{% + {% + \forest@get@one@tightedgeofpath#1#2\forest@gep@edge + \global\let\forest@gep@global@edge\forest@gep@edge + }% + \let#3\forest@gep@global@edge +} +\def\forest@get@one@tightedgeofpath#1#2#3{% + \forest@projectpathtogrowline#1{forest@pp@}% + \forest@sortprojections{forest@pp@}% + \forest@processprojectioninfo{forest@pp@}{forest@pi@}% + \forest@breakpath#1{forest@pi@}\forest@brokenpath + \forest@sort@inner@arrays{forest@pi@}#2% + \forest@pathtodict\forest@brokenpath{forest@pi@}% + \forest@gettightedgeofpath@getedge + \pgfsyssoftpath@getcurrentpath\forest@edge + \forest@simplifypath\forest@edge#3% +} +\def\forest@getbothtightedgesofpath#1#2#3{% + {% + \forest@get@one@tightedgeofpath#1\forest@sort@ascending\forest@gep@firstedge + \c@pgf@counta=0 + \loop + \ifnum\c@pgf@counta<\forest@pi@n\relax + \forest@ppi@deflet{forest@pi@\the\c@pgf@counta @}% + \forest@reversearray\forest@ppi@let + {0}% + {\csname forest@pi@\the\c@pgf@counta @n\endcsname}% + \advance\c@pgf@counta 1 + \repeat + \forest@gettightedgeofpath@getedge + \pgfsyssoftpath@getcurrentpath\forest@edge + \forest@simplifypath\forest@edge\forest@gep@secondedge + \global\let\forest@gep@global@firstedge\forest@gep@firstedge + \global\let\forest@gep@global@secondedge\forest@gep@secondedge + }% + \let#2\forest@gep@global@firstedge + \let#3\forest@gep@global@secondedge +} +\def\forest@sort@inner@arrays#1#2{% + \c@pgf@counta=0 + \forest@loopa + \ifnum\c@pgf@counta<\csname#1n\endcsname + \c@pgf@countb=\csname#1\the\c@pgf@counta @n\endcsname\relax + \ifnum\c@pgf@countb>1 + \advance\c@pgf@countb -1 + \forest@ppi@deflet{#1\the\c@pgf@counta @}% + \forest@ppi@defcmp{#1\the\c@pgf@counta @}% + \forest@sort\forest@ppi@cmp\forest@ppi@let#2{0}{\the\c@pgf@countb}% + \fi + \advance\c@pgf@counta 1 + \forest@repeata +} +\def\forest@ppi@deflet#1{% + \edef\forest@ppi@let##1##2{% + \noexpand\csletcs{#1##1x}{#1##2x}% + \noexpand\csletcs{#1##1y}{#1##2y}% + \noexpand\csletcs{#1##1d}{#1##2d}% + }% +} +\def\forest@ppi@defcmp#1{% + \edef\forest@ppi@cmp##1##2{% + \noexpand\forest@sort@cmpdimcs{#1##1d}{#1##2d}% + }% +} +\let\forest@inpath\advance +\def\forest@pathtodict#1#2{% + \edef\forest@pathtodict@prefix{#2}% + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@pathtodict@movetoop + \let\pgfsyssoftpath@linetotoken\forest@pathtodict@linetoop + \def\forest@pathtodict@subpathstart{}% + #1% + \forest@restore@pgfsyssoftpath@tokendefs +} +\def\forest@pathtodict@movetoop#1#2{% + \def\forest@pathtodict@subpathstart{(#1,#2)-}% +} +\def\forest@pathtodict@linetoop#1#2{% +\if\relax\forest@pathtodict@subpathstart\relax\else + \let\forest@pathtodict@from\forest@pathtodict@subpathstart + \fi + \expandafter\let\csname\forest@pathtodict@prefix\forest@pathtodict@from-(#1,#2)\endcsname\forest@inpath + \def\forest@pathtodict@from{(#1,#2)-}% + \def\forest@pathtodict@subpathstart{}% +} +\def\forest@gettightedgeofpath@getedge{% + \pgfsyssoftpath@setcurrentpath\pgfutil@empty + \let\forest@last@x\relax + \let\forest@last@y\relax + \c@pgf@counta=0 + \forest@temp@count=\forest@pi@n\relax + \advance\forest@temp@count -1 + \edef\forest@nminusone{\the\forest@temp@count}% + \forest@loopa + \ifnum\c@pgf@counta<\forest@nminusone\relax + \forest@gettightedgeofpath@getedge@loopa + \forest@repeata + \ifnum\forest@nminusone<\forest@n\relax\else + \ifnum\csname forest@pi@\forest@nminusone @n\endcsname>0 + \forest@gettightedgeofpath@maybemoveto{\forest@nminusone}{0}% + \fi + \fi +} +\def\forest@gettightedgeofpath@getedge@loopa{% + \ifnum\csname forest@pi@\the\c@pgf@counta @n\endcsname>0 + \forest@gettightedgeofpath@maybemoveto{\the\c@pgf@counta}{0}% + \c@pgf@countb=0 + \forest@loopb + \ifnum\c@pgf@countb<\csname forest@pi@\the\c@pgf@counta @n\endcsname\relax + \forest@gettightedgeofpath@getedge@loopb + \forest@repeatb + \fi + \advance\c@pgf@counta 1 +} +\def\forest@gettightedgeofpath@getedge@loopb{% + \c@pgf@countc=0 + \advance\c@pgf@counta 1 + \edef\forest@aplusone{\the\c@pgf@counta}% + \advance\c@pgf@counta -1 + \forest@loopc + \ifnum\c@pgf@countc<\csname forest@pi@\forest@aplusone @n\endcsname\relax + \forest@tempfalse + \expandafter\ifx\csname forest@pi@(% + \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% + \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb y\endcsname)--(% + \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% + \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname)% + \endcsname\forest@inpath + \forest@temptrue + \else + \expandafter\ifx\csname forest@pi@(% + \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% + \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname)--(% + \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% + \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb y\endcsname)% + \endcsname\forest@inpath + \forest@temptrue + \fi + \fi + \ifforest@temp + \forest@gettightedgeofpath@maybemoveto{\the\c@pgf@counta}{\the\c@pgf@countb}% + \edef\forest@last@x{% + \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname}% + \edef\forest@last@y{% + \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname}% + \pgfsyssoftpath@lineto\forest@last@x\forest@last@y + \c@pgf@countc=\csname forest@pi@\forest@aplusone @n\endcsname + \c@pgf@countb=\csname forest@pi@\the\c@pgf@counta @n\endcsname + \fi + \advance\c@pgf@countc 1 + \forest@repeatc + \advance\c@pgf@countb 1 +} +\def\forest@gettightedgeofpath@maybemoveto#1#2{% + \forest@temptrue + \ifx\forest@last@x\relax\else + \ifdim\forest@last@x=\csname forest@pi@#1@#2x\endcsname\relax + \ifdim\forest@last@y=\csname forest@pi@#1@#2y\endcsname\relax + \forest@tempfalse + \fi + \fi + \fi + \ifforest@temp + \edef\forest@last@x{\csname forest@pi@#1@#2x\endcsname}% + \edef\forest@last@y{\csname forest@pi@#1@#2y\endcsname}% + \pgfsyssoftpath@moveto\forest@last@x\forest@last@y + \fi +} +\def\forest@simplifypath#1#2{% + \pgfsyssoftpath@setcurrentpath\pgfutil@empty + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@simplifypath@moveto + \let\pgfsyssoftpath@linetotoken\forest@simplifypath@lineto + \let\forest@last@x\relax + \let\forest@last@y\relax + \let\forest@last@atan\relax + #1% + \ifx\forest@last@x\relax\else + \ifx\forest@last@atan\relax\else + \pgfsyssoftpath@lineto\forest@last@x\forest@last@y + \fi + \fi + \forest@restore@pgfsyssoftpath@tokendefs + \pgfsyssoftpath@getcurrentpath#2% +} +\def\forest@simplifypath@moveto#1#2{% + \ifx\forest@last@x\relax\else + \pgfsyssoftpath@lineto\forest@last@x\forest@last@y + \fi + \pgfsyssoftpath@moveto{#1}{#2}% + \def\forest@last@x{#1}% + \def\forest@last@y{#2}% + \let\forest@last@atan\relax +} +\def\forest@getedgeofpath@precision{1pt} +\def\forest@simplifypath@lineto#1#2{% + \ifx\forest@last@x\relax + \def\forest@last@x{#1}% + \def\forest@last@y{#2}% + \let\forest@last@atan\relax + \else + \pgfpointdiff{\pgfqpoint{#1}{#2}}{\pgfqpoint{\forest@last@x}{\forest@last@y}}% + \ifdim\pgf@x<\pgfintersectiontolerance + \ifdim-\pgf@x<\pgfintersectiontolerance + \pgf@x=0pt + \fi + \fi + \csname pgfmathatan2\endcsname{\pgf@x}{\pgf@y}% + \let\forest@current@atan\pgfmathresult + \ifx\forest@last@atan\relax + \def\forest@last@x{#1}% + \def\forest@last@y{#2}% + \let\forest@last@atan\forest@current@atan + \else + \pgfutil@tempdima=\forest@current@atan pt + \advance\pgfutil@tempdima -\forest@last@atan pt + \ifdim\pgfutil@tempdima<0pt\relax + \multiply\pgfutil@tempdima -1 + \fi + \ifdim\pgfutil@tempdima<\forest@getedgeofpath@precision\relax + \else + \pgfsyssoftpath@lineto\forest@last@x\forest@last@y + \let\forest@last@atan\forest@current@atan + \fi + \def\forest@last@x{#1}% + \def\forest@last@y{#2}% + \fi + \fi +} +\def\forest@getnegativerectangleedgeofpath#1#2{% + \forest@getnegativerectangleorbandedgeofpath{#1}{#2}{\the\pgf@xb}} +\def\forest@getpositiverectangleedgeofpath#1#2{% + \forest@getpositiverectangleorbandedgeofpath{#1}{#2}{\the\pgf@xb}} +\def\forest@getbothrectangleedgesofpath#1#2#3{% + \forest@getbothrectangleorbandedgesofpath{#1}{#2}{#3}{\the\pgf@xb}} +\def\forest@bandlength{5000pt} % something large (ca. 180cm), but still manageable for TeX without producing `too large' errors +\def\forest@getnegativebandedgeofpath#1#2{% + \forest@getnegativerectangleorbandedgeofpath{#1}{#2}{\forest@bandlength}} +\def\forest@getpositivebandedgeofpath#1#2{% + \forest@getpositiverectangleorbandedgeofpath{#1}{#2}{\forest@bandlength}} +\def\forest@getbothbandedgesofpath#1#2#3{% + \forest@getbothrectangleorbandedgesofpath{#1}{#2}{#3}{\forest@bandlength}} +\def\forest@getnegativerectangleorbandedgeofpath#1#2#3{% + \forest@path@getboundingrectangle@ls#1{\forest@grow}% + \edef\forest@gre@path{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{#3}{\the\pgf@ya}% + }% + {% + \pgftransformreset + \pgftransformrotate{\forest@grow}% + \forest@pgfpathtransformed\forest@gre@path + }% + \pgfsyssoftpath@getcurrentpath#2% +} +\def\forest@getpositiverectangleorbandedgeofpath#1#2#3{% + \forest@path@getboundingrectangle@ls#1{\forest@grow}% + \edef\forest@gre@path{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@xa}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@linetotoken{#3}{\the\pgf@yb}% + }% + {% + \pgftransformreset + \pgftransformrotate{\forest@grow}% + \forest@pgfpathtransformed\forest@gre@path + }% + \pgfsyssoftpath@getcurrentpath#2% +} +\def\forest@getbothrectangleorbandedgesofpath#1#2#3#4{% + \forest@path@getboundingrectangle@ls#1{\forest@grow}% + \edef\forest@gre@negpath{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@linetotoken{#4}{\the\pgf@ya}% + }% + \edef\forest@gre@pospath{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@xa}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@linetotoken{#4}{\the\pgf@yb}% + }% + {% + \pgftransformreset + \pgftransformrotate{\forest@grow}% + \forest@pgfpathtransformed\forest@gre@negpath + }% + \pgfsyssoftpath@getcurrentpath#2% + {% + \pgftransformreset + \pgftransformrotate{\forest@grow}% + \forest@pgfpathtransformed\forest@gre@pospath + }% + \pgfsyssoftpath@getcurrentpath#3% +} +\def\forest@distance@between@edge@paths#1#2#3{% + % #1, #2 = (edge) paths + % + % project paths + \forest@projectpathtogrowline#1{forest@p1@}% + \forest@projectpathtogrowline#2{forest@p2@}% + % merge projections (the lists are sorted already, because edge + % paths are |sorted|) + \forest@dbep@mergeprojections + {forest@p1@}{forest@p2@}% + {forest@P1@}{forest@P2@}% + % process projections + \forest@processprojectioninfo{forest@P1@}{forest@PI1@}% + \forest@processprojectioninfo{forest@P2@}{forest@PI2@}% + % break paths + \forest@breakpath#1{forest@PI1@}\forest@broken@one + \forest@breakpath#2{forest@PI2@}\forest@broken@two + % sort inner arrays ---optimize: it's enough to find max and min + \forest@sort@inner@arrays{forest@PI1@}\forest@sort@descending + \forest@sort@inner@arrays{forest@PI2@}\forest@sort@ascending + % compute the distance + \let\forest@distance\relax + \c@pgf@countc=0 + \loop + \ifnum\c@pgf@countc<\csname forest@PI1@n\endcsname\relax + \ifnum\csname forest@PI1@\the\c@pgf@countc @n\endcsname=0 \else + \ifnum\csname forest@PI2@\the\c@pgf@countc @n\endcsname=0 \else + \pgfutil@tempdima=\csname forest@PI2@\the\c@pgf@countc @0d\endcsname\relax + \advance\pgfutil@tempdima -\csname forest@PI1@\the\c@pgf@countc @0d\endcsname\relax + \ifx\forest@distance\relax + \edef\forest@distance{\the\pgfutil@tempdima}% + \else + \ifdim\pgfutil@tempdima<\forest@distance\relax + \edef\forest@distance{\the\pgfutil@tempdima}% + \fi + \fi + \fi + \fi + \advance\c@pgf@countc 1 + \repeat + \let#3\forest@distance +} + % merge projections: we need two projection arrays, both containing + % projection points from both paths, but each with the original + % points from only one path +\def\forest@dbep@mergeprojections#1#2#3#4{% + % TODO: optimize: v bistvu ni treba sortirat, ker je edge path že sortiran + \forest@sortprojections{#1}% + \forest@sortprojections{#2}% + \c@pgf@counta=0 + \c@pgf@countb=0 + \c@pgf@countc=0 + \edef\forest@input@prefix@one{#1}% + \edef\forest@input@prefix@two{#2}% + \edef\forest@output@prefix@one{#3}% + \edef\forest@output@prefix@two{#4}% + \forest@dbep@mp@iterate + \csedef{#3n}{\the\c@pgf@countc}% + \csedef{#4n}{\the\c@pgf@countc}% +} +\def\forest@dbep@mp@iterate{% + \let\forest@dbep@mp@next\forest@dbep@mp@iterate + \ifnum\c@pgf@counta<\csname\forest@input@prefix@one n\endcsname\relax + \ifnum\c@pgf@countb<\csname\forest@input@prefix@two n\endcsname\relax + \let\forest@dbep@mp@next\forest@dbep@mp@do + \else + \let\forest@dbep@mp@next\forest@dbep@mp@iteratefirst + \fi + \else + \ifnum\c@pgf@countb<\csname\forest@input@prefix@two n\endcsname\relax + \let\forest@dbep@mp@next\forest@dbep@mp@iteratesecond + \else + \let\forest@dbep@mp@next\relax + \fi + \fi + \forest@dbep@mp@next +} +\def\forest@dbep@mp@do{% + \forest@sort@cmptwodimcs% + {\forest@input@prefix@one\the\c@pgf@counta xp}% + {\forest@input@prefix@one\the\c@pgf@counta yp}% + {\forest@input@prefix@two\the\c@pgf@countb xp}% + {\forest@input@prefix@two\the\c@pgf@countb yp}% + \if\forest@sort@cmp@result=% + \forest@dbep@mp@@store@p\forest@input@prefix@one\c@pgf@counta + \forest@dbep@mp@@store@o\forest@input@prefix@one + \c@pgf@counta\forest@output@prefix@one + \forest@dbep@mp@@store@o\forest@input@prefix@two + \c@pgf@countb\forest@output@prefix@two + \advance\c@pgf@counta 1 + \advance\c@pgf@countb 1 + \else + \if\forest@sort@cmp@result>% + \forest@dbep@mp@@store@p\forest@input@prefix@two\c@pgf@countb + \forest@dbep@mp@@store@o\forest@input@prefix@two + \c@pgf@countb\forest@output@prefix@two + \advance\c@pgf@countb 1 + \else%< + \forest@dbep@mp@@store@p\forest@input@prefix@one\c@pgf@counta + \forest@dbep@mp@@store@o\forest@input@prefix@one + \c@pgf@counta\forest@output@prefix@one + \advance\c@pgf@counta 1 + \fi + \fi + \advance\c@pgf@countc 1 + \forest@dbep@mp@iterate +} +\def\forest@dbep@mp@@store@p#1#2{% + \csletcs + {\forest@output@prefix@one\the\c@pgf@countc xp}% + {#1\the#2xp}% + \csletcs + {\forest@output@prefix@one\the\c@pgf@countc yp}% + {#1\the#2yp}% + \csletcs + {\forest@output@prefix@two\the\c@pgf@countc xp}% + {#1\the#2xp}% + \csletcs + {\forest@output@prefix@two\the\c@pgf@countc yp}% + {#1\the#2yp}% +} +\def\forest@dbep@mp@@store@o#1#2#3{% + \csletcs{#3\the\c@pgf@countc xo}{#1\the#2xo}% + \csletcs{#3\the\c@pgf@countc yo}{#1\the#2yo}% +} +\def\forest@dbep@mp@iteratefirst{% + \forest@dbep@mp@iterateone\forest@input@prefix@one\c@pgf@counta\forest@output@prefix@one +} +\def\forest@dbep@mp@iteratesecond{% + \forest@dbep@mp@iterateone\forest@input@prefix@two\c@pgf@countb\forest@output@prefix@two +} +\def\forest@dbep@mp@iterateone#1#2#3{% + \loop + \ifnum#2<\csname#1n\endcsname\relax + \forest@dbep@mp@@store@p#1#2% + \forest@dbep@mp@@store@o#1#2#3% + \advance\c@pgf@countc 1 + \advance#21 + \repeat +} +\newif\ifforest@equaltotolerance +\def\forest@equaltotolerance#1#2{{% + \pgfpointdiff{#1}{#2}% + \ifdim\pgf@x<0pt \multiply\pgf@x -1 \fi + \ifdim\pgf@y<0pt \multiply\pgf@y -1 \fi + \global\forest@equaltotolerancefalse + \ifdim\pgf@x<\pgfintersectiontolerance\relax + \ifdim\pgf@y<\pgfintersectiontolerance\relax + \global\forest@equaltotolerancetrue + \fi + \fi +}} +\def\forest@save@pgfsyssoftpath@tokendefs{% + \let\forest@origmovetotoken\pgfsyssoftpath@movetotoken + \let\forest@origlinetotoken\pgfsyssoftpath@linetotoken + \let\forest@origcurvetosupportatoken\pgfsyssoftpath@curvetosupportatoken + \let\forest@origcurvetosupportbtoken\pgfsyssoftpath@curvetosupportbtoken + \let\forest@origcurvetotoken\pgfsyssoftpath@curvetototoken + \let\forest@origrectcornertoken\pgfsyssoftpath@rectcornertoken + \let\forest@origrectsizetoken\pgfsyssoftpath@rectsizetoken + \let\forest@origclosepathtoken\pgfsyssoftpath@closepathtoken + \let\pgfsyssoftpath@movetotoken\forest@badtoken + \let\pgfsyssoftpath@linetotoken\forest@badtoken + \let\pgfsyssoftpath@curvetosupportatoken\forest@badtoken + \let\pgfsyssoftpath@curvetosupportbtoken\forest@badtoken + \let\pgfsyssoftpath@curvetototoken\forest@badtoken + \let\pgfsyssoftpath@rectcornertoken\forest@badtoken + \let\pgfsyssoftpath@rectsizetoken\forest@badtoken + \let\pgfsyssoftpath@closepathtoken\forest@badtoken +} +\def\forest@badtoken{% + \PackageError{forest}{This token should not be in this path}{}% +} +\def\forest@restore@pgfsyssoftpath@tokendefs{% + \let\pgfsyssoftpath@movetotoken\forest@origmovetotoken + \let\pgfsyssoftpath@linetotoken\forest@origlinetotoken + \let\pgfsyssoftpath@curvetosupportatoken\forest@origcurvetosupportatoken + \let\pgfsyssoftpath@curvetosupportbtoken\forest@origcurvetosupportbtoken + \let\pgfsyssoftpath@curvetototoken\forest@origcurvetotoken + \let\pgfsyssoftpath@rectcornertoken\forest@origrectcornertoken + \let\pgfsyssoftpath@rectsizetoken\forest@origrectsizetoken + \let\pgfsyssoftpath@closepathtoken\forest@origclosepathtoken +} +\def\forest@extendpath#1#2#3{% + \pgf@process{#3}% + \pgfsyssoftpath@setcurrentpath#1% + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@extendpath@moveto + \let\pgfsyssoftpath@linetotoken\forest@extendpath@lineto + #2% + \forest@restore@pgfsyssoftpath@tokendefs + \pgfsyssoftpath@getcurrentpath#1% +} +\def\forest@extendpath@moveto#1#2{% + \forest@extendpath@do{#1}{#2}\pgfsyssoftpath@moveto +} +\def\forest@extendpath@lineto#1#2{% + \forest@extendpath@do{#1}{#2}\pgfsyssoftpath@lineto +} +\def\forest@extendpath@do#1#2#3{% + {% + \advance\pgf@x #1 + \advance\pgf@y #2 + #3{\the\pgf@x}{\the\pgf@y}% + }% +} +\def\forest@path@getboundingrectangle@ls#1#2{% + {% + \pgftransformreset + \pgftransformrotate{-(#2)}% + \forest@pgfpathtransformed#1% + }% + \pgfsyssoftpath@getcurrentpath\forest@gbr@rotatedpath + \forest@path@getboundingrectangle@xy\forest@gbr@rotatedpath +} +\def\forest@path@getboundingrectangle@xy#1{% + \forest@save@pgfsyssoftpath@tokendefs + \let\pgfsyssoftpath@movetotoken\forest@gbr@firstpoint + \let\pgfsyssoftpath@linetotoken\forest@gbr@firstpoint + #1% + \forest@restore@pgfsyssoftpath@tokendefs +} +\def\forest@gbr@firstpoint#1#2{% + \pgf@xa=#1 \pgf@xb=#1 \pgf@ya=#2 \pgf@yb=#2 + \let\pgfsyssoftpath@movetotoken\forest@gbr@point + \let\pgfsyssoftpath@linetotoken\forest@gbr@point +} +\def\forest@gbr@point#1#2{% + \ifdim#1<\pgf@xa\relax\pgf@xa=#1 \fi + \ifdim#1>\pgf@xb\relax\pgf@xb=#1 \fi + \ifdim#2<\pgf@ya\relax\pgf@ya=#2 \fi + \ifdim#2>\pgf@yb\relax\pgf@yb=#2 \fi +} +\newif\ifforesttikzcshack +\foresttikzcshacktrue +\newif\ifforest@install@keys@to@tikz@path@ +\forest@install@keys@to@tikz@path@true +\forestset{package@options/.cd, + external/.is if=forest@external@, + tikzcshack/.is if=foresttikzcshack, + tikzinstallkeys/.is if=forest@install@keys@to@tikz@path@, +} +\pgfkeys{/forest/external/.cd, + copy command/.initial={cp "\source" "\target"}, + optimize/.is if=forest@external@optimize@, + context/.initial={% + \forestOve{\csname forest@id@of@standard node\endcsname}{environment@formula}}, + depends on macro/.style={context/.append/.expanded={% + \expandafter\detokenize\expandafter{#1}}}, +} +\def\forest@external@copy#1#2{% + \pgfkeysgetvalue{/forest/external/copy command}\forest@copy@command + \ifx\forest@copy@command\pgfkeysnovalue\else + \IfFileExists{#1}{% + {% + \def\source{#1}% + \def\target{#2}% + \immediate\write18{\forest@copy@command}% + }% + }{}% + \fi +} +\newif\ifforest@external@ +\newif\ifforest@external@optimize@ +\forest@external@optimize@true +\ProcessPgfPackageOptions{/forest/package@options} +\ifforest@install@keys@to@tikz@path@ + \tikzset{fit to tree/.style={/forest/fit to tree}} +\fi +\ifforest@external@ + \ifdefined\tikzexternal@tikz@replacement\else + \usetikzlibrary{external}% + \fi + \pgfkeys{% + /tikz/external/failed ref warnings for={}, + /pgf/images/aux in dpth=false, + }% + \tikzifexternalizing{}{% + \forest@external@copy{\jobname.aux}{\jobname.aux.copy}% + }% + \AtBeginDocument{% + \tikzifexternalizing{% + \IfFileExists{\tikzexternalrealjob.aux.copy}{% + \makeatletter + \input \tikzexternalrealjob.aux.copy + \makeatother + }{}% + }{% + \newwrite\forest@auxout + \immediate\openout\forest@auxout=\tikzexternalrealjob.for.tmp + }% + \IfFileExists{\tikzexternalrealjob.for}{% + {% + \makehashother\makeatletter + \input \tikzexternalrealjob.for + }% + }{}% + }% + \AtEndDocument{% + \tikzifexternalizing{}{% + \immediate\closeout\forest@auxout + \forest@external@copy{\jobname.for.tmp}{\jobname.for}% + }% + }% +\fi +\newenvironment{forest}{\Collect@Body\forest@env}{} +\long\def\Forest{\@ifnextchar*{\forest@nogroup}{\forest@group}} +\def\forest@group#1{{\forest@env{#1}}} +\def\forest@nogroup*#1{\forest@env{#1}} +\newif\ifforest@externalize@tree@ +\newif\ifforest@was@tikzexternalwasenable +\long\def\forest@env#1{% + \let\forest@external@next\forest@begin + \forest@was@tikzexternalwasenablefalse + \ifdefined\tikzexternal@tikz@replacement + \ifx\tikz\tikzexternal@tikz@replacement + \forest@was@tikzexternalwasenabletrue + \tikzexternaldisable + \fi + \fi + \forest@externalize@tree@false + \ifforest@external@ + \ifforest@was@tikzexternalwasenable + \tikzifexternalizing{% + \let\forest@external@next\forest@begin@externalizing + }{% + \let\forest@external@next\forest@begin@externalize + }% + \fi + \fi + \forest@standardnode@calibrate + \forest@external@next{#1}% +} +\long\def\forest@begin@externalizing#1{% + \forest@external@setup{#1}% + \let\forest@external@next\forest@begin + \forest@externalize@inner@n=-1 + \ifforest@external@optimize@\forest@externalizing@maybeoptimize\fi + \forest@external@next{#1}% + \tikzexternalenable +} +\def\forest@externalizing@maybeoptimize{% + \edef\forest@temp{\tikzexternalrealjob-forest-\forest@externalize@outer@n}% + \edef\forest@marshal{% + \noexpand\pgfutil@in@ + {\expandafter\detokenize\expandafter{\forest@temp}.} + {\expandafter\detokenize\expandafter{\jobname}.}% + }\forest@marshal + \ifpgfutil@in@ + \else + \let\forest@external@next\@gobble + \fi +} +\long\def\forest@begin@externalize#1{% + \forest@external@setup{#1}% + \iftikzexternal@file@isuptodate + \setbox0=\hbox{% + \csname forest@externalcheck@\forest@externalize@outer@n\endcsname + }% + \fi + \iftikzexternal@file@isuptodate + \csname forest@externalload@\forest@externalize@outer@n\endcsname + \else + \forest@externalize@tree@true + \forest@externalize@inner@n=-1 + \forest@begin{#1}% + \ifcsdef{forest@externalize@@\forest@externalize@id}{}{% + \immediate\write\forest@auxout{% + \noexpand\forest@external + {\forest@externalize@outer@n}% + {\expandafter\detokenize\expandafter{\forest@externalize@id}}% + {\expandonce\forest@externalize@checkimages}% + {\expandonce\forest@externalize@loadimages}% + }% + }% + \fi + \tikzexternalenable +} +\def\forest@includeexternal@check#1{% + \tikzsetnextfilename{#1}% + \tikzexternal@externalizefig@systemcall@uptodatecheck +} +\def\makehashother{\catcode`\#=12}% +\long\def\forest@external@setup#1{% + % set up \forest@externalize@id and \forest@externalize@outer@n + % we need to deal with #s correctly (\write doubles them) + \setbox0=\hbox{\makehashother\makeatletter + \scantokens{\forest@temp@toks{#1}}\expandafter + }% + \expandafter\forest@temp@toks\expandafter{\the\forest@temp@toks}% + \edef\forest@temp{\pgfkeysvalueof{/forest/external/context}}% + \edef\forest@externalize@id{% + \expandafter\detokenize\expandafter{\forest@temp}% + @@% + \expandafter\detokenize\expandafter{\the\forest@temp@toks}% + }% + \letcs\forest@externalize@outer@n{forest@externalize@@\forest@externalize@id}% + \ifdefined\forest@externalize@outer@n + \global\tikzexternal@file@isuptodatetrue + \else + \global\advance\forest@externalize@max@outer@n 1 + \edef\forest@externalize@outer@n{\the\forest@externalize@max@outer@n}% + \global\tikzexternal@file@isuptodatefalse + \fi + \def\forest@externalize@loadimages{}% + \def\forest@externalize@checkimages{}% +} +\newcount\forest@externalize@max@outer@n +\global\forest@externalize@max@outer@n=0 +\newcount\forest@externalize@inner@n +\long\def\forest@external#1#2#3#4{% #1=n,#2=context+source code,#3=update check code, #4=load code + \ifnum\forest@externalize@max@outer@n<#1 + \global\forest@externalize@max@outer@n=#1 + \fi + \global\csdef{forest@externalize@@\detokenize{#2}}{#1}% + \global\csdef{forest@externalcheck@#1}{#3}% + \global\csdef{forest@externalload@#1}{#4}% + \tikzifexternalizing{}{% + \immediate\write\forest@auxout{% + \noexpand\forest@external{#1}% + {\expandafter\detokenize\expandafter{#2}}% + {\unexpanded{#3}}% + {\unexpanded{#4}}% + }% + }% +} +\def\forest@includeexternal#1{% + \edef\forest@temp{\pgfkeysvalueof{/forest/external/context}}% + \typeout{forest: Including external picture '#1' for forest context+code: + '\expandafter\detokenize\expandafter{\forest@externalize@id}'}% + {% + %\def\pgf@declaredraftimage##1##2{\def\pgf@image{\hbox{}}}% + \tikzsetnextfilename{#1}% + \tikzexternalenable + \tikz{}% + }% +} +\def\forest@includeexternal@box#1#2{% + \global\setbox#1=\hbox{\forest@includeexternal{#2}}% +} +\long\def\forest@begin#1{% + \iffalse{\fi\forest@parsebracket#1}% +} +\def\forest@parsebracket{% + \bracketParse{\forest@get@root@afterthought}\forest@root=% +} +\def\forest@get@root@afterthought{% + \expandafter\forest@get@root@afterthought@\expandafter{\iffalse}\fi +} +\long\def\forest@get@root@afterthought@#1{% + \ifblank{#1}{}{% + \forestOeappto{\forest@root}{given options}{,afterthought={\unexpanded{#1}}}% + }% + \forest@do +} +\def\forest@do{% + \forest@node@Compute@numeric@ts@info{\forest@root}% + \forestset{process keylist=given options}% + \forestset{stages}% + \ifforest@was@tikzexternalwasenable + \tikzexternalenable + \fi +} +\def\forest@standardnode@new{% + \advance\forest@node@maxid1 + \forest@fornode{\the\forest@node@maxid}{% + \forest@node@init + \forest@node@setname{standard node}% + }% +} +\def\forest@standardnode@calibrate{% + \forest@fornode{\forest@node@Nametoid{standard node}}{% + \edef\forest@environment{\forestove{environment@formula}}% + \forestoget{previous@environment}\forest@previous@environment + \ifx\forest@environment\forest@previous@environment\else + \forestolet{previous@environment}\forest@environment + \forest@node@typeset + \forestoget{calibration@procedure}\forest@temp + \expandafter\forestset\expandafter{\forest@temp}% + \fi + }% +} +\def\forestStandardNode[#1]#2#3#4{% + \let\forest@standardnode@restoretikzexternal\relax + \ifdefined\tikzexternaldisable + \ifx\tikz\tikzexternal@tikz@replacement + \tikzexternaldisable + \let\forest@standardnode@restoretikzexternal\tikzexternalenable + \fi + \fi + \forest@standardnode@new + \forest@fornode{\forest@node@Nametoid{standard node}}{% + \forestset{content=#1}% + \forestoset{environment@formula}{#2}% + \edef\forest@temp{\unexpanded{#3}}% + \forestolet{calibration@procedure}\forest@temp + \def\forest@calibration@initializing@code{}% + \pgfqkeys{/forest/initializing@code}{#4}% + \forestolet{initializing@code}\forest@calibration@initializing@code + \forest@standardnode@restoretikzexternal + } +} +\forestset{initializing@code/.unknown/.code={% + \eappto\forest@calibration@initializing@code{% + \noexpand\forestOget{\forest@node@Nametoid{standard node}}{\pgfkeyscurrentname}\noexpand\forest@temp + \noexpand\forestolet{\pgfkeyscurrentname}\noexpand\forest@temp + }% + } +} +\def\forest@initializefromstandardnode{% + \forestOve{\forest@node@Nametoid{standard node}}{initializing@code}% +} +\forestStandardNode[dj] + {% + \forestOve{\forest@node@Nametoid{standard node}}{content},% + \the\ht\strutbox,\the\pgflinewidth,% + \pgfkeysvalueof{/pgf/inner ysep},\pgfkeysvalueof{/pgf/outer ysep},% + \pgfkeysvalueof{/pgf/inner xsep},\pgfkeysvalueof{/pgf/outer xsep}% + } + { + l sep={\the\ht\strutbox+\pgfkeysvalueof{/pgf/inner ysep}}, + l={l_sep()+abs(max_y()-min_y())+2*\pgfkeysvalueof{/pgf/outer ysep}}, + s sep={2*\pgfkeysvalueof{/pgf/inner xsep}} + } + {l sep,l,s sep} +\pgfqkeys{/forest/@cs}{% + name/.code={% + \edef\forest@cn{\forest@node@Nametoid{#1}}% + \forest@forestcs@resetxy}, + id/.code={% + \edef\forest@cn{#1}% + \forest@forestcs@resetxy}, + go/.code={% + \forest@go{#1}% + \forest@forestcs@resetxy}, + anchor/.code={\forest@forestcs@anchor{#1}}, + l/.code={% + \pgfmathsetlengthmacro\forest@forestcs@l{#1}% + \forest@forestcs@ls + }, + s/.code={% + \pgfmathsetlengthmacro\forest@forestcs@s{#1}% + \forest@forestcs@ls + }, + .unknown/.code={% + \expandafter\pgfutil@in@\expandafter.\expandafter{\pgfkeyscurrentname}% + \ifpgfutil@in@ + \expandafter\forest@forestcs@namegoanchor\pgfkeyscurrentname\forest@end + \else + \expandafter\forest@nameandgo\expandafter{\pgfkeyscurrentname}% + \forest@forestcs@resetxy + \fi + } +} +\def\forest@forestcs@resetxy{% + \ifnum\forest@cn=0 + \else + \global\pgf@x\forestove{x}% + \global\pgf@y\forestove{y}% + \fi +} +\def\forest@forestcs@ls{% + \ifdefined\forest@forestcs@l + \ifdefined\forest@forestcs@s + {% + \pgftransformreset + \pgftransformrotate{\forestove{grow}}% + \pgfpointtransformed{\pgfpoint{\forest@forestcs@l}{\forest@forestcs@s}}% + }% + \global\advance\pgf@x\forestove{x}% + \global\advance\pgf@y\forestove{y}% + \fi + \fi +} +\def\forest@forestcs@anchor#1{% + \edef\forest@marshal{% + \noexpand\forest@original@tikz@parse@node\relax + (\forestove{name}\ifx\relax#1\relax\else.\fi#1)% + }\forest@marshal +} +\def\forest@forestcs@namegoanchor#1.#2\forest@end{% + \forest@nameandgo{#1}% + \forest@forestcs@anchor{#2}% +} +\tikzdeclarecoordinatesystem{forest}{% + \forest@forthis{% + \forest@forestcs@resetxy + \ifdefined\forest@forestcs@l\undef\forest@forestcs@l\fi + \ifdefined\forest@forestcs@s\undef\forest@forestcs@s\fi + \pgfqkeys{/forest/@cs}{#1}% + }% +} +\endinput +%% +%% End of file `forest.sty'. -- cgit v1.2.3