%% %% 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) 2015 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 `author-maintained'. %% %% This work consists of the following files: %% - forest.dtx: central sources (with rudimentary implementation documentation) %% - forest-libs.dtx: sources and documentation for libraries %% + forest-compat.sty: sources/runtime for compatibility mode %% - forest.ins: produces derived runtime .sty files %% + forest.sty: main package %% + forest-lib-*.sty: libraries (for the list, see forest.ins) %% - forest-doc.tex: central documentation %% - forest-doc.sty: private package needed to compile the documentation %% - forest-index.dtx: sources of indexing package used in the documentation, %% and also part of the documentation itself %% - forest-doc.ins: produces derived .sty files needed to compile the documentation %% - forest-index.sty %% - forest-doc.ist: index style file needed to compile the documentation %% - forest.pdf: documentation of core package implementation %% - forest-doc.pdf: user's guide %% - README %% - LICENCE %% To use the package, only the files marked with + need to be installed. %% \ProvidesPackage{forest}[2015/01/30 v2.0.0 Drawing (linguistic) trees] \RequirePackage{tikz}[2013/12/13] \usetikzlibrary{shapes} \usetikzlibrary{fit} \usetikzlibrary{calc} \usepgflibrary{intersections} \RequirePackage{pgfopts} \RequirePackage{etoolbox}[2010/08/21] \RequirePackage{elocalloc}% for \locbox \RequirePackage{environ} \RequirePackage{xparse} \pgfkeys{/forest/.is family} \def\forestset#1{\pgfqkeys{/forest}{#1}} \newif\ifforest@external@ \newif\ifforesttikzcshack \newif\ifforest@install@keys@to@tikz@path@ \newif\ifforestdebug \def\forest@compat{} \forestset{package@options/.cd, external/.is if=forest@external@, tikzcshack/.is if=foresttikzcshack, tikzinstallkeys/.is if=forest@install@keys@to@tikz@path@, debug/.is if=forestdebug, compat/.store in=\forest@compat, compat/.default=most, .unknown/.code={% load library \eappto\forest@loadlibrarieslater{% \noexpand\useforestlibrary{\pgfkeyscurrentname}% \noexpand\forestapplylibrarydefaults{\pgfkeyscurrentname}% }% }, } \forest@install@keys@to@tikz@path@true \foresttikzcshacktrue \def\forest@loadlibrarieslater{} \AtEndOfPackage{\forest@loadlibrarieslater} \def\useforestlibrary#1{\forcsvlist\useforestlibrary@{#1}} \def\useforestlibrary@#1{\RequirePackage{forest-lib-#1}} \def\forestapplylibrarydefaults#1{\forcsvlist\forestapplylibrarydefaults@{#1}} \def\forestapplylibrarydefaults@#1{\forestset{libraries/#1/defaults/.try}} \NewDocumentCommand\ProvidesForestLibrary{m O{}}{\ProvidesPackage{forest-lib-#1}[#2]} \ProcessPgfPackageOptions{/forest/package@options} \def\forest@patch#1#2#3#4#5{% % #1 = cs to be patched % %2 = purpose of the patch % #3 = macro arguments % #4 = original code % #5 = patched code \csdef{forest@original@#1}#3{#4}% \csdef{forest@patched@#1}#3{#5}% \ifcsequal{#1}{forest@original@#1}{% \csletcs{#1}{forest@patched@#1}% }{% \ifcsequal{#1}{forest@patched@#1}{% all is good, the patch is in! }{% \PackageWarning{forest}{Failed patching '\expandafter\string\csname #1\endcsname'. Purpose of the patch: #2}% }% }% } \forest@patch{pgfgettransform}{fix a leaking space}{#1}{% \edef#1{{\pgf@pt@aa}{\pgf@pt@ab}{\pgf@pt@ba}{\pgf@pt@bb}{\the\pgf@pt@x}{\the\pgf@pt@y}} }{% \edef#1{{\pgf@pt@aa}{\pgf@pt@ab}{\pgf@pt@ba}{\pgf@pt@bb}{\the\pgf@pt@x}{\the\pgf@pt@y}}% } \long\def\@escapeif#1#2\fi{\fi#1} \long\def\@escapeifif#1#2\fi#3\fi{\fi\fi#1} \long\def\@escapeififif#1#2\fi#3\fi#4\fi{\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 }% }% }% \def\newsafeloop#1{% \csdef{safeloop@#1}##1\saferepeat{% \edef\safeloop@marshal{% \noexpand\csdef{safeiterate@#1}{% \unexpanded{##1}\relax \noexpand\expandafter \expandonce{\csname safeiterate@#1\endcsname}% \noexpand\fi }% }\safeloop@marshal \csuse{safeiterate@#1}% \advance\noexpand\safeloop@depth-1\relax \cslet{safeiterate@#1}\relax }% }% \newcount\safeloop@depth \def\safeloop{% \advance\safeloop@depth1 \ifcsdef{safeloop@\the\safeloop@depth}{}{\expandafter\newsafeloop\expandafter{\the\safeloop@depth}}% \csdef{safeloopn@\the\safeloop@depth}{0}% \csuse{safeloop@\the\safeloop@depth}% \csedef{safeloopn@\the\safeloop@depth}{\number\numexpr\csuse{safeloopn@\the\safeloop@depth}+1}% } \let\saferepeat\fi \def\safeloopn{\csuse{safeloopn@\the\safeloop@depth}}% \def\newsafeRKloop#1{% \csdef{safeRKloop@#1}##1\safeRKrepeat{% \edef\safeRKloop@marshal{% \noexpand\csdef{safeRKiterate@#1}{% \unexpanded{##1}\relax \noexpand\expandafter \expandonce{\csname safeRKiterate@#1\endcsname}% \noexpand\fi }% }\safeRKloop@marshal \csuse{safeRKiterate@#1}% \advance\noexpand\safeRKloop@depth-1\relax \cslet{safeRKiterate@#1}\relax }% \expandafter\newif\csname ifsafeRKbreak@\the\safeRKloop@depth\endcsname }% \newcount\safeRKloop@depth \def\safeRKloop{% \advance\safeRKloop@depth1 \ifcsdef{safeRKloop@\the\safeRKloop@depth}{}{\expandafter\newsafeRKloop\expandafter{\the\safeRKloop@depth}}% \csdef{safeRKloopn@\the\safeRKloop@depth}{0}% \csuse{safeRKbreak@\the\safeRKloop@depth false}% \csuse{safeRKloop@\the\safeRKloop@depth}% \csedef{safeRKloopn@\the\safeRKloop@depth}{\number\numexpr\csuse{safeRKloopn@\the\safeRKloop@depth}+1}% } \let\safeRKrepeat\fi \def\safeRKloopn{\csuse{safeRKloopn@\the\safeRKloop@depth}}% \newloop\forest@loop \newdimen\forest@temp@dimen \newcount\forest@temp@count \newcount\forest@n \newif\ifforest@temp \newcount\forest@temp@global@count \newtoks\forest@temp@toks \def\etotoks#1#2{\edef\pot@temp{#2}\expandafter#1\expandafter{\pot@temp}} \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\the\expandafter#1\pot@temp}} \def\pretotoks#1#2{\toks@={#2}\expandafter\expandafter\expandafter#1\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\the\expandafter#1\pot@temp}} \def\gpretotoks#1#2{\toks@={#2}\expandafter\expandafter\expandafter\global\expandafter\expandafter\expandafter#1\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@copycommandkey#1#2{% copies command of #1 into #2 \pgfkeysifdefined{#1/.@cmd}{}{% \PackageError{forest}{Key #1 is not a command key}{}% }% \pgfkeysgetvalue{#1/.@cmd}\forest@temp \pgfkeyslet{#2/.@cmd}\forest@temp \pgfkeysifdefined{#1/.@args}{% \pgfkeysgetvalue{#1/.@args}\forest@temp \pgfkeyslet{#2/.@args}\forest@temp }{}% \pgfkeysifdefined{#1/.@body}{% \pgfkeysgetvalue{#1/.@body}\forest@temp \pgfkeyslet{#2/.@body}\forest@temp }{}% \pgfkeysifdefined{#1/.@@body}{% \pgfkeysgetvalue{#1/.@@body}\forest@temp \pgfkeyslet{#2/.@@body}\forest@temp }{}% \pgfkeysifdefined{#1/.@def}{% \pgfkeysgetvalue{#1/.@def}\forest@temp \pgfkeyslet{#2/.@def}\forest@temp }{}% } \forestset{ copy command key/.code 2 args={\forest@copycommandkey{#1}{#2}}, autoforward/.code 2 args={\forest@autoforward{#1}{#2={#1={##1}}}{true}}, autoforward'/.code 2 args={\forest@autoforward{#1}{#2-=#1,#2={#1={##1}}}{true}}, Autoforward/.code 2 args={\forest@autoforward{#1}{#2}{true}}, autoforward register/.code 2 args={\forest@autoforward{#1}{#2={#1={##1}}}{false}}, autoforward register'/.code 2 args={\forest@autoforward{#1}{#2-=#1,#2={#1={##1}}}{false}}, Autoforward register/.code 2 args={\forest@autoforward{#1}{#2}{false}}, copy command key@if it exists/.code 2 args={% \pgfkeysifdefined{#1/.@cmd}{% \forest@copycommandkey{#1}{#2}% }{}% }, unautoforward/.style={ typeout={unautoforwarding #1}, copy command key@if it exists={/forest/autoforwarded #1}{/forest/#1}, copy command key@if it exists={/forest/autoforwarded #1+}{/forest/#1+}, copy command key@if it exists={/forest/autoforwarded #1-}{/forest/#1-}, copy command key@if it exists={/forest/autoforwarded #1*}{/forest/#1*}, copy command key@if it exists={/forest/autoforwarded #1:}{/forest/#1:}, copy command key@if it exists={/forest/autoforwarded #1'}{/forest/#1'}, copy command key@if it exists={/forest/autoforwarded #1+'}{/forest/#1+'}, copy command key@if it exists={/forest/autoforwarded #1-'}{/forest/#1-'}, copy command key@if it exists={/forest/autoforwarded #1*'}{/forest/#1*'}, copy command key@if it exists={/forest/autoforwarded #1:'}{/forest/#1:'}, copy command key@if it exists={/forest/autoforwarded +#1}{/forest/+#1}, }, /handlers/.undef/.code={\csundef{pgfk@\pgfkeyscurrentpath}}, undef option/.style={ /forest/#1/.undef, /forest/#1/.@cmd/.undef, /forest/#1+/.@cmd/.undef, /forest/#1-/.@cmd/.undef, /forest/#1*/.@cmd/.undef, /forest/#1:/.@cmd/.undef, /forest/#1'/.@cmd/.undef, /forest/#1+'/.@cmd/.undef, /forest/#1-'/.@cmd/.undef, /forest/#1*'/.@cmd/.undef, /forest/#1:'/.@cmd/.undef, /forest/+#1/.@cmd/.undef, /forest/TeX={\patchcmd{\forest@node@init}{\forestoinit{#1}}{}{}{}}, }, undef register/.style={undef option={#1}}, } \def\forest@autoforward#1#2#3{% % #1 = option name % #2 = code of a style taking one arg (new option value), % which expands to whatever should be done with the new value % autoforward(') adds to the keylist (arg#2) % #3 = true=option, false=register \forest@autoforward@createforwarder{}{#1}{}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{+}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{-}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{*}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{:}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{'}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{+'}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{-'}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{*'}{#2}{#3}% \forest@autoforward@createforwarder{}{#1}{:'}{#2}{#3}% \forest@autoforward@createforwarder{+}{#1}{}{#2}{#3}% } \def\forest@autoforward@createforwarder#1#2#3#4#5{% % #1=prefix, #2=option name, #3=suffix, #4=macro code (#2 above), #5=option or register \pgfkeysifdefined{/forest/#1#2#3/.@cmd}{% \forest@copycommandkey{/forest/#1#2#3}{/forest/autoforwarded #1#2#3}% \pgfkeyssetvalue{/forest/autoforwarded #1#2#3/option@name}{#2}% \pgfkeysdef{/forest/#1#2#3}{% \pgfkeysalso{autoforwarded #1#2#3={##1}}% \def\forest@temp@macro####1{#4}% \csname forest@temp#5\endcsname \edef\forest@temp@value{\ifforest@temp\expandafter\forestOv\expandafter{\expandafter\forest@setter@node\expandafter}\else\expandafter\forestrv\fi{#2}}% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfkeysalso\expandafter\expandafter\expandafter{\expandafter\forest@temp@macro\expandafter{\forest@temp@value}}% }% }{}% } \def\forest@node@removekeysfromkeylist#1#2{% #1 = keys to remove, #2 = option name \edef\forest@marshal{% \noexpand\forest@removekeysfromkeylist{\unexpanded{#1}}{\forestov{#2}}\noexpand\forest@temp@toks}\forest@marshal \forestoeset{#2}{\the\forest@temp@toks}% } \def\forest@removekeysfromkeylist#1#2#3{% % #1 = keys to remove (a keylist: an empty value means remove a key with any value) % #2 = keylist % #3 = toks cs for result \forest@temp@toks{}% \def\forestnovalue{\forestnovalue}% \pgfqkeys{/forest/remove@key@installer}{#1}% \let\forestnovalue\pgfkeysnovaluetext \pgfqkeys{/forest/remove@key}{#2}% \pgfqkeys{/forest/remove@key@uninstaller}{#1}% #3\forest@temp@toks } \def\forest@remove@key@novalue{\forest@remove@key@novalue}% \forestset{ remove@key@installer/.unknown/.code={% #1 = (outer) value \def\forest@temp{#1}% \ifx\forest@temp\pgfkeysnovalue@text \pgfkeysdef{/forest/remove@key/\pgfkeyscurrentname}{}% \else \ifx\forest@temp\forestnovalue \expandafter\forest@remove@key@installer@defwithvalue\expandafter{\pgfkeyscurrentname}{\pgfkeysnovalue}% \else \expandafter\forest@remove@key@installer@defwithvalue\expandafter{\pgfkeyscurrentname}{#1}% \fi \fi }, remove@key/.unknown/.code={% #1 = (inner) value \expandafter\apptotoks\expandafter\forest@temp@toks\expandafter{\pgfkeyscurrentname={#1},}% }, remove@key@uninstaller/.unknown/.code={% \pgfkeyslet{/forest/remove@key/\pgfkeyscurrentname/.@cmd}\@undefined}, } \def\forest@remove@key@installer@defwithvalue#1#2{% #1=key name, #2 = outer value \pgfkeysdef{/forest/remove@key/#1}{% ##1 = inner value \def\forest@temp@outer{#2}% \def\forest@temp@inner{##1}% \ifx\forest@temp@outer\forest@temp@inner \else \apptotoks\forest@temp@toks{#1={##1},}% \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.}% } \newloop\forest@sort@loop \newloop\forest@sort@loopA \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@aux{aux} \def\forest@sort@xch#1#2{% \forest@sort@let{\forest@sort@aux}{#1}% \forest@sort@let{#1}{#2}% \forest@sort@let{#2}{\forest@sort@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{\forest@sort@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}{\forest@sort@aux}% } \def\forest@insertionsort@qbody{% \forest@sort@cmp{\the\forest@sort@k}{\forest@sort@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 \safeloop \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 \saferepeat } \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% \forestOeset{#3}{given options}{\forest@contentto=\unexpanded{#2}}% \ifblank{#1}{}{% \forestrset{preamble}{#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{% \bracket@Parse@appendSpace \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\forestolet#1#2{\pgfkeyslet{/forest/@node/\forest@cn/#1}{#2}} \def\forestocslet#1#2{% \edef\forest@marshal{% \noexpand\pgfkeyslet{/forest/@node/\forest@cn/#1}{\expandonce{\csname#2\endcsname}}% }\forest@marshal } \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\forestOcslet#1#2#3{% \edef\forest@marshal{% \noexpand\pgfkeyslet{/forest/@node/#1/#2}{\expandonce{\csname#3\endcsname}}% }\forest@marshal } \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} % full expansion expands precisely to the value \def\forestrv#1{\expandafter\expandafter\expandafter\expandonce \pgfkeysvalueof{/forest/@node/register/#1}} % full expansion expands all the way \def\forestrve#1{\pgfkeysvalueof{/forest/@node/register/#1}} % full expansion expands to the cs holding the value \def\forestrm#1{\expandafter\expandonce\expandafter{\pgfkeysvalueof{/forest/@node/register/#1}}} \def\forestrget#1#2{\pgfkeysgetvalue{/forest/@node/register/#1}{#2}} \def\forestrlet#1#2{\pgfkeyslet{/forest/@node/register/#1}{#2}} \def\forestrcslet#1#2{% \edef\forest@marshal{% \noexpand\pgfkeyslet{/forest/@node/register/#1}{\expandonce{\csname#2\endcsname}}% }\forest@marshal } \def\forestrset#1#2{\pgfkeyssetvalue{/forest/@node/register/#1}{#2}} \def\forestreset#1#2{% \edef\forest@option@temp{% \noexpand\pgfkeyssetvalue{/forest/@node/register/#1}{#2}% }\forest@option@temp } \def\forestrappto#1#2{% \forestreset{#1}{\forestrv{#1}\unexpanded{#2}}% } \def\forestrpreto#1#2{% \forestreset{#1}{\unexpanded{#2}\forestrv{#1}}% } \def\forestrifdefined#1#2#3{% \pgfkeysifdefined{/forest/@node/register/#1}{#2}{#3}% } \def\forestregister#1{\forestrv{#1}} \def\foresteregister#1{\forestrve{#1}} \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{\ifstrequal{##1}{name}{\forestoset{name}{node@\forest@cn}}{\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@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@@forselfandfollowingsiblings@reversed#1{% \ifnum\forest@cn=0 \else \@escapeif{% \edef\forest@marshal{% \noexpand\def\noexpand\forest@cn{\forestove{@next}}% \noexpand\forest@node@@forselfandfollowingsiblings@reversed{\unexpanded{#1}}% \noexpand\forest@fornode{\forest@cn}{\unexpanded{#1}}% }\forest@marshal }% \fi } \def\forest@node@foreachchild@reversed#1{\forest@node@Foreachchild@reversed{\forest@cn}{#1}} \def\forest@node@Foreachchild@reversed#1#2{% \forest@fornode{\forestOve{#1}{@last}}{\forest@node@@forselfandprecedingsiblings@reversed{#2}}% } \def\forest@node@@forselfandprecedingsiblings@reversed#1{% \ifnum\forest@cn=0 \else \forest@forthis{#1}% \@escapeif{% \edef\forest@cn{\forestove{@previous}}% \forest@node@@forselfandprecedingsiblings@reversed{#1}% }% \fi } \def\forest@node@@forselfandprecedingsiblings#1{% \ifnum\forest@cn=0 \else \@escapeif{% \edef\forest@marshal{% \noexpand\def\noexpand\forest@cn{\forestove{@previous}}% \noexpand\forest@node@@forselfandprecedingsiblings{\unexpanded{#1}}% \noexpand\forest@fornode{\forest@cn}{\unexpanded{#1}}% }\forest@marshal }% \fi } \def\forest@node@@foreach#1#2#3#4{% % #1 = do what % #2 = do that -1=before,1=after processing children % #3 & #4: normal or reversed order of children? % #3 = @first/@last % #4 = \forest@node@@forselfandfollowingsiblings / \forest@node@@forselfandprecedingsiblings@reversed \ifnum#2<0 \forest@forthis{#1}\fi \ifnum\forestove{#3}=0 \else\@escapeif{% \forest@forthis{% \edef\forest@cn{\forestove{#3}}% #4{\forest@node@@foreach{#1}{#2}{#3}{#4}}% }% }\fi \ifnum#2>0 \forest@forthis{#1}\fi } \def\forest@node@foreach#1{% \forest@node@@foreach{#1}{-1}{@first}{\forest@node@@forselfandfollowingsiblings}} \def\forest@node@Foreach#1#2{% \forest@fornode{#1}{\forest@node@@foreach{#2}{-1}{@first}{\forest@node@@forselfandfollowingsiblings}}} \def\forest@node@foreach@reversed#1{% \forest@node@@foreach{#1}{-1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}} \def\forest@node@Foreach@reversed#1#2{% \forest@fornode{#1}{\forest@node@@foreach{#2}{-1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}}} \def\forest@node@foreach@childrenfirst#1{% \forest@node@@foreach{#1}{1}{@first}{\forest@node@@forselfandfollowingsiblings}} \def\forest@node@Foreach@childrenfirst#1#2{% \forest@fornode{#1}{\forest@node@@foreach{#2}{1}{@first}{\forest@node@@forselfandfollowingsiblings}}} \def\forest@node@foreach@childrenfirst@reversed#1{% \forest@node@@foreach{#1}{1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}} \def\forest@node@Foreach@childrenfirst@reversed#1#2{% \forest@fornode{#1}{\forest@node@@foreach{#2}{1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}}} \def\forest@node@foreachdescendant#1{% \forest@node@foreachchild{\forest@node@@foreach{#1}{-1}{@first}{\forest@node@@forselfandfollowingsiblings}}} \def\forest@node@Foreachdescendant#1#2{% \forest@node@Foreachchild{#1}{\forest@node@@foreach{#2}{-1}{@first}{\forest@node@@forselfandfollowingsiblings}}} \def\forest@node@foreachdescendant@reversed#1{% \forest@node@foreachchild@reversed{\forest@node@@foreach{#1}{-1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}}} \def\forest@node@Foreachdescendant@reversed#1#2{% \forest@node@Foreachchild@reversed{#1}{\forest@node@@foreach{#2}{-1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}}} \def\forest@node@foreachdescendant@childrenfirst#1{% \forest@node@foreachchild{\forest@node@@foreach{#1}{1}{@first}{\forest@node@@forselfandfollowingsiblings}}} \def\forest@node@Foreachdescendant@childrenfirst#1#2{% \forest@node@Foreachchild{#1}{\forest@node@@foreach{#2}{1}{@first}{\forest@node@@forselfandfollowingsiblings}}} \def\forest@node@foreachdescendant@childrenfirst@reversed#1{% \forest@node@foreachchild@reversed{\forest@node@@foreach{#1}{1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}}} \def\forest@node@Foreachdescendant@childrenfirst@reversed#1#2{% \forest@node@Foreachchild@reversed{#1}{\forest@node@@foreach{#2}{1}{@last}{\forest@node@@forselfandprecedingsiblings@reversed}}} \def\forest@node@foreach@breadthfirst#1#2{% #1 = max level, #2 = code \forest@node@Foreach@breadthfirst@{\forest@cn}{@first}{@next}{#1}{#2}} \def\forest@node@foreach@breadthfirst@reversed#1#2{% #1 = max level, #2 = code \forest@node@Foreach@breadthfirst@{\forest@cn}{@last}{@previous}{#1}{#2}} \def\forest@node@Foreach@breadthfirst#1#2#3{% #1 = node id, #2 = max level, #3 = code \forest@node@Foreach@breadthfirst@{#1}{@first}{@next}{#2}{#3}} \def\forest@node@Foreach@breadthfirst@reversed#1#2#3{% #1 = node id, #2 = max level, #3 = code \forest@node@Foreach@breadthfirst@{#1}{@last}{@previous}{#2}{#3}} \def\forest@node@Foreach@breadthfirst@#1#2#3#4#5{% % #1 = root node, % #2 = @first/@last, #3 = @next/@previous (must be in sync with #2), % #4 = max level (< 0 means infinite) % #5 = code to execute at each node \forest@node@Foreach@breadthfirst@processqueue{#1,}{#2}{#3}{#4}{#5}% } \def\forest@node@Foreach@breadthfirst@processqueue#1#2#3#4#5{% % #1 = queue, % #2 = @first/@last, #3 = @next/@previous (must be in sync with #2), % #4 = max level (< 0 means infinite) % #5 = code to execute at each node \ifstrempty{#1}{}{% \forest@node@Foreach@breadthfirst@processqueue@#1\forest@node@Foreach@breadthfirst@processqueue@ {#2}{#3}{#4}{#5}% }% } \def\forest@node@Foreach@breadthfirst@processqueue@#1,#2\forest@node@Foreach@breadthfirst@processqueue@#3#4#5#6{% % #1 = first, % #2 = rest, % #3 = @first/@last, #4 = next/previous (must be in sync with #2), % #5 = max level (< 0 means infinite) % #6 = code to execute at each node \forest@fornode{#1}{% #6% \ifnum#5<0 \forest@node@getlistofchildren\forest@temp{#3}{#4}% \else \ifnum\forestove{level}>#5\relax \def\forest@temp{}% \else \forest@node@getlistofchildren\forest@temp{#3}{#4}% \fi \fi \edef\forest@marshal{% \noexpand\forest@node@Foreach@breadthfirst@processqueue{\unexpanded{#2}\forest@temp}% {#3}{#4}{#5}{\unexpanded{#6}}% }\forest@marshal }% } \def\forest@node@getlistofchildren#1#2#3{% #1 = list cs, #2 = @first/@last, #3 = @next/@previous \forest@node@Getlistofchildren{\forest@cn}{#1}{#2}{#3}% } \def\forest@node@Getlistofchildren#1#2#3#4{% #1 = node, #2 = list cs, #3 = @first/@last, #4 = @next/@previous \def#2{}% \ifnum\forestove{#3}=0 \else \eappto#2{\forestOve{#1}{#3},}% \@escapeif{% \edef\forest@marshal{% \noexpand\forest@node@Getlistofchildren@{\forestOve{#1}{#3}}\noexpand#2{#4}% }\forest@marshal }% \fi } \def\forest@node@Getlistofchildren@#1#2#3{% #1 = node, #2 = list cs, #3 = @next/@previous \ifnum\forestOve{#1}{#3}=0 \else \eappto#2{\forestOve{#1}{#3},}% \@escapeif{% \edef\forest@marshal{% \noexpand\forest@node@Getlistofchildren@{\forestOve{#1}{#3}}\noexpand#2{#3}% }\forest@marshal }% \fi } \def\forest@node@Compute@numeric@ts@info@#1{% \forest@node@Foreach{#1}{\forest@node@@compute@numeric@ts@info}% \ifnum\forestOve{#1}{@parent}=0 \else \forest@fornode{#1}{\forest@node@@compute@numeric@ts@info@nbar}% % hack: the parent of the node we called the update for gets +1 for n_children \edef\forest@node@temp{\forestOve{#1}{@parent}}% \forestOeset{\forest@node@temp}{n children}{% \number\numexpr\forestOve{\forest@node@temp}{n children}-1% }% \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 \ifnum\forestOve{#1}{@parent}=0 0% \else \@escapeifif{\expandnumberarg\forest@node@Linearnextnotdescendantid{\forestOve{#1}{@parent}}}% \fi \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}% } \def\forest@declarehandler#1#2#3{%#1=handler for specific type,#2=option name,#3=default value \pgfkeyssetvalue{/forest/#2}{#3}% \appto\forest@node@init{\forestoinit{#2}}% \pgfkeyssetvalue{/forest/#2/node@or@reg}{\forest@cn}% \forest@convert@others@to@underscores{#2}\forest@pgfmathoptionname \edef\forest@marshal{% \noexpand#1{/forest/#2}{/forest}{#2}{\forest@pgfmathoptionname}% }\forest@marshal } \def\forest@def@with@pgfeov#1#2{% \pgfeov mustn't occur in the arg of the .code handler!!! \long\def#1##1\pgfeov{#2}% } \def\forest@declaretoks@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declaretoks@handler@A{#1}{#2}{#3}{#4}{}% } \def\forest@declarekeylist@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declaretoks@handler@A{#1}{#2}{#3}{#4}{,}% \forest@copycommandkey{#1}{#1'}% \pgfkeyssetvalue{#1'/option@name}{#3}% \forest@copycommandkey{#1+}{#1}% \pgfkeysalso{#1-/.code={% \forest@fornode{\forest@setter@node}{% \forest@node@removekeysfromkeylist{##1}{#3}% }}}% \pgfkeyssetvalue{#1-/option@name}{#3}% } \def\forest@declaretoks@handler@A#1#2#3#4#5{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix \pgfkeysalso{% #1/.code={\forestOset{\forest@setter@node}{#3}{##1}}, #1+/.code={\forestOappto{\forest@setter@node}{#3}{#5##1}}, #2/+#3/.code={\forestOpreto{\forest@setter@node}{#3}{##1#5}}, #2/if #3/.code n args={3}{% \forestoget{#3}\forest@temp@option@value \edef\forest@temp@compared@value{\unexpanded{##1}}% \ifx\forest@temp@option@value\forest@temp@compared@value \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, #2/if in #3/.code n args={3}{% \forestoget{#3}\forest@temp@option@value \edef\forest@temp@compared@value{\unexpanded{##1}}% \expandafter\expandafter\expandafter\pgfutil@in@\expandafter\expandafter\expandafter{\expandafter\forest@temp@compared@value\expandafter}\expandafter{\forest@temp@option@value}% \ifpgfutil@in@ \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, #2/where #3/.style n args={3}{for tree={#2/if #3={##1}{##2}{##3}}}, #2/where in #3/.style n args={3}{for tree={#2/if in #3={##1}{##2}{##3}}} }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#2/+#3/option@name}{#3}% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@toks{##1}{#3}}% } \def\forest@declareautowrappedtoks@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix \forest@declaretoks@handler{#1}{#2}{#3}{#4}% \forest@copycommandkey{#1}{#1'}% \pgfkeysalso{#1/.style={#1'/.wrap value={##1}}}% \pgfkeyssetvalue{#1'/option@name}{#3}% \forest@copycommandkey{#1+}{#1+'}% \pgfkeysalso{#1+/.style={#1+'/.wrap value={##1}}}% \pgfkeyssetvalue{#1+'/option@name}{#3}% \forest@copycommandkey{#2/+#3}{#2/+#3'}% \pgfkeysalso{#2/+#3/.style={#2/+#3'/.wrap value={##1}}}% \pgfkeyssetvalue{#2/+#3'/option@name}{#3}% } \def\forest@declarereadonlydimen@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \pgfkeysalso{% #2/if #3/.code n args={3}{% \forestoget{#3}\forest@temp@option@value \ifdim\forest@temp@option@value=##1\relax \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, #2/where #3/.style n args={3}{for tree={#2/if #3={##1}{##2}{##3}}}, }% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@dimen{##1}{#3}}% } \def\forest@declaredimen@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declarereadonlydimen@handler{#1}{#2}{#3}{#4}% \pgfkeysalso{% #1/.code={% \pgfmathsetlengthmacro\forest@temp{##1}% \forestOlet{\forest@setter@node}{#3}\forest@temp }, #1+/.code={% \pgfmathsetlengthmacro\forest@temp{##1}% \pgfutil@tempdima=\forestove{#3} \advance\pgfutil@tempdima\forest@temp\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, #1-/.code={% \pgfmathsetlengthmacro\forest@temp{##1}% \pgfutil@tempdima=\forestove{#3} \advance\pgfutil@tempdima-\forest@temp\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, #1*/.style={% #1={#4()*(##1)}% }, #1:/.style={% #1={#4()/(##1)}% }, #1'/.code={% \pgfutil@tempdima=##1\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, #1'+/.code={% \pgfutil@tempdima=\forestove{#3}\relax \advance\pgfutil@tempdima##1\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, #1'-/.code={% \pgfutil@tempdima=\forestove{#3}\relax \advance\pgfutil@tempdima-##1\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, #1'*/.style={% \pgfutil@tempdima=\forestove{#3}\relax \multiply\pgfutil@tempdima##1\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, #1':/.style={% \pgfutil@tempdima=\forestove{#3}\relax \divide\pgfutil@tempdima##1\relax \forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}% }, }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#1-/option@name}{#3}% \pgfkeyssetvalue{#1*/option@name}{#3}% \pgfkeyssetvalue{#1:/option@name}{#3}% \pgfkeyssetvalue{#1'/option@name}{#3}% \pgfkeyssetvalue{#1'+/option@name}{#3}% \pgfkeyssetvalue{#1'-/option@name}{#3}% \pgfkeyssetvalue{#1'*/option@name}{#3}% \pgfkeyssetvalue{#1':/option@name}{#3}% } \def\forest@declarereadonlycount@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \pgfkeysalso{ #2/if #3/.code n args={3}{% \forestoget{#3}\forest@temp@option@value \ifnum\forest@temp@option@value=##1\relax \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, #2/where #3/.style n args={3}{for tree={#2/if #3={##1}{##2}{##3}}}, }% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@count{##1}{#3}}% } \def\forest@declarecount@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declarereadonlycount@handler{#1}{#2}{#3}{#4}% \pgfkeysalso{ #1/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \forestOlet{\forest@setter@node}{#3}\forest@temp }, #1+/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestove{#3}\relax \advance\c@pgf@counta\forest@temp\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1-/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestove{#3}\relax \advance\c@pgf@counta-\forest@temp\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1*/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestove{#3}\relax \multiply\c@pgf@counta\forest@temp\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1:/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestove{#3}\relax \divide\c@pgf@counta\forest@temp\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1'/.code={% \c@pgf@counta=##1\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1'+/.code={% \c@pgf@counta=\forestove{#3}\relax \advance\c@pgf@counta##1\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1'-/.code={% \c@pgf@counta=\forestove{#3}\relax \advance\c@pgf@counta-##1\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1'*/.style={% \c@pgf@counta=\forestove{#3}\relax \multiply\c@pgf@counta##1\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, #1':/.style={% \c@pgf@counta=\forestove{#3}\relax \divide\c@pgf@counta##1\relax \forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}% }, }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#1-/option@name}{#3}% \pgfkeyssetvalue{#1*/option@name}{#3}% \pgfkeyssetvalue{#1:/option@name}{#3}% \pgfkeyssetvalue{#1'/option@name}{#3}% \pgfkeyssetvalue{#1'+/option@name}{#3}% \pgfkeyssetvalue{#1'-/option@name}{#3}% \pgfkeyssetvalue{#1'*/option@name}{#3}% \pgfkeyssetvalue{#1':/option@name}{#3}% } \def\forest@declareboolean@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \pgfkeysalso{% #1/.code={% \ifstrequal{##1}{1}{% \forestOset{\forest@setter@node}{#3}{1}% }{% \ifstrequal{##1}{0}{% \forestOset{\forest@setter@node}{#3}{0}% }{% \pgfmathifthenelse{##1}{1}{0}% \forestOlet{\forest@setter@node}{#3}\pgfmathresult }% }% }, #1/.default=1, #2/not #3/.code={\forestOset{\forest@setter@node}{#3}{0}}, #2/if #3/.code 2 args={% \forestoget{#3}\forest@temp@option@value \ifnum\forest@temp@option@value=1 \pgfkeysalso{##1}% \else \pgfkeysalso{##2}% \fi }, #2/where #3/.style 2 args={for tree={#2/if #3={##1}{##2}}} }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@count{##1}{#3}}% } \forestset{ declare toks/.code 2 args={% \forest@declarehandler\forest@declaretoks@handler{#1}{#2}% }, declare autowrapped toks/.code 2 args={% \forest@declarehandler\forest@declareautowrappedtoks@handler{#1}{#2}% }, declare keylist/.code 2 args={% \forest@declarehandler\forest@declarekeylist@handler{#1}{#2}% }, declare readonly dimen/.code={% \forest@declarehandler\forest@declarereadonlydimen@handler{#1}{}% }, declare dimen/.code 2 args={% \forest@declarehandler\forest@declaredimen@handler{#1}{#2}% }, declare readonly count/.code={% \forest@declarehandler\forest@declarereadonlycount@handler{#1}{}% }, declare count/.code 2 args={% \forest@declarehandler\forest@declarecount@handler{#1}{#2}% }, declare boolean/.code 2 args={% \forest@declarehandler\forest@declareboolean@handler{#1}{#2}% }, /handlers/.restore default value/.code={% \edef\forest@handlers@currentpath{\pgfkeyscurrentpath}% \pgfkeysgetvalue{\pgfkeyscurrentpath/option@name}\forest@currentoptionname \pgfkeysgetvalue{/forest/\forest@currentoptionname}\forest@temp \expandafter\pgfkeysalso\expandafter{\forest@handlers@currentpath/.expand once=\forest@temp}% }, /handlers/.pgfmath/.code={% \pgfmathparse{#1}% \pgfkeysalso{\pgfkeyscurrentpath/.expand once=\pgfmathresult}% }, /handlers/.wrap value/.code={% \edef\forest@handlers@wrap@currentpath{\pgfkeyscurrentpath}% \pgfkeysgetvalue{\forest@handlers@wrap@currentpath/option@name}\forest@currentoptionname \forestOget{\pgfkeysvalueof{/forest/\forest@currentoptionname/node@or@reg}}{\forest@currentoptionname}\forest@option@value \forest@def@with@pgfeov\forest@wrap@code{#1}% \expandafter\edef\expandafter\forest@wrapped@value\expandafter{\expandafter\expandonce\expandafter{\expandafter\forest@wrap@code\forest@option@value\pgfeov}}% \pgfkeysalso{\forest@handlers@wrap@currentpath/.expand once=\forest@wrapped@value}% }, /handlers/.option/.code={% \edef\forest@marshal{% \noexpand\pgfkeysalso{\pgfkeyscurrentpath={\forestoption{#1}}}% }\forest@marshal }, /handlers/.register/.code={% \edef\forest@marshal{% \noexpand\pgfkeysalso{\pgfkeyscurrentpath={\forestregister{#1}}}% }\forest@marshal }, /handlers/.wrap pgfmath arg/.code 2 args={% \pgfmathparse{#2}\let\forest@wrap@arg@i\pgfmathresult \edef\forest@wrap@args{{\expandonce\forest@wrap@arg@i}}% \def\forest@wrap@code##1{#1}% \expandafter\expandafter\expandafter\forest@temp@toks\expandafter\expandafter\expandafter{\expandafter\forest@wrap@code\forest@wrap@args}% \pgfkeysalso{\pgfkeyscurrentpath/.expand once=\the\forest@temp@toks}% }, /handlers/.wrap 2 pgfmath args/.code n args={3}{% \pgfmathparse{#2}\let\forest@wrap@arg@i\pgfmathresult \pgfmathparse{#3}\let\forest@wrap@arg@ii\pgfmathresult \edef\forest@wrap@args{{\expandonce\forest@wrap@arg@i}{\expandonce\forest@wrap@arg@ii}}% \def\forest@wrap@code##1##2{#1}% \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}% }, /handlers/.wrap 3 pgfmath args/.code n args={4}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{}{}{}{}{}{3}% \forest@wrap@n@pgfmath@do{#1}{3}}, /handlers/.wrap 4 pgfmath args/.code n args={5}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{#5}{}{}{}{}{4}% \forest@wrap@n@pgfmath@do{#1}{4}}, /handlers/.wrap 5 pgfmath args/.code n args={6}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{#5}{#6}{}{}{}{5}% \forest@wrap@n@pgfmath@do{#1}{5}}, /handlers/.wrap 6 pgfmath args/.code n args={7}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{#5}{#6}{#7}{}{}{6}% \forest@wrap@n@pgfmath@do{#1}{6}}, /handlers/.wrap 7 pgfmath args/.code n args={8}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{#5}{#6}{#7}{#8}{}{7}% \forest@wrap@n@pgfmath@do{#1}{7}}, /handlers/.wrap 8 pgfmath args/.code n args={9}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}{8}% \forest@wrap@n@pgfmath@do{#1}{8}}, /handlers/.process args/.code={% \forest@processargs#1\forest@eov\forest@END }, } \def\forest@wrap@n@pgfmath@args#1#2#3#4#5#6#7#8#9{% \pgfmathparse{#1}\let\forest@wrap@arg@i\pgfmathresult \ifnum#9>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}% } \newtoks\forest@processargs@result \newtoks\forest@processargs@current \newif\ifforest@processargs@append \def\forest@eov{\forest@eov} \def\forest@processargs#1#2\forest@END{% #1 = processing instructions, #2 = args \forest@processargs@result{}% \forest@processargs@current{}% \forest@processargs@appendfalse \forest@processargs@getins#1.\forest@END#2\forest@END } \def\forest@processargs@maybeappend{% \ifforest@processargs@append \eapptotoks\forest@processargs@result{{\the\forest@processargs@current}}% \forest@processargs@current{}% \fi } \def\forest@processargs@getins#1#2\forest@END#3\forest@END{% #1 = first instruction, #2 = rest of instructions, #3 = args \csname forest@processargs@ins@#1\endcsname#2\forest@END#3\forest@END } \csdef{forest@processargs@ins@.}\forest@END#1\forest@END{% \forest@processargs@maybeappend \forest@processargs@appremainingargs#1\forest@END } \def\forest@processargs@appremainingargs#1#2\forest@END{% \edef\forest@temp{\unexpanded{#1}}% \ifx\forest@temp\forest@eov \let\forest@processargs@next\forest@processargs@done \else \apptotoks\forest@processargs@result{{#1}}% \let\forest@processargs@next\forest@processargs@appremainingargs \fi \forest@processargs@next#2\forest@END } \def\forest@processargs@done#1\forest@END{% \pgfkeysalso{\pgfkeyscurrentpath/.expanded=\the\forest@processargs@result}% } \csdef{forest@processargs@ins@_}#1\forest@END#2#3\forest@END{% no processing % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \forest@processargs@current{#2}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \csdef{forest@processargs@ins@x}#1\forest@END#2#3\forest@END{% expand % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \etotoks\forest@processargs@current{#2}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \csdef{forest@processargs@ins@o}#1\forest@END#2#3\forest@END{% expand once % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \expandafter\forest@processargs@current\expandafter{#2}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \csdef{forest@processargs@ins@O}#1\forest@END#2#3\forest@END{% option % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \etotoks\forest@processargs@current{\forestoption{#2}}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \csdef{forest@processargs@ins@R}#1\forest@END#2#3\forest@END{% register % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \etotoks\forest@processargs@current{\forestregister{#2}}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \csdef{forest@processargs@ins@P}#1\forest@END#2#3\forest@END{% pgfmath expression % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \pgfmathparse{#2}% \expandafter\forest@processargs@current\expandafter{\pgfmathresult}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \csdef{forest@processargs@ins@+}#1\forest@END#2\forest@END{% join processors \forest@processargs@appendfalse \edef\forest@marshal{% \unexpanded{\forest@processargs@getins#1\forest@END}{\the\forest@processargs@current}\unexpanded{#2\forest@END}% }\forest@marshal } \csdef{forest@processargs@ins@r}#1\forest@END#2#3\forest@END{% reverse keylist % #1 = rest of ins, #2 = first arg, #3 = rest of args \forest@processargs@maybeappend \forest@processargs@current{}% \pgfqkeys{/forest}{split={#2}{,}{reverse@keylist}}% \forest@processargs@appendtrue \forest@processargs@getins#1\forest@END#3\forest@END } \forestset{% reverse@keylist/.code={% \epretotoks\forest@processargs@current{#1,}% }, } \def\forest@pgfmathhelper@register@toks#1#2{% #1 is discarded: it is present only for analogy with options \forestrget{#2}\pgfmathresult } \def\forest@pgfmathhelper@register@dimen#1#2{% \forestrget{#2}\forest@temp \pgfmathparse{+\forest@temp}% } \def\forest@pgfmathhelper@register@count#1#2{% \forestrget{#2}\forest@temp \pgfmathtruncatemacro\pgfmathresult{\forest@temp}% } \def\forest@declareregisterhandler#1#2{%#1=handler for specific type,#2=option name \pgfkeyssetvalue{/forest/#2/node@or@reg}{register}% \forest@convert@others@to@underscores{#2}\forest@pgfmathoptionname \edef\forest@marshal{% \noexpand#1{/forest/#2}{/forest}{#2}{\forest@pgfmathoptionname}% }\forest@marshal } \def\forest@declaretoksregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declaretoksregister@handler@A{#1}{#2}{#3}{#4}{}% } \def\forest@declarekeylistregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declaretoksregister@handler@A{#1}{#2}{#3}{#4}{,}% \forest@copycommandkey{#1}{#1'}% \pgfkeyssetvalue{#1'/option@name}{#3}% \forest@copycommandkey{#1+}{#1}% \pgfkeysalso{#1-/.code={% \forest@fornode{register}{% \forest@node@removekeysfromkeylist{##1}{#3}% }}}% \pgfkeyssetvalue{#1-/option@name}{#3}% } \def\forest@declaretoksregister@handler@A#1#2#3#4#5{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix \pgfkeysalso{% #1/.code={\forestrset{#3}{##1}}, #1+/.code={\forestrappto{#3}{#5##1}}, #2/+#3/.code={\forestrpreto{#3}{##1#5}}, #2/if #3/.code n args={3}{% \forestrget{#3}\forest@temp@option@value \edef\forest@temp@compared@value{\unexpanded{##1}}% \ifx\forest@temp@option@value\forest@temp@compared@value \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, #2/if in #3/.code n args={3}{% \forestrget{#3}\forest@temp@option@value \edef\forest@temp@compared@value{\unexpanded{##1}}% \expandafter\expandafter\expandafter\pgfutil@in@\expandafter\expandafter\expandafter{\expandafter\forest@temp@compared@value\expandafter}\expandafter{\forest@temp@option@value}% \ifpgfutil@in@ \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#2/+#3/option@name}{#3}% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@toks{##1}{#3}}% } \def\forest@declareautowrappedtoksregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix \forest@declaretoksregister@handler{#1}{#2}{#3}{#4}% \forest@copycommandkey{#1}{#1'}% \pgfkeysalso{#1/.style={#1'/.wrap value={##1}}}% \pgfkeyssetvalue{#1'/option@name}{#3}% \forest@copycommandkey{#1+}{#1+'}% \pgfkeysalso{#1+/.style={#1+'/.wrap value={##1}}}% \pgfkeyssetvalue{#1+'/option@name}{#3}% \forest@copycommandkey{#2/+#3}{#2/+#3'}% \pgfkeysalso{#2/+#3/.style={#2/+#3'/.wrap value={##1}}}% \pgfkeyssetvalue{#2/+#3'/option@name}{#3}% } \def\forest@declarereadonlydimenregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \pgfkeysalso{% #2/if #3/.code n args={3}{% \forestrget{#3}\forest@temp@option@value \ifdim\forest@temp@option@value=##1\relax \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, }% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@dimen{##1}{#3}}% } \def\forest@declaredimenregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declarereadonlydimenregister@handler{#1}{#2}{#3}{#4}% \pgfkeysalso{% #1/.code={% \pgfmathsetlengthmacro\forest@temp{##1}% \forestrlet{#3}\forest@temp }, #1+/.code={% \pgfmathsetlengthmacro\forest@temp{##1}% \pgfutil@tempdima=\forestrve{#3} \advance\pgfutil@tempdima\forest@temp\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, #1-/.code={% \pgfmathsetlengthmacro\forest@temp{##1}% \pgfutil@tempdima=\forestrve{#3} \advance\pgfutil@tempdima-\forest@temp\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, #1*/.style={% #1={#4()*(##1)}% }, #1:/.style={% #1={#4()/(##1)}% }, #1'/.code={% \pgfutil@tempdima=##1\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, #1'+/.code={% \pgfutil@tempdima=\forestrve{#3}\relax \advance\pgfutil@tempdima##1\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, #1'-/.code={% \pgfutil@tempdima=\forestrve{#3}\relax \advance\pgfutil@tempdima-##1\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, #1'*/.style={% \pgfutil@tempdima=\forestrve{#3}\relax \multiply\pgfutil@tempdima##1\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, #1':/.style={% \pgfutil@tempdima=\forestrve{#3}\relax \divide\pgfutil@tempdima##1\relax \forestreset{#3}{\the\pgfutil@tempdima}% }, }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#1-/option@name}{#3}% \pgfkeyssetvalue{#1*/option@name}{#3}% \pgfkeyssetvalue{#1:/option@name}{#3}% \pgfkeyssetvalue{#1'/option@name}{#3}% \pgfkeyssetvalue{#1'+/option@name}{#3}% \pgfkeyssetvalue{#1'-/option@name}{#3}% \pgfkeyssetvalue{#1'*/option@name}{#3}% \pgfkeyssetvalue{#1':/option@name}{#3}% } \def\forest@declarereadonlycountregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \pgfkeysalso{ #2/if #3/.code n args={3}{% \forestrget{#3}\forest@temp@option@value \ifnum\forest@temp@option@value=##1\relax \pgfkeysalso{##2}% \else \pgfkeysalso{##3}% \fi }, }% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@count{##1}{#3}}% } \def\forest@declarecountregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \forest@declarereadonlycountregister@handler{#1}{#2}{#3}{#4}% \pgfkeysalso{ #1/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \forestrlet{#3}\forest@temp }, #1+/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestrve{#3}\relax \advance\c@pgf@counta\forest@temp\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1-/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestrve{#3}\relax \advance\c@pgf@counta-\forest@temp\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1*/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestrve{#3}\relax \multiply\c@pgf@counta\forest@temp\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1:/.code={% \pgfmathtruncatemacro\forest@temp{##1}% \c@pgf@counta=\forestrve{#3}\relax \divide\c@pgf@counta\forest@temp\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1'/.code={% \c@pgf@counta=##1\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1'+/.code={% \c@pgf@counta=\forestrve{#3}\relax \advance\c@pgf@counta##1\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1'-/.code={% \c@pgf@counta=\forestrve{#3}\relax \advance\c@pgf@counta-##1\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1'*/.style={% \c@pgf@counta=\forestrve{#3}\relax \multiply\c@pgf@counta##1\relax \forestreset{#3}{\the\c@pgf@counta}% }, #1':/.style={% \c@pgf@counta=\forestrve{#3}\relax \divide\c@pgf@counta##1\relax \forestreset{#3}{\the\c@pgf@counta}% }, }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#1-/option@name}{#3}% \pgfkeyssetvalue{#1*/option@name}{#3}% \pgfkeyssetvalue{#1:/option@name}{#3}% \pgfkeyssetvalue{#1'/option@name}{#3}% \pgfkeyssetvalue{#1'+/option@name}{#3}% \pgfkeyssetvalue{#1'-/option@name}{#3}% \pgfkeyssetvalue{#1'*/option@name}{#3}% \pgfkeyssetvalue{#1':/option@name}{#3}% } \def\forest@declarebooleanregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname \pgfkeysalso{% #1/.code={% \ifstrequal{##1}{1}{% \forestrset{#3}{1}% }{% \ifstrequal{##1}{0}{% \forestrset{#3}{0}% }{% \pgfmathifthenelse{##1}{1}{0}% \forestrlet{#3}\pgfmathresult }% }% }, #1/.default=1, #2/not #3/.code={\forestrset{#3}{0}}, #2/if #3/.code 2 args={% \forestrget{#3}\forest@temp@option@value \ifnum\forest@temp@option@value=1 \pgfkeysalso{##1}% \else \pgfkeysalso{##2}% \fi }, }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@count{##1}{#3}}% } \forestset{ declare toks register/.code={% \forest@declareregisterhandler\forest@declaretoksregister@handler{#1}% }, declare autowrapped toks register/.code={% \forest@declareregisterhandler\forest@declareautowrappedtoksregister@handler{#1}% }, declare keylist register/.code={% \forest@declareregisterhandler\forest@declarekeylistregister@handler{#1}% }, declare dimen register/.code={% \forest@declareregisterhandler\forest@declaredimenregister@handler{#1}% }, declare count register/.code={% \forest@declareregisterhandler\forest@declarecountregister@handler{#1}% }, declare boolean register/.code={% \forest@declareregisterhandler\forest@declarebooleanregister@handler{#1}% }, } \forestset{ declare toks register=temptoksa,temptoksa={}, declare toks register=temptoksb,temptoksb={}, declare toks register=temptoksc,temptoksc={}, declare toks register=temptoksd,temptoksd={}, declare keylist register=tempkeylista,tempkeylista'={}, declare keylist register=tempkeylistb,tempkeylistb'={}, declare keylist register=tempkeylistc,tempkeylistc'={}, declare keylist register=tempkeylistd,tempkeylistd'={}, declare dimen register=tempdima,tempdima'={0pt}, declare dimen register=tempdimb,tempdimb'={0pt}, declare dimen register=tempdimc,tempdimc'={0pt}, declare dimen register=tempdimd,tempdimd'={0pt}, declare dimen register=tempdimx,tempdimx'={0pt}, declare dimen register=tempdimy,tempdimy'={0pt}, declare dimen register=tempdiml,tempdiml'={0pt}, declare dimen register=tempdims,tempdims'={0pt}, declare count register=tempcounta,tempcounta'={0}, declare count register=tempcountb,tempcountb'={0}, declare count register=tempcountc,tempcountc'={0}, declare count register=tempcountd,tempcountd'={0}, declare boolean register=tempboola,tempboola={0}, declare boolean register=tempboolb,tempboolb={0}, declare boolean register=tempboolc,tempboolc={0}, declare boolean register=tempboold,tempboold={0}, } \def\forest@node@Nametoid#1{% #1 = name \csname forest@id@of@#1\endcsname } \def\forest@node@Ifnamedefined#1#2#3{% #1 = name, #2=true,#3=false \ifcsvoid{forest@id@of@#1}{#3}{#2}% } \def\forest@node@setname#1{% \def\forest@temp@setname{y}% \def\forest@temp@silent{n}% \def\forest@temp@propagating{n}% \forest@node@setnameoralias{#1}% } \def\forest@node@setname@silent#1{% \def\forest@temp@setname{y}% \def\forest@temp@silent{y}% \def\forest@temp@propagating{n}% \forest@node@setnameoralias{#1}% } \def\forest@node@setalias#1{% \def\forest@temp@setname{n}% \def\forest@temp@silent{n}% \def\forest@temp@propagating{n}% \forest@node@setnameoralias{#1}% } \def\forest@node@setalias@silent#1{% \def\forest@temp@setname{n}% \def\forest@temp@silent{y}% \def\forest@temp@propagating{n}% \forest@node@setnameoralias{#1}% } \def\forest@node@setnameoralias#1{% \ifstrempty{#1}{% \forest@node@setnameoralias{node@\forest@cn}% }{% \forest@node@Ifnamedefined{#1}{% \if y\forest@temp@propagating % this will find a unique name, eventually: \@escapeif{\forest@node@setnameoralias{#1@\forest@cn}}% \else\@escapeif{% \if y\forest@temp@setname \@escapeif{\forest@node@setnameoralias@nameclash{#1}}% \else\@escapeif{% setting an alias: clashing with alias is not a problem \forestOget{\forest@node@Nametoid{#1}}{name}\forest@temp \expandafter\ifstrequal\expandafter{\forest@temp}{#1}{% \forest@node@setnameoralias@nameclash{#1}% }{% \forest@node@setnameoralias@do{#1}% }% }\fi }\fi }{% \forest@node@setnameoralias@do{#1}% }% }% } \def\forest@node@setnameoralias@nameclash#1{% \if y\forest@temp@silent \forest@fornode{\forest@node@Nametoid{#1}}{% \def\forest@temp@propagating{y}% \forest@node@setnameoralias{}% }% \forest@node@setnameoralias@do{#1}% \else \PackageError{forest}{Node name "#1" is already used}{}% \fi } \def\forest@node@setnameoralias@do#1{% \if y\forest@temp@setname \csdef{forest@id@of@\forestove{name}}{}% \forestoeset{name}{#1}% \fi \csedef{forest@id@of@#1}{\forest@cn}% } \forestset{ TeX/.code={#1}, TeX'/.code={\appto\forest@externalize@loadimages{#1}#1}, TeX''/.code={\appto\forest@externalize@loadimages{#1}}, options/.code={\forestset{#1}}, typeout/.style={TeX={\typeout{#1}}}, declare toks={name}{}, name/.code={% override the default setter \forest@fornode{\forest@setter@node}{\forest@node@setname{#1}}% }, name/.default={}, name'/.code={% override the default setter \forest@fornode{\forest@setter@node}{\forest@node@setname@silent{#1}}% }, name'/.default={}, alias/.code={\forest@fornode{\forest@setter@node}{\forest@node@setalias{#1}}}, alias'/.code={\forest@fornode{\forest@setter@node}{\forest@node@setalias@silent{#1}}}, begin draw/.code={\begin{tikzpicture}}, end draw/.code={\end{tikzpicture}}, declare keylist register=default preamble, default preamble'={}, declare keylist register=preamble, preamble'={}, declare autowrapped toks={content}{}, % #1 = which option to split, #2 = separator (one char!), #3 = receiving options %%% begin listing region: split_option split option/.style n args=3{split/.process args={O}{#1}{#2}{#3}} %%% end listing region: split_option , split register/.style n args=3{% #1 = which register to split, #2 = separator (one char!), #3 = receiving options split/.process args={R}{#1}{#2}{#3}, }, TeX={% \def\forest@split@sourcevalues{}% \def\forest@split@sourcevalue{}% \def\forest@split@receivingoptions{}% \def\forest@split@receivingoption{}% }, split/.code n args=3{% #1 = string to split, #2 = separator (one char!), #3 = receiving options \forest@saveandrestoremacro\forest@split@sourcevalues{% \forest@saveandrestoremacro\forest@split@sourcevalue{% \forest@saveandrestoremacro\forest@split@receivingoptions{% \forest@saveandrestoremacro\forest@split@receivingoption{% \def\forest@split@sourcevalues{#1#2}% \edef\forest@split@receivingoptions{#3,}% \def\forest@split@receivingoption{}% \safeloop \expandafter\forest@split\expandafter{\forest@split@sourcevalues}{#2}\forest@split@sourcevalue\forest@split@sourcevalues \ifdefempty\forest@split@receivingoptions{}{% \expandafter\forest@split\expandafter{\forest@split@receivingoptions}{,}\forest@temp\forest@split@receivingoptions \ifdefempty\forest@temp{}{\let\forest@split@receivingoption\forest@temp\def\forest@temp{}}% }% \edef\forest@marshal{% \noexpand\pgfkeysalso{\forest@split@receivingoption={\expandonce{\forest@split@sourcevalue}}}% }\forest@marshal \ifdefempty\forest@split@sourcevalues{\forest@tempfalse}{\forest@temptrue}% \ifforest@temp \saferepeat }}}}% }, declare count={grow}{270}, TeX={% a hack for grow-reversed connection, and compass-based grow specification \forest@copycommandkey{/forest/grow}{/forest/grow@@}% %\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}, Autoforward={anchor}{ node options-=anchor, node options+={anchor={##1}} }, anchor'/.style={anchor@no@compass=true,anchor=#1}, anchor+'/.style={anchor@no@compass=true,anchor+=#1}, anchor-'/.style={anchor@no@compass=true,anchor-=#1}, anchor*'/.style={anchor@no@compass=true,anchor*=#1}, anchor:'/.style={anchor@no@compass=true,anchor:=#1}, anchor'+'/.style={anchor@no@compass=true,anchor'+=#1}, anchor'-'/.style={anchor@no@compass=true,anchor'-=#1}, anchor'*'/.style={anchor@no@compass=true,anchor'*=#1}, anchor':'/.style={anchor@no@compass=true,anchor':=#1}, % /tikz/forest anchor/.style={ % /forest/TeX={\forestanchortotikzanchor{#1}\forest@temp@anchor}, % anchor/.expand once=\forest@temp@anchor % }, declare toks={calign}{midpoint}, TeX={% \forest@copycommandkey{/forest/calign}{/forest/calign'}% }, 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) % = % (!u.parent anchor)--(.child anchor)\forestoption{edge label}; \forestoption{edge label};% }, edge path'/.style={ edge path={% \noexpand\path[\forestoption{edge}]% #1% \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{0pt}, declare dimen=y{0pt}, 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}{anchor=base}, declare toks={tikz}{}, afterthought/.style={tikz+={#1}}, 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}}, plain content/.style={content format={\forestoption{content}}}, math content/.style={content format={\noexpand\ensuremath{\forestoption{content}}}}, declare toks={node format}{% \noexpand\node (\forestoption{name})% [\forestoption{node options}]% {\foresteoption{content format}};% }, node format'/.style={ node format={\noexpand\node(\forestoption{name})#1;} }, tabular@environment/.style={content format={% \noexpand\begin{tabular}[\forestoption{base}]{\forestoption{align}}% \forestoption{content}% \noexpand\end{tabular}% }}, declare toks={align}{}, TeX={% \forest@copycommandkey{/forest/align}{/forest/align'}% %\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={% \forest@copycommandkey{/forest/base}{/forest/base'}% %\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 to/.store in=\forest@unknownto, unknown to=node options, unknown key error/.code={\PackageError{forest}{Unknown keyval: \detokenize{#1}}{}}, content to/.store in=\forest@contentto, content to=content, .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{\forest@unknownto={\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}, 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@iftikzkey#1#2#3{% #1 = key name, #2 = true code, #3 = false code \forest@temptrue \pgfkeysifdefined{/tikz/\pgfkeyscurrentname}{}{% \pgfkeysifdefined{/tikz/\pgfkeyscurrentname/.@cmd}{}{% \pgfkeysifdefined{/pgf/\pgfkeyscurrentname}{}{% \pgfkeysifdefined{/pgf/\pgfkeyscurrentname/.@cmd}{}{% \forest@tempfalse }}}}% \ifforest@temp\@escapeif{#2}\else\@escapeif{#3}\fi } \def\forest@ifoptionortikzkey#1#2#3{% #1 = key name, #2 = true code, #3 = false code \forest@temptrue \pgfkeysifdefined{/forest/\pgfkeyscurrentname}{}{% \pgfkeysifdefined{/forest/\pgfkeyscurrentname/.@cmd}{}{% \forest@iftikzkey{#1}{}{}% }}% \ifforest@temp\@escapeif{#2}\else\@escapeif{#3}\fi } \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@compat@ignoreinvalidsteps#1{#1} \def\forest@relatednode@option@setter#1.#2=#3\forest@END{% \forest@forthis{% \forest@relatednode@option@compat@ignoreinvalidsteps{% \forest@nameandgo{#1}% \let\forest@setter@node\forest@cn }% }% \ifnum\forest@setter@node=0 \else \forestset{#2={#3}}% \fi \def\forest@setter@node{\forest@cn}% }% \def\forest@split#1#2#3#4{% #1=list (assuming that the list is nonempty and finishes with the separator), #2 = sep, #3 = cs receiving first, #4 = cs receiving last \def\forest@split@@##1#2##2\forest@split@@##3##4{\def##3{##1}\def##4{##2}}% \forest@split@@#1\forest@split@@{#3}{#4}} \forestset{ for tree'/.style 2 args={#1,for children={for tree'={#1}{#2}},#2}, if/.code n args={3}{% \pgfmathparse{#1}% \ifnum\pgfmathresult=0 \@escapeif{\pgfkeysalso{#3}}% \else \@escapeif{\pgfkeysalso{#2}}% \fi }, if nodewalk valid/.code n args={3}{% \edef\forest@marshal{% \unexpanded{\forest@forthis{% \forest@nodewalk{% on invalid={fake}{#1}, TeX={\global\let\forest@global@temp\forest@cn} }{}% }% \def\forest@cn}{\forest@cn}\unexpanded{% \ifnum\forest@global@temp=0 \@escapeif{\pgfkeysalso{#3}}% \else \@escapeif{\pgfkeysalso{#2}}% \fi}% }\forest@marshal }, if nodewalk empty/.code n args={3}{% \forest@forthis{% \forest@nodewalk{% on invalid={fake}{#1}, TeX={\global\let\forest@global@temp\forest@nodewalk@n}, }{}% }% \ifnum\forest@global@temp=0 \@escapeif{\pgfkeysalso{#2}}% \else \@escapeif{\pgfkeysalso{#3}}% \fi }, where/.style n args={3}{for tree={if={#1}{#2}{#3}}}, where nodewalk valid/.style n args={3}{for tree={if nodewalk valid={#1}{#2}{#3}}}, where nodewalk empty/.style n args={3}{for tree={if nodewalk empty={#1}{#2}{#3}}}, repeat/.code 2 args={% \pgfmathtruncatemacro\forest@temp{#1}% \expandafter\forest@repeatkey\expandafter{\forest@temp}{#2}% }, until/.code 2 args={% \ifstrempty{#1}{% \forest@untilkey{\ifnum\forest@cn=0\else\relax\forestloopbreak\fi}{on invalid={fake}{#2}}% }{% \forest@untilkey{\pgfmathifthenelse{#1}{"\noexpand\forestloopbreak"}{""}\pgfmathresult}{#2}% }% }, while/.code 2 args={% \ifstrempty{#1}{% \forest@untilkey{\ifnum\forest@cn=0\relax\forestloopbreak\fi}{on invalid={fake}{#2}}% }{% \forest@untilkey{\pgfmathifthenelse{not(#1)}{"\noexpand\forestloopbreak"}{""}\pgfmathresult}{#2}% }% }, do until/.code 2 args={% \ifstrempty{#1}{% \forest@dountilkey{\ifnum\forest@cn=0\else\relax\forestloopbreak\fi}{on invalid={fake}{#2}}% }{% \forest@dountilkey{\pgfmathifthenelse{#1}{"\noexpand\forestloopbreak"}{""}\pgfmathresult}{#2}% }% }, do while/.code 2 args={% \ifstrempty{#1}{% \forest@dountilkey{\ifnum\forest@cn=0\relax\forestloopbreak\fi}{on invalid={fake}{#2}}% }{% \forest@dountilkey{\pgfmathifthenelse{not(#1)}{"\noexpand\forestloopbreak"}{""}\pgfmathresult}{#2}% }% }, until nodewalk valid/.code 2 args={% \forest@untilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@cn=0\relax\else\forestloopbreak\fi}}{}}}{#2}% }, while nodewalk valid/.code 2 args={% \forest@untilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@cn=0\relax\forestloopbreak\fi}}{}}}{#2}% }, do until nodewalk valid/.code 2 args={% \forest@dountilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@cn=0\relax\else\forestloopbreak\fi}}{}}}{#2}% }, do while nodewalk valid/.code 2 args={% \forest@dountilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@cn=0\relax\forestloopbreak\fi}}{}}}{#2}% }, until nodewalk empty/.code 2 args={% \forest@untilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@nodewalk@n=0\relax\forestloopbreak\fi}}{}}}{#2}% }, while nodewalk empty/.code 2 args={% \forest@untilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@nodewalk@n=0\relax\else\forestloopbreak\fi}}{}}}{#2}% }, do until nodewalk empty/.code 2 args={% \forest@dountilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@nodewalk@n=0\relax\forestloopbreak\fi}}{}}}{#2}% }, do while nodewalk empty/.code 2 args={% \forest@dountilkey{\forest@forthis{% \forest@nodewalk{on invalid={fake}{#1},TeX={\ifnum\forest@nodewalk@n=0\relax\else\forestloopbreak\fi}}{}}}{#2}% }, break/.code={\forestloopBreak{#1}}, break/.default=0, } \def\forest@repeatkey#1#2{% \safeRKloop \ifnum\safeRKloopn>#1\relax \csuse{safeRKbreak@\the\safeRKloop@depth true}% \fi \expandafter\unless\csname ifsafeRKbreak@\the\safeRKloop@depth\endcsname \pgfkeysalso{#2}% \safeRKrepeat } \def\forest@untilkey#1#2{% #1 = condition, #2 = keys \safeRKloop #1% \expandafter\unless\csname ifsafeRKbreak@\the\safeRKloop@depth\endcsname \pgfkeysalso{#2}% \safeRKrepeat } \def\forest@dountilkey#1#2{% #1 = condition, #2 = keys \safeRKloop \pgfkeysalso{#2}% #1% \expandafter\unless\csname ifsafeRKbreak@\the\safeRKloop@depth\endcsname \safeRKrepeat } \def\forestloopbreak{% \csname safeRKbreak@\the\safeRKloop@depth true\endcsname } \def\forestloopBreak#1{% \csname safeRKbreak@\number\numexpr\the\safeRKloop@depth-#1\relax true\endcsname } \def\forestloopcount{% \csname safeRKloopn@\number\numexpr\the\safeRKloop@depth\endcsname } \def\forestloopCount#1{% \csname safeRKloopn@\number\numexpr\the\safeRKloop@depth-#1\endcsname } \pgfmathdeclarefunction{forestloopcount}{1}{% \edef\pgfmathresult{\forestloopCount{\ifstrempty{#1}{0}{#1}}}% } \forest@copycommandkey{/forest/repeat}{/forest/nodewalk/repeat} \forest@copycommandkey{/forest/while}{/forest/nodewalk/while} \forest@copycommandkey{/forest/do while}{/forest/nodewalk/do while} \forest@copycommandkey{/forest/until}{/forest/nodewalk/until} \forest@copycommandkey{/forest/do until}{/forest/nodewalk/do until} \forest@copycommandkey{/forest/if}{/forest/nodewalk/if} \forest@copycommandkey{/forest/if nodewalk valid}{/forest/nodewalk/if nodewalk valid} \forestset{ aggregate postparse/.is choice, aggregate postparse/int/.code={% \let\forest@aggregate@pgfmathpostparse\forest@aggregate@pgfmathpostparse@toint}, aggregate postparse/none/.code={% \let\forest@aggregate@pgfmathpostparse\relax}, aggregate postparse/print/.code={% \let\forest@aggregate@pgfmathpostparse\forest@aggregate@pgfmathpostparse@print}, aggregate postparse/macro/.code={% \let\forest@aggregate@pgfmathpostparse\forest@aggregate@pgfmathpostparse@usemacro}, aggregate postparse macro/.store in=\forest@aggregate@pgfmathpostparse@macro, } \def\forest@aggregate@pgfmathpostparse@print{% \pgfmathprintnumberto{\pgfmathresult}{\pgfmathresult}% } \def\forest@aggregate@pgfmathpostparse@toint{% \expandafter\forest@split\expandafter{\pgfmathresult.}{.}\pgfmathresult\forest@temp } \def\forest@aggregate@pgfmathpostparse@usemacro{% \forest@aggregate@pgfmathpostparse@macro } \let\forest@aggregate@pgfmathpostparse\relax \pgfkeys{ /handlers/.aggregate/.code n args=4{% % #1 = start value % #2 = pgfmath expression for every step % #3 = pgfmath expression for after walk % #4 = nodewalk \edef\forest@marshal{% \unexpanded{\forest@aggregate{#1}{#2}{#3}{#4}}{\pgfkeyscurrentpath}% }\forest@marshal }, /handlers/.sum/.style 2 args={/handlers/.aggregate={0}{(##1)+(#1)}{##1}{#2}}, /handlers/.count/.style={/handlers/.aggregate={0}{1+(##1)}{##1}{#1}}, /handlers/.average/.style 2 args={/handlers/.aggregate={0}{(##1)+(#1)}{##1/\forestregister{aggregate n}}{#2}}, /handlers/.product/.style 2 args={/handlers/.aggregate={1}{(#1)*(##1)}{##1}{#2}}, /handlers/.min/.style 2 args={/handlers/.aggregate={}{min(#1,##1)}{##1}{#2}}, /handlers/.max/.style 2 args={/handlers/.aggregate={}{max(#1,##1)}{##1}{#2}}, /forest/declare count register={aggregate n}, } \def\forest@aggregate#1#2#3#4#5{% % #5 = current path \def\forest@aggregate@result{#1}% \forest@forthis{% \forestrset{aggregate n}{0}% \forest@nodewalk{#4}{% TeX={% \forestreset{aggregate n}{\number\numexpr\forestrv{aggregate n}+1}% \def\forest@marshal##1{\pgfmathparse{#2}}% \expandafter\forest@marshal\expandafter{\forest@aggregate@result}% \let\forest@aggregate@result\pgfmathresult }% }{}% }% \def\forest@marshal##1{\pgfmathparse{#3}}% \expandafter\forest@marshal\expandafter{\forest@aggregate@result}% \let\forest@aggregate@result\pgfmathresult \let\forest@temp@pgfmathpostparse\pgfmathpostparse \let\pgfmathpostparse\forest@aggregate@pgfmathpostparse \pgfmathqparse{\forest@aggregate@result pt}% \let\pgfmathpostparse\forest@temp@pgfmathpostparse \let\forest@aggregate@result\pgfmathresult \pgfkeysalso{#5/.expand once=\forest@aggregate@result}% } \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}}% } \pgfmathdeclarefunction{min_s}{2}{% #1 = node, #2 = context node (for growth rotation) \forest@forthis{% \forest@nameandgo{#1}% \forest@compute@minmax@ls{#2}% \pgfmathsetmacro\pgfmathresult{\forestove{min@s}}% }% } \pgfmathdeclarefunction{min_l}{2}{% #1 = node, #2 = context node (for growth rotation) \forest@forthis{% \forest@nameandgo{#1}% \forest@compute@minmax@ls{#2}% \pgfmathsetmacro\pgfmathresult{\forestove{min@l}}% }% } \pgfmathdeclarefunction{max_s}{2}{% #1 = node, #2 = context node (for growth rotation) \forest@forthis{% \forest@nameandgo{#1}% \forest@compute@minmax@ls{#2}% \pgfmathsetmacro\pgfmathresult{\forestove{max@s}}% }% } \pgfmathdeclarefunction{max_l}{2}{% #1 = node, #2 = context node (for growth rotation) \forest@forthis{% \forest@nameandgo{#1}% \forest@compute@minmax@ls{#2}% \pgfmathsetmacro\pgfmathresult{\forestove{max@l}}% }% } \def\forest@compute@minmax@ls#1{% #1 = nodewalk; in the context of which node? {% \pgftransformreset \forest@forthis{% \forest@nameandgo{#1}% \pgftransformrotate{-\forestove{grow}}% }% \forestoget{min x}\forest@temp@minx \forestoget{min y}\forest@temp@miny \forestoget{max x}\forest@temp@maxx \forestoget{max y}\forest@temp@maxy \pgfpointtransformed{\pgfqpoint{\forest@temp@minx}{\forest@temp@miny}}% \forestoeset{min@l}{\the\pgf@x}% \forestoeset{min@s}{\the\pgf@y}% \forestoeset{max@l}{\the\pgf@x}% \forestoeset{max@s}{\the\pgf@y}% \pgfpointtransformed{\pgfqpoint{\forest@temp@minx}{\forest@temp@maxy}}% \ifdim\pgf@x<\forestove{min@l}\relax\forestoeset{min@l}{\the\pgf@x}\fi \ifdim\pgf@y<\forestove{min@s}\relax\forestoeset{min@s}{\the\pgf@y}\fi \ifdim\pgf@x>\forestove{max@l}\relax\forestoeset{max@l}{\the\pgf@x}\fi \ifdim\pgf@y>\forestove{max@s}\relax\forestoeset{max@s}{\the\pgf@y}\fi \pgfpointtransformed{\pgfqpoint{\forest@temp@maxx}{\forest@temp@miny}}% \ifdim\pgf@x<\forestove{min@l}\relax\forestoeset{min@l}{\the\pgf@x}\fi \ifdim\pgf@y<\forestove{min@s}\relax\forestoeset{min@s}{\the\pgf@y}\fi \ifdim\pgf@x>\forestove{max@l}\relax\forestoeset{max@l}{\the\pgf@x}\fi \ifdim\pgf@y>\forestove{max@s}\relax\forestoeset{max@s}{\the\pgf@y}\fi \pgfpointtransformed{\pgfqpoint{\forest@temp@maxx}{\forest@temp@maxy}}% \ifdim\pgf@x<\forestove{min@l}\relax\forestoeset{min@l}{\the\pgf@x}\fi \ifdim\pgf@y<\forestove{min@s}\relax\forestoeset{min@s}{\the\pgf@y}\fi \ifdim\pgf@x>\forestove{max@l}\relax\forestoeset{max@l}{\the\pgf@x}\fi \ifdim\pgf@y>\forestove{max@s}\relax\forestoeset{max@s}{\the\pgf@y}\fi % smuggle out \edef\forest@marshal{% \noexpand\forestoeset{min@l}{\forestove{min@l}}% \noexpand\forestoeset{min@s}{\forestove{min@s}}% \noexpand\forestoeset{max@l}{\forestove{max@l}}% \noexpand\forestoeset{max@s}{\forestove{max@s}}% }\expandafter }\forest@marshal } \def\forest@pgfmathhelper@attribute@toks#1#2{% \forest@forthis{% \forest@nameandgo{#1}% \ifnum\forest@cn=0 \def\pgfmathresult{}% \else \forestoget{#2}\pgfmathresult \fi }% } \def\forest@pgfmathhelper@attribute@dimen#1#2{% \forest@forthis{% \forest@nameandgo{#1}% \ifnum\forest@cn=0 \def\pgfmathresult{0pt}% \else \forestoget{#2}\forest@temp \pgfmathparse{+\forest@temp}% \fi }% } \def\forest@pgfmathhelper@attribute@count#1#2{% \forest@forthis{% \forest@nameandgo{#1}% \ifnum\forest@cn=0 \def\pgfmathresult{0}% \else \forestoget{#2}\forest@temp \pgfmathtruncatemacro\pgfmathresult{\forest@temp}% \fi }% } \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@nodewalk@n{0} \def\forest@nodewalk@historyback{0,} \def\forest@nodewalk@historyforward{0,} \def\forest@nodewalk@origin{0} \def\forest@nodewalk@config@everystep@independent@before#1{% #1 = every step keylist \forestrset{every step}{#1}% } \def\forest@nodewalk@config@everystep@independent@after{% \noexpand\forestrset{every step}{\forestrv{every step}}% } \def\forest@nodewalk@config@history@independent@before{% \def\forest@nodewalk@n{0}% \edef\forest@nodewalk@origin{\forest@cn}% \def\forest@nodewalk@historyback{0,}% \def\forest@nodewalk@historyforward{0,}% } \def\forest@nodewalk@config@history@independent@after{% \edef\noexpand\forest@nodewalk@n{\expandonce{\forest@nodewalk@n}}% \edef\noexpand\forest@nodewalk@origin{\expandonce{\forest@nodewalk@origin}}% \edef\noexpand\forest@nodewalk@historyback{\expandonce{\forest@nodewalk@historyback}}% \edef\noexpand\forest@nodewalk@historyforward{\expandonce{\forest@nodewalk@historyforward}}% } \def\forest@nodewalk@config@everystep@shared@before#1{}% #1 = every step keylist \def\forest@nodewalk@config@everystep@shared@after{} \def\forest@nodewalk@config@history@shared@before{} \def\forest@nodewalk@config@history@shared@after{} \def\forest@nodewalk@config@everystep@inherited@before#1{}% #1 = every step keylist \let\forest@nodewalk@config@everystep@inherited@after\forest@nodewalk@config@everystep@independent@after \def\forest@nodewalk@config@history@inherited@before{} \let\forest@nodewalk@config@history@inherited@after\forest@nodewalk@config@history@independent@after \def\forest@nodewalk#1#2{% #1 = nodewalk, #2 = every step keylist \def\forest@nodewalk@config@everystep@method{independent}% \def\forest@nodewalk@config@history@method{independent}% \def\forest@nodewalk@config@oninvalid{inherited}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \forest@Nodewalk{#1}{#2}% }% } \def\forest@Nodewalk#1#2{% #1 = nodewalk, #2 = every step keylist \edef\forest@marshal{% \noexpand\pgfqkeys{/forest/nodewalk}{\unexpanded{#1}}% \csname forest@nodewalk@config@everystep@\forest@nodewalk@config@everystep@method @after\endcsname \csname forest@nodewalk@config@history@\forest@nodewalk@config@history@method @after\endcsname }% \csname forest@nodewalk@config@everystep@\forest@nodewalk@config@everystep@method @before\endcsname{#2}% \csname forest@nodewalk@config@history@\forest@nodewalk@config@history@method @before\endcsname \forest@nodewalk@fakefalse \forest@marshal } \pgfmathdeclarefunction{valid}{1}{% \forest@forthis{% \forest@nameandgo{#1}% \edef\pgfmathresult{\ifnum\forest@cn=0 0\else 1\fi}% }% } \pgfmathdeclarefunction{invalid}{1}{% \forest@forthis{% \forest@nameandgo{#1}% \edef\pgfmathresult{\ifnum\forest@cn=0 1\else 0\fi}% }% } \newif\ifforest@nodewalk@fake \def\forest@nodewalk@oninvalid{error} \def\forest@nodewalk@makestep{% \ifnum\forest@cn=0 \csname forest@nodewalk@makestep@oninvalid@\forest@nodewalk@config@oninvalid\endcsname \else \forest@nodewalk@makestep@ \fi } \def\forest@nodewalk@makestep@oninvalid@step{\forest@nodewalk@makestep@} \def\forest@nodewalk@makestep@oninvalid@error{\PackageError{forest}{nodewalk stepped to the invalid node; stack: "\forest@nodewalk@currentstepname"}{}}% \let\forest@nodewalk@makestep@oninvalid@fake\relax \def\forest@nodewalk@makestep@oninvalid@compatfake{% \forest@deprecated{last step in stack "\forest@nodewalk@currentstepname", which stepped on an invalid node; enabled by "compat=ignoreinvalidsteps". Use "on invalid={fake}{...}" or "for Nodewalk={on invalid=fake}{...}{...}" instead.}% }% \def\forest@nodewalk@makestep@oninvalid@inherited{\csname forest@nodewalk@makestep@oninvalid@\forest@nodewalk@oninvalid\endcsname} \def\forest@nodewalk@makestep@{% \ifforest@nodewalk@fake \else \edef\forest@nodewalk@n{\number\numexpr\forest@nodewalk@n+1}% \epreto\forest@nodewalk@historyback{\forest@cn,}% \def\forest@nodewalk@historyforward{0,}% \ifforestdebug\forest@nodewalk@makestep@debug\fi \forest@process@keylist@register{every step}% \fi } \def\forest@nodewalk@makestep@debug{% \edef\forest@marshal{% \noexpand\typeout{\ifforest@nodewalk@fake fake \fi "\forest@nodewalk@currentstepname" step to node id=\forest@cn, content=\forestoption{content}}% }\forest@marshal }% \forestset{ debug/.is if=forestdebug, } \def\forest@handlers@savecurrentpath{% \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% \let\forest@currentkey\pgfkeyscurrentkey \pgfkeys@split@path \edef\forest@currentpath{\pgfkeyscurrentpath}% \let\forest@currentname\pgfkeyscurrentname } \pgfkeys{/handlers/save current path/.code={\forest@handlers@savecurrentpath}} \newif\ifforest@nodewalkstephandler@style \newif\ifforest@nodewalkstephandler@autostep \newif\ifforest@nodewalkstephandler@stripfakesteps \newif\ifforest@nodewalkstephandler@muststartatvalidnode \newif\ifforest@nodewalkstephandler@makefor \let\forest@nodewalkstephandler@styletrueorfalse\forest@nodewalkstephandler@stylefalse \def\forest@nodewalk@currentstepname{} \forestset{ /forest/define@step/style/.is if=forest@nodewalkstephandler@style, /forest/define@step/autostep/.is if=forest@nodewalkstephandler@autostep, % the following is useful because some macros use grouping (by \forest@forthis or similar) and therefore, after making the last step, revert \forest@cn to the original value, essentially making a fake step /forest/define@step/strip fake steps/.is if=forest@nodewalkstephandler@stripfakesteps, % this can never happen with autosteps ... /forest/define@step/autostep/.append code={% \ifforest@nodewalkstephandler@autostep \forest@nodewalkstephandler@stripfakestepsfalse \fi }, /forest/define@step/must start at valid node/.is if=forest@nodewalkstephandler@muststartatvalidnode, /forest/define@step/n args/.store in=\forest@nodewalkstephandler@nargs, /forest/define@step/make for/.is if=forest@nodewalkstephandler@makefor, /forest/define@step/@bare/.style={strip fake steps=false,must start at valid node=false,make for=false}, define long step/.code n args=3{% \forest@nodewalkstephandler@styletrueorfalse % true for end users; but in the package, most of steps are defined by .code \forest@nodewalkstephandler@autostepfalse \forest@nodewalkstephandler@stripfakestepstrue \forest@nodewalkstephandler@muststartatvalidnodetrue % most steps can only start at a valid node \forest@nodewalkstephandler@makefortrue % make for prefix? \def\forest@nodewalkstephandler@nargs{0}% \pgfqkeys{/forest/define@step}{#2}% \forest@temp@toks{#3}% handler code \ifforest@nodewalkstephandler@style \expandafter\forest@temp@toks\expandafter{% \expandafter\pgfkeysalso\expandafter{\the\forest@temp@toks}% }% \fi \ifforest@nodewalkstephandler@autostep \apptotoks\forest@temp@toks{\forest@nodewalk@makestep}% \fi \ifforest@nodewalkstephandler@stripfakesteps \expandafter\forest@temp@toks\expandafter{\expandafter\forest@nodewalk@stripfakesteps\expandafter{\the\forest@temp@toks}}% \fi \ifforest@nodewalkstephandler@muststartatvalidnode \edef\forest@marshal{% \noexpand\forest@temp@toks{% \unexpanded{% \ifnum\forest@cn=0 \csname forest@nodewalk@start@oninvalid@\forest@nodewalk@oninvalid\endcsname{#1}% \else }% \noexpand\@escapeif{\the\forest@temp@toks}% \noexpand\fi }% }\forest@marshal \fi \pretotoks\forest@temp@toks{\appto\forest@nodewalk@currentstepname{,#1}}% \expandafter\forest@temp@toks\expandafter{\expandafter\forest@saveandrestoremacro\expandafter\forest@nodewalk@currentstepname\expandafter{\the\forest@temp@toks}}% \ifforestdebug \epretotoks\forest@temp@toks{\noexpand\typeout{Starting step "#1" from id=\forest@cn \ifnum\forest@nodewalkstephandler@nargs>0 with args ####1\fi \ifnum\forest@nodewalkstephandler@nargs>1 ,####2\fi \ifnum\forest@nodewalkstephandler@nargs>2 ,####3\fi \ifnum\forest@nodewalkstephandler@nargs>3 ,####4\fi \ifnum\forest@nodewalkstephandler@nargs>4 ,####5\fi \ifnum\forest@nodewalkstephandler@nargs>5 ,####6\fi \ifnum\forest@nodewalkstephandler@nargs>6 ,####7\fi \ifnum\forest@nodewalkstephandler@nargs>7 ,####8\fi \ifnum\forest@nodewalkstephandler@nargs>8 ,####9\fi }}% \fi \def\forest@temp{/forest/nodewalk/#1/.code}% \ifnum\forest@nodewalkstephandler@nargs<2 \eappto\forest@temp{=}% \else\ifnum\forest@nodewalkstephandler@nargs=2 \eappto\forest@temp{ 2 args=}% \else \eappto\forest@temp{ n args={\forest@nodewalkstephandler@nargs}}% \fi\fi \eappto\forest@temp{{\the\forest@temp@toks}}% \expandafter\pgfkeysalso\expandafter{\forest@temp}% \ifforest@nodewalkstephandler@makefor \ifnum\forest@nodewalkstephandler@nargs=0 \forestset{% for #1/.code={\forest@forstepwrapper{#1}{##1}}, }% \else\ifnum\forest@nodewalkstephandler@nargs=1 \forestset{% for #1/.code 2 args={\forest@forstepwrapper{#1={##1}}{##2}}, }% \else \forestset{% for #1/.code n args/.expanded=% {\number\numexpr\forest@nodewalkstephandler@nargs+1}% {\noexpand\forest@forstepwrapper{#1\ifnum\forest@nodewalkstephandler@nargs>0=\fi\forest@util@nargs{####}{\number\numexpr\forest@nodewalkstephandler@nargs}{0}}{####\number\numexpr\forest@nodewalkstephandler@nargs+1}}, }% \fi\fi \fi }, } \def\forest@forstepwrapper#1#2{\forest@forthis{\forest@nodewalk{#1}{#2}}} \def\forest@util@nargs#1#2#3{% #1 = prefix (#, ##, ...), #2 = n args, #3=start; returns {#start}{#start+1}...{#start+n} \ifnum#2>0 {#1\number\numexpr#3+1}\fi \ifnum#2>1 {#1\number\numexpr#3+2}\fi \ifnum#2>2 {#1\number\numexpr#3+3}\fi \ifnum#2>3 {#1\number\numexpr#3+4}\fi \ifnum#2>4 {#1\number\numexpr#3+5}\fi \ifnum#2>5 {#1\number\numexpr#3+6}\fi \ifnum#2>6 {#1\number\numexpr#3+7}\fi \ifnum#2>7 {#1\number\numexpr#3+8}\fi \ifnum#2>8 {#1\number\numexpr#3+9}\fi } \def\forest@nodewalk@start@oninvalid@fake#1{} \def\forest@nodewalk@start@oninvalid@real#1{} \def\forest@nodewalk@start@oninvalid@error#1{\PackageError{forest}{nodewalk step "#1" cannot start at the invalid node}{}} \forestset{ define long step={current}{autostep}{}, define long step={next}{autostep}{\edef\forest@cn{\forestove{@next}}}, define long step={previous}{autostep}{\edef\forest@cn{\forestove{@previous}}}, define long step={parent}{autostep}{\edef\forest@cn{\forestove{@parent}}}, define long step={first}{autostep}{\edef\forest@cn{\forestove{@first}}}, define long step={last}{autostep}{\edef\forest@cn{\forestove{@last}}}, define long step={sibling}{autostep}{% \edef\forest@cn{% \ifnum\forestove{@previous}=0 \forestove{@next}% \else \forestove{@previous}% \fi }% }, define long step={next node}{autostep}{\edef\forest@cn{\forest@node@linearnextid}}, define long step={previous node}{autostep}{\edef\forest@cn{\forest@node@linearpreviousid}}, define long step={first leaf}{autostep}{% \safeloop \edef\forest@cn{\forestove{@first}}% \unless\ifnum\forestove{@first}=0 \saferepeat }, define long step={first leaf'}{autostep}{% \safeloop \unless\ifnum\forestove{@first}=0 \edef\forest@cn{\forestove{@first}}% \saferepeat }, define long step={last leaf}{autostep}{% \safeloop \edef\forest@cn{\forestove{@last}}% \unless\ifnum\forestove{@last}=0 \saferepeat }, define long step={last leaf'}{autostep}{% \safeloop \unless\ifnum\forestove{@last}=0 \edef\forest@cn{\forestove{@last}}% \saferepeat }, define long step={next leaf}{style,strip fake steps=false}{group={do until={n_children()==0}{next node}}}, define long step={previous leaf}{style,strip fake steps=false}{group={do until={n_children()==0}{previous node}}}, define long step={next on tier}{autostep}{% \def\forest@temp{#1}% \ifx\forest@temp\pgfkeysnovalue@text \forestoget{tier}\forest@nodewalk@giventier \else \def\forest@nodewalk@giventier{#1}% \fi \edef\forest@cn{\forest@node@linearnextnotdescendantid}% \safeloop \forestoget{tier}\forest@nodewalk@tier \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier \edef\forest@cn{\forest@node@linearnextid}% \saferepeat }, define long step={previous on tier}{autostep}{% \def\forest@temp{#1}% \ifx\forest@temp\pgfkeysnovalue@text \forestoget{tier}\forest@nodewalk@giventier \else \def\forest@nodewalk@giventier{#1}% \fi \safeloop \edef\forest@cn{\forest@node@linearpreviousid}% \forestoget{tier}\forest@nodewalk@tier \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier \saferepeat }, % define long step={root}{autostep,must start at valid node=false}{% \edef\forest@cn{\forest@node@rootid}}, define long step={root'}{autostep,must start at valid node=false}{% \forestOifdefined{\forest@root}{@parent}{\edef\forest@cn{\forest@root}}{\edef\forest@cn{0}}% }, define long step={origin}{autostep,must start at valid node=false}{\edef\forest@cn{\forest@nodewalk@origin}}, % define long step={n}{autostep,n args=1}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \edef\forest@cn{\forest@node@nthchildid{\forest@temp@n}}% }, define long step={n}{autostep,make for=false,n args=1}{% % Yes, twice. ;-) % n=1 and n(ext) \def\forest@nodewalk@temp{#1}% \ifx\forest@nodewalk@temp\pgfkeysnovalue@text \edef\forest@cn{\forestove{@next}}% \else \pgfmathtruncatemacro\forest@temp@n{#1}% \edef\forest@cn{\forest@node@nthchildid{\forest@temp@n}}% \fi }, define long step={n'}{autostep,n args=1}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \edef\forest@cn{\forest@node@nbarthchildid{\forest@temp@n}}% }, define long step={to tier}{autostep,n args=1}{% \def\forest@nodewalk@giventier{#1}% \safeloop \forestoget{tier}\forest@nodewalk@tier \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier \forestoget{@parent}\forest@cn \saferepeat }, % define long step={name}{autostep,n args=1,must start at valid node=false}{% \edef\forest@cn{% \forest@node@Ifnamedefined{#1}{\forest@node@Nametoid{#1}}{0}% }% }, define long step={id}{autostep,n args=1,must start at valid node=false}{% \forestOifdefined{#1}{@parent}{\edef\forest@cn{#1}}{\edef\forest@cn{0}}% }, define long step={Nodewalk}{n args=3,@bare}{% #1 = config, #2 = nodewalk \def\forest@nodewalk@config@everystep@method{independent}% \def\forest@nodewalk@config@history@method{shared}% \def\forest@nodewalk@config@oninvalid{inherited}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \pgfqkeys{/forest/nodewalk@config}{#1}% \forest@Nodewalk{#2}{#3}% }% }, define long step={nodewalk}{n args=2,@bare}{% #1 = nodewalk, #2 = every step \forest@nodewalk{#1}{#2}% }, define long step={nodewalk'}{n args=1,@bare}{% #1 = nodewalk, #2 = every step \def\forest@nodewalk@config@everystep@method{inherited}% \def\forest@nodewalk@config@history@method{independent}% \def\forest@nodewalk@config@oninvalid{inherited}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \forest@Nodewalk{#1}{}% }% }, % these must be defined explicitely, as prefix "for" normally introduces the every-step keylist for nodewalk/.code 2 args={% \forest@forthis{\forest@nodewalk{#1}{#2}}}, for nodewalk'/.code={% \def\forest@nodewalk@config@everystep@method{inherited}% \def\forest@nodewalk@config@history@method{independent}% \def\forest@nodewalk@config@oninvalid{inherited}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \forest@forthis{\forest@Nodewalk{#1}{}}% }% }, for Nodewalk/.code n args=3{% #1 = config, #2 = nodewalk, #3 = every-step \def\forest@nodewalk@config@everystep@method{inherited}% \def\forest@nodewalk@config@history@method{independent}% \def\forest@nodewalk@config@oninvalid{inherited}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \pgfqkeys{/forest/nodewalk@config}{#1}% \forest@forthis{\forest@Nodewalk{#2}{#3}}% }% }, copy command key={/forest/for nodewalk}{/forest/nodewalk/for nodewalk}, copy command key={/forest/for nodewalk'}{/forest/nodewalk/for nodewalk'}, copy command key={/forest/for Nodewalk}{/forest/nodewalk/for Nodewalk}, declare keylist register=every step, every step'={}, %%% begin nodewalk config nodewalk@config/.cd, every@step/.is choice, every@step/independent/.code={}, every@step/inherited/.code={}, every@step/shared/.code={}, every step/.store in=\forest@nodewalk@config@everystep@method, every step/.prefix style={every@step=#1}, @history/independent/.code={}, @history/inherited/.code={}, @history/shared/.code={}, history/.store in=\forest@nodewalk@config@history@method, history/.prefix style={@history=#1}, on@invalid/.is choice, on@invalid/error/.code={}, on@invalid/fake/.code={}, on@invalid/step/.code={}, on@invalid/inherited/.code={}, on invalid/.store in=\forest@nodewalk@config@oninvalid, on invalid/.prefix style={on@invalid=#1}, %%% end nodewalk config } \forestset{ define long step={branch}{n args=1,@bare,style}{% branch@@build/.style={branch@build={##1}{}}, @branch={#1}, }, define long step={branch'}{n args=1,@bare,style}{% branch@@build/.style/.expanded={branch@build={####1}{\forestregister{every step},}}, @branch={#1}, }, nodewalk/@branch/.style={ TeX={\forest@temp@toks{}}, split/.process args={r}{#1}{,}{branch@@build}, branch@do, }, nodewalk/branch@build/.code 2 args={% #1 = nodewalk for this branch, #2 = perhaps every step keylist \ifstrempty{#1}{}{% \expandafter\ifstrempty\expandafter{\the\forest@temp@toks}{% \edef\forest@marshal{% \noexpand\forest@temp@toks{for nodewalk={\unexpanded{#1}}{\forestregister{every step}}}% }\forest@marshal }{% \edef\forest@marshal{% \noexpand\forest@temp@toks{for nodewalk={\unexpanded{#1}}{#2\the\forest@temp@toks}}% }\forest@marshal }% }% }, nodewalk/branch@do/.code={% \edef\forest@marshal{% \noexpand\pgfkeysalso{fake={\the\forest@temp@toks}}% }\forest@marshal }, define long step={group}{autostep}{\forest@go{#1}}, nodewalk/fake/.code={% \forest@saveandrestoreifcs{forest@nodewalk@fake}{% \forest@nodewalk@faketrue \pgfkeysalso{#1}% }% }, nodewalk/real/.code={% \forest@saveandrestoreifcs{forest@nodewalk@fake}{% \forest@nodewalk@fakefalse \pgfkeysalso{#1}% }% }, define long step={filter}{n args=2,@bare,style}{% #1 = nodewalk, #2 = condition nodewalk/.expanded={\unexpanded{#1}}{if={\unexpanded{#2}}{\forestregister{every step}}{}}{} }, on@invalid/.is choice, on@invalid/error/.code={}, on@invalid/fake/.code={}, on@invalid/step/.code={}, on invalid/.code 2 args={% \pgfkeysalso{/forest/on@invalid={#1}}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \def\forest@nodewalk@oninvalid{#1}% \pgfkeysalso{#2}% }% }, define long step={strip fake steps}{n args=1,@bare}{% \forest@nodewalk@stripfakesteps{\pgfkeysalso{#1}}}, define long step={walk back}{n args=1,@bare}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \forest@nodewalk@walklist{\forest@nodewalk@historyforward}{\forest@nodewalk@historyback}{\ifnum\forest@cn=0 0\else1\fi}{\forest@temp@n+\ifnum\forest@cn=0 0\else1\fi}{\let\forest@cn\forest@nodewalk@cn\forest@nodewalk@makestep}% \forest@nodewalk@back@updatehistory }, nodewalk/walk back/.default=1, define long step={jump back}{n args=1,@bare}{% \pgfmathtruncatemacro\forest@temp@n{(#1)+\ifnum\forest@cn=0 0\else1\fi}% \forest@nodewalk@walklist{\forest@nodewalk@historyforward}{\forest@nodewalk@historyback}{\forest@temp@n-1}{\forest@temp@n}{\let\forest@cn\forest@nodewalk@cn\forest@nodewalk@makestep}% \forest@nodewalk@back@updatehistory }, nodewalk/jump back/.default=1, define long step={back}{n args=1,@bare}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \forest@nodewalk@walklist{\forest@nodewalk@historyforward}{\forest@nodewalk@historyback}{\ifnum\forest@cn=0 0\else1\fi}{\forest@temp@n+\ifnum\forest@cn=0 0\else1\fi}{\let\forest@cn\forest@nodewalk@cn\forest@saveandrestoreifcs{forest@nodewalk@fake}{\forest@nodewalk@faketrue\forest@nodewalk@makestep}}% \forest@nodewalk@back@updatehistory }, nodewalk/back/.default=1, define long step={walk forward}{n args=1,@bare}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \forest@nodewalk@walklist{\forest@nodewalk@historyback}{\forest@nodewalk@historyforward}{0}{\forest@temp@n}{\let\forest@cn\forest@nodewalk@cn\forest@nodewalk@makestep}% \forest@nodewalk@forward@updatehistory }, nodewalk/walk forward/.default=1, define long step={jump forward}{n args=1,@bare}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \forest@nodewalk@walklist{\forest@nodewalk@historyback}{\forest@nodewalk@historyforward}{\forest@temp@n-1}{\forest@temp@n}{\let\forest@cn\forest@nodewalk@cn\forest@nodewalk@makestep}% \forest@nodewalk@forward@updatehistory }, nodewalk/jump forward/.default=1, define long step={forward}{n args=1,@bare}{% \pgfmathtruncatemacro\forest@temp@n{#1}% \forest@nodewalk@walklist{\forest@nodewalk@historyback}{\forest@nodewalk@historyforward}{0}{\forest@temp@n}{\let\forest@cn\forest@nodewalk@cn\forest@saveandrestoreifcs{forest@nodewalk@fake}{\forest@nodewalk@faketrue\forest@nodewalk@makestep}}% \forest@nodewalk@forward@updatehistory }, nodewalk/forward/.default=1, define long step={last valid'}{@bare}{% \ifnum\forest@cn=0 \forest@nodewalk@tolastvalid \forest@nodewalk@makestep \fi }, define long step={last valid}{@bare}{% \forest@nodewalk@tolastvalid }, define long step={reverse}{n args=1,@bare,make for}{% \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback \global\let\forest@global@tempn\forest@nodewalk@n }}{}% \forest@nodewalk@walklist{}{\forest@global@temp}{0}{\forest@global@tempn}{\let\forest@cn\forest@nodewalk@cn\forest@nodewalk@makestep}% }, define long step={walk and reverse}{n args=1,@bare,make for}{% \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@walklist{}{\noexpand\forest@nodewalk@historyback}{0}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}{\let\noexpand\forest@cn\noexpand\forest@nodewalk@cn\noexpand\forest@nodewalk@makestep}% }\forest@marshal }, define long step={sort}{n args=1,@bare,make for}{% \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback \global\let\forest@global@tempn\forest@nodewalk@n }}{}% \forest@nodewalk@sortlist{\forest@global@temp}{\forest@global@tempn}\forest@sort@ascending }, define long step={sort'}{n args=1,@bare,make for}{% \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback \global\let\forest@global@tempn\forest@nodewalk@n }}{}% \forest@nodewalk@sortlist{\forest@global@temp}{\forest@global@tempn}\forest@sort@descending }, define long step={walk and sort}{n args=1,@bare,make for}{% walk as given, then walk sorted \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@sortlist{\noexpand\forest@nodewalk@historyback}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}\noexpand\forest@sort@ascending }\forest@marshal }, define long step={walk and sort'}{n args=1,@bare,make for}{% \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@sortlist{\noexpand\forest@nodewalk@historyback}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}\noexpand\forest@sort@descending }\forest@marshal }, sort by/.store in=\forest@nodesort@by, define long step={save}{n args=2,@bare,make for}{% #1 = name, #2 = nodewalk \forest@forthis{% \forest@nodewalk{#2,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback \global\let\forest@global@tempn\forest@nodewalk@n }}{}% }% \forest@nodewalk@walklist{}{\forest@global@temp}{0}{\forest@global@tempn}\relax \csedef{forest@nodewalk@saved@#1}{\forest@nodewalk@walklist@walked}% }, define long step={walk and save}{n args=2,@bare,make for}{% #1 = name, #2 = nodewalk \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#2}}% \noexpand\forest@nodewalk@walklist{}{\noexpand\forest@nodewalk@historyback}{0}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}\relax }\forest@marshal \csedef{forest@nodewalk@saved@#1}{\forest@nodewalk@walklist@walked}% }, nodewalk/save history/.code 2 args={% #1 = back, forward \csedef{forest@nodewalk@saved@#1}{\forest@nodewalk@historyback}% \csedef{forest@nodewalk@saved@#2}{\forest@nodewalk@historyforward}% }, define long step={load}{n args=1,@bare,make for}{% \forest@nodewalk@walklist{}{\csuse{forest@nodewalk@saved@#1}0,}{0}{-1}{\ifnum\forest@nodewalk@cn=0 \else\let\forest@cn\forest@nodewalk@cn\forest@nodewalk@makestep\fi}% }, if in saved nodewalk/.code n args=4{% is node #1 in nodewalk #2; yes: #3, no: #4 \forest@forthis{% \forest@go{#1}% \edef\forest@marshal{% \noexpand\pgfutil@in@{,\forest@cn,}{,\csuse{forest@nodewalk@saved@#2},}% }\forest@marshal }% \ifpgfutil@in@ \@escapeif{\pgfkeysalso{#3}}% \else \@escapeif{\pgfkeysalso{#4}}% \fi }, where in saved nodewalk/.style n args=4{ for tree={if in saved nodewalk={#1}{#2}{#3}{#4}} }, nodewalk/options/.code={\forestset{#1}}, nodewalk/TeX/.code={#1}, nodewalk/TeX'/.code={\appto\forest@externalize@loadimages{#1}#1}, nodewalk/TeX''/.code={\appto\forest@externalize@loadimages{#1}}, nodewalk/typeout/.style={TeX={\typeout{#1}}}, % repeat is taken later from /forest/repeat } \def\forest@nodewalk@walklist#1#2#3#4#5{% % #1 = list of preceding, #2 = list to walk % #3 = from, #4 = to % #5 = every step code \let\forest@nodewalk@cn\forest@cn \edef\forest@marshal{% \noexpand\forest@nodewalk@walklist@{#1}{#2}{\number\numexpr#3}{\number\numexpr#4}{1}{0}{\unexpanded{#5}}% }\forest@marshal } \def\forest@nodewalk@walklist@#1#2#3#4#5#6#7{% % #1 = list of walked, #2 = list to walk % #3 = from, #4 = to % #5 = current step n, #6 = steps made % #7 = every step code \def\forest@nodewalk@walklist@walked{#1}% \def\forest@nodewalk@walklist@rest{#2}% \edef\forest@nodewalk@walklist@stepsmade{#6}% \ifnum#4<0 \forest@temptrue \else \ifnum#5>#4\relax \forest@tempfalse \else \forest@temptrue \fi \fi \ifforest@temp \edef\forest@nodewalk@cn{\forest@csvlist@getfirst@{#2}}% \ifnum\forest@nodewalk@cn=0 #7% \else \ifnum#5>#3\relax #7% \edef\forest@nodewalk@walklist@stepsmade{\number\numexpr#6+1}% \fi \forest@csvlist@getfirstrest@{#2}\forest@nodewalk@cn\forest@nodewalk@walklist@rest \@escapeifif{% \edef\forest@marshal{% \noexpand\forest@nodewalk@walklist@ {\forest@nodewalk@cn,#1}{\forest@nodewalk@walklist@rest}{#3}{#4}{\number\numexpr#5+1}{\forest@nodewalk@walklist@stepsmade}{\unexpanded{#7}}% }\forest@marshal }% \fi \fi } \def\forest@nodewalk@back@updatehistory{% \ifnum\forest@cn=0 \let\forest@nodewalk@historyback\forest@nodewalk@walklist@rest \let\forest@nodewalk@historyforward\forest@nodewalk@walklist@walked \else \expandafter\forest@csvlist@getfirstrest@\expandafter{\forest@nodewalk@walklist@walked}\forest@temp\forest@nodewalk@historyforward \edef\forest@nodewalk@historyback{\forest@temp,\forest@nodewalk@walklist@rest}% \fi } \def\forest@nodewalk@forward@updatehistory{% \let\forest@nodewalk@historyforward\forest@nodewalk@walklist@rest \let\forest@nodewalk@historyback\forest@nodewalk@walklist@walked } \def\forest@go#1{% \def\forest@nodewalk@config@everystep@method{independent}% \def\forest@nodewalk@config@history@method{inherited}% \def\forest@nodewalk@config@oninvalid{inherited}% \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% \forest@Nodewalk{#1}{}% }% } \def\forest@csvlist@getfirst@#1{% assuming that the list is nonempty and finishes with a comma \forest@csvlist@getfirst@@#1\forest@csvlist@getfirst@@} \def\forest@csvlist@getfirst@@#1,#2\forest@csvlist@getfirst@@{#1} \def\forest@csvlist@getrest@#1{% assuming that the list is nonempty and finishes with a comma \forest@csvlist@getrest@@#1\forest@csvlist@getrest@@} \def\forest@csvlist@getrest@@#1,#2\forest@csvlist@getrest@@{#2} \def\forest@csvlist@getfirstrest@#1#2#3{% assuming that the list is nonempty and finishes with a comma % #1 = list, #2 = cs receiving first, #3 = cs receiving rest \forest@csvlist@getfirstrest@@#1\forest@csvlist@getfirstrest@@{#2}{#3}} \def\forest@csvlist@getfirstrest@@#1,#2\forest@csvlist@getfirstrest@@#3#4{% \def#3{#1}% \def#4{#2}% } \def\forest@nodewalk@stripfakesteps#1{% % go to the last valid node if the walk contained any nodes, otherwise restore the current node \edef\forest@marshal{% \unexpanded{#1}% \noexpand\ifnum\noexpand\forest@nodewalk@n=\forest@nodewalk@n\relax \def\noexpand\forest@cn{\forest@cn}% \noexpand\else \unexpanded{% \edef\forest@cn{% \expandafter\forest@csvlist@getfirst@\expandafter{\forest@nodewalk@historyback}% }% }% \noexpand\fi }\forest@marshal } \def\forest@nodewalk@tolastvalid{% \ifnum\forest@cn=0 \edef\forest@cn{\expandafter\forest@csvlist@getfirst@\expandafter{\forest@nodewalk@historyback}}% \ifnum\forest@cn=0 \let\forest@cn\forest@nodewalk@origin \fi \fi } \def\forest@nodewalk@sortlist#1#2#3{%#1=list,#2=to,#3=asc/desc \edef\forest@nodewalksort@list{#1}% \expandafter\forest@nodewalk@sortlist@\expandafter{\number\numexpr#2}{#3}% } \def\forest@nodewalk@sortlist@#1#2{%#1=to,#2=asc/desc \safeloop \unless\ifnum\safeloopn>#1\relax \expandafter\forest@csvlist@getfirstrest@\expandafter{\forest@nodewalksort@list}\forest@nodewalksort@cn\forest@nodewalksort@list \csedef{forest@nodesort@\safeloopn}{\forest@nodewalksort@cn}% \saferepeat \edef\forest@nodesort@sortkey{\forest@nodesort@by}% \forest@sort\forest@nodesort@cmpnodes\forest@nodesort@let#2{1}{#1}% \def\forest@nodewalksort@sorted{}% \safeloop \unless\ifnum\safeloopn>#1\relax \edef\forest@cn{\csname forest@nodesort@\safeloopn\endcsname}% \forest@nodewalk@makestep \saferepeat } \forestset{ define long step={min}{n args=1,@bare,make for}{% the first min in the argument nodewalk \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback }}{}% \forest@nodewalk@minmax{\forest@global@temp}{-1}{<}{\forest@nodewalk@minmax@node,}% }, define long step={mins}{n args=1,@bare,make for}{% all mins in the argument nodewalk \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback }}{}% \forest@nodewalk@minmax{\forest@global@temp}{-1}{<}{\forest@nodewalk@minmax@nodes}% }, define long step={walk and min}{n args=1,@bare}{% \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@minmax{\noexpand\forest@nodewalk@historyback}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}{<}{\noexpand\forest@nodewalk@minmax@node,}%% }\forest@marshal }, define long step={walk and mins}{n args=1,@bare}{% \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@minmax{\noexpand\forest@nodewalk@historyback}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}{<}{\noexpand\forest@nodewalk@minmax@nodes}%% }\forest@marshal }, define long step={min in nodewalk}{@bare}{% find the first min in the preceding nodewalk, step to it \forest@nodewalk@minmax{\forest@nodewalk@historyback}{-1}{<}{\forest@nodewalk@minmax@node,}% }, define long step={mins in nodewalk}{@bare}{% find mins in the preceding nodewalk, step to mins \forest@nodewalk@minmax{\forest@nodewalk@historyback}{-1}{<}{\forest@nodewalk@minmax@nodes}% }, define long step={min in nodewalk'}{@bare}{% find the first min in the preceding nodewalk, step to min in history \forest@nodewalk@minmax{\forest@nodewalk@historyback}{-1}{<}{}% }, % define long step={max}{n args=1,@bare,make for}{% the first max in the argument nodewalk \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback }}{}% \forest@nodewalk@minmax{\forest@global@temp}{-1}{>}{\forest@nodewalk@minmax@node,}% }, define long step={maxs}{n args=1,@bare,make for}{% all maxs in the argument nodewalk \forest@nodewalk{#1,TeX={% \global\let\forest@global@temp\forest@nodewalk@historyback }}{}% \forest@nodewalk@minmax{\forest@global@temp}{-1}{>}{\forest@nodewalk@minmax@nodes}% }, define long step={walk and max}{n args=1,@bare}{% \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@minmax{\noexpand\forest@nodewalk@historyback}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}{>}{\noexpand\forest@nodewalk@minmax@node,}%% }\forest@marshal }, define long step={walk and maxs}{n args=1,@bare}{% \edef\forest@marshal{% \noexpand\pgfkeysalso{\unexpanded{#1}}% \noexpand\forest@nodewalk@minmax{\noexpand\forest@nodewalk@historyback}{\noexpand\forest@nodewalk@n-\forest@nodewalk@n}{>}{\noexpand\forest@nodewalk@minmax@nodes}%% }\forest@marshal }, define long step={max in nodewalk}{@bare}{% find the first max in the preceding nodewalk, step to it \forest@nodewalk@minmax{\forest@nodewalk@historyback}{-1}{>}{\forest@nodewalk@minmax@node,}% }, define long step={maxs in nodewalk}{@bare}{% find maxs in the preceding nodewalk, step to maxs \forest@nodewalk@minmax{\forest@nodewalk@historyback}{-1}{>}{\forest@nodewalk@minmax@nodes}% }, define long step={max in nodewalk'}{@bare}{% find the first max in the preceding nodewalk, step to max in history \forest@nodewalk@minmax{\forest@nodewalk@historyback}{-1}{>}{}% }, } \def\forest@nodewalk@minmax#1#2#3#4{% % #1 = list of nodes % #2 = max index in list (start with 1) % #3 = min/max = ascending/descending = % #4 = how many results? 1 = {\forest@nodewalk@minmax@node,}, all={\forest@nodewalk@minmax@nodes}, walk in history={} \edef\forest@nodesort@sortkey{\forest@nodesort@by}% \edef\forest@nodewalk@minmax@N{\number\numexpr#2}% \edef\forest@nodewalk@minmax@n{}% \edef\forest@nodewalk@minmax@list{#1}% \def\forest@nodewalk@minmax@nodes{}% \def\forest@nodewalk@minmax@node{}% \ifdefempty{\forest@nodewalk@minmax@list}{% }{% \safeloop \expandafter\forest@csvlist@getfirstrest@\expandafter{\forest@nodewalk@minmax@list}\forest@nodewalk@minmax@cn\forest@nodewalk@minmax@list \ifnum\forest@nodewalk@minmax@cn=0 \else \ifdefempty{\forest@nodewalk@minmax@node}{% \edef\forest@nodewalk@minmax@node{\forest@nodewalk@minmax@cn}% \edef\forest@nodewalk@minmax@nodes{\forest@nodewalk@minmax@cn,}% \edef\forest@nodewalk@minmax@n{\safeloopn}% }{% \csedef{forest@nodesort@1}{\forest@nodewalk@minmax@node}% \csedef{forest@nodesort@2}{\forest@nodewalk@minmax@cn}% \forest@nodesort@cmpnodes{2}{1}% \if=\forest@sort@cmp@result \edef\forest@nodewalk@minmax@node{\forest@nodewalk@minmax@cn}% \epreto\forest@nodewalk@minmax@nodes{\forest@nodewalk@minmax@cn,}% \edef\forest@nodewalk@minmax@n{\safeloopn}% \else \if#3\forest@sort@cmp@result \edef\forest@nodewalk@minmax@node{\forest@nodewalk@minmax@cn}% \edef\forest@nodewalk@minmax@nodes{\forest@nodewalk@minmax@cn,}% \edef\forest@nodewalk@minmax@n{\safeloopn}% \fi \fi }% \fi \ifdefempty{\forest@nodewalk@minmax@list}{\forest@tempfalse}{\forest@temptrue}% \ifnum\safeloopn=\forest@nodewalk@minmax@N\relax\forest@temptrue\fi \ifforest@temp \saferepeat \edef\forest@nodewalk@minmax@list{#4}% \ifdefempty\forest@nodewalk@minmax@list{% \forestset{nodewalk/jump back=\forest@nodewalk@minmax@n-1}% CHECK }{% \safeloop \expandafter\forest@csvlist@getfirstrest@\expandafter{\forest@nodewalk@minmax@list}\forest@cn\forest@nodewalk@minmax@list \forest@nodewalk@makestep \ifdefempty{\forest@nodewalk@minmax@list}{\forest@tempfalse}{\forest@temptrue}% \ifforest@temp \saferepeat }% }% } \newtoks\forest@nodewalk@shortsteps@resolution \newif\ifforest@nodewalk@areshortsteps \pgfqkeys{/forest/nodewalk}{ .unknown/.code={% \forest@nodewalk@areshortstepsfalse \pgfkeysifdefined{/forest/\pgfkeyscurrentname/@.cmd}{% }{% \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text % no value, so possibly short steps \forest@nodewalk@shortsteps@resolution{}% \forest@nodewalk@areshortstepstrue \expandafter\forest@nodewalk@shortsteps\pgfkeyscurrentname==========,% "=" and "," cannot be short steps, so they are good as delimiters \fi }% \ifforest@nodewalk@areshortsteps \@escapeif{\expandafter\pgfkeysalso\expandafter{\the\forest@nodewalk@shortsteps@resolution}}% \else \@escapeif{\pgfkeysalso{/forest/\pgfkeyscurrentname={#1}}}% \fi }, } \def\forest@nodewalk@shortsteps{% \futurelet\forest@nodewalk@nexttoken\forest@nodewalk@shortsteps@ } \def\forest@nodewalk@shortsteps@{% \ifx\forest@nodewalk@nexttoken=% \let\forest@nodewalk@nextop\forest@nodewalk@shortsteps@end \else \ifx\forest@nodewalk@nexttoken\bgroup \letcs\forest@nodewalk@nextop{forest@shortstep@group}% \else \let\forest@nodewalk@nextop\forest@nodewalk@shortsteps@@ \fi \fi \forest@nodewalk@nextop } \def\forest@nodewalk@shortsteps@@#1{% \ifcsdef{forest@shortstep@#1}{% \csname forest@shortstep@#1\endcsname }{% \forest@nodewalk@areshortstepsfalse \forest@nodewalk@shortsteps@end }% } \csdef{forest@nodewalk@defshortstep@0@args}#1#2{% \csdef{forest@shortstep@#1}{% \apptotoks\forest@nodewalk@shortsteps@resolution{,#2}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@1@args}#1#2{% \csdef{forest@shortstep@#1}##1{% \edef\forest@marshal####1{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@2@args}#1#2{% \csdef{forest@shortstep@#1}##1##2{% \edef\forest@marshal####1####2{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@3@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3{% \edef\forest@marshal####1####2####3{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@4@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3##4{% \edef\forest@marshal####1####2####3####4{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}{##4}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@5@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3##4##5{% \edef\forest@marshal####1####2####3####4####5{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}{##4}{##5}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@6@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3##4##5##6{% \edef\forest@marshal####1####2####3####4####5####6{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}{##4}{##5}{##6}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@7@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3##4##5##6##7{% \edef\forest@marshal####1####2####3####4####5####6####7{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}{##4}{##5}{##6}{##7}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@8@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3##4##5##6##7##8{% \edef\forest@marshal####1####2####3####4####5####6####7####8{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}}% \forest@nodewalk@shortsteps}} \csdef{forest@nodewalk@defshortstep@9@args}#1#2{% \csdef{forest@shortstep@#1}##1##2##3##4##5##6##7##8##9{% \edef\forest@marshal####1####2####3####4####5####6####7####8####9{#2}% \eapptotoks\forest@nodewalk@shortsteps@resolution{,\forest@marshal{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}}% \forest@nodewalk@shortsteps}} \forestset{ define short step/.code n args=3{% #1 = short step, #2 = n args, #3 = long step \csname forest@nodewalk@defshortstep@#2@args\endcsname{#1}{#3}% }, } \def\forest@nodewalk@shortsteps@end#1,{} \forestset{ define short step={group}{1}{group={#1}}, % {braces} are special define short step={p}{0}{previous}, define short step={n}{0}{next}, define short step={u}{0}{parent}, define short step={s}{0}{sibling}, define short step={c}{0}{current}, define short step={o}{0}{origin}, define short step={r}{0}{root}, define short step={R}{0}{root'}, define short step={P}{0}{previous leaf}, define short step={N}{0}{next leaf}, define short step={F}{0}{first leaf}, define short step={L}{0}{last leaf}, define short step={>}{0}{next on tier}, define short step={<}{0}{previous on tier}, define short step={1}{0}{n=1}, define short step={2}{0}{n=2}, define short step={3}{0}{n=3}, define short step={4}{0}{n=4}, define short step={5}{0}{n=5}, define short step={6}{0}{n=6}, define short step={7}{0}{n=7}, define short step={8}{0}{n=8}, define short step={9}{0}{n=9}, define short step={l}{0}{last}, define short step={b}{0}{back}, define short step={f}{0}{forward}, define short step={v}{0}{last valid}, define short step={*}{2}{repeat={#1}{#2}}, for 1/.style={for nodewalk={n=1}{#1}}, for 2/.style={for nodewalk={n=2}{#1}}, for 3/.style={for nodewalk={n=3}{#1}}, for 4/.style={for nodewalk={n=4}{#1}}, for 5/.style={for nodewalk={n=5}{#1}}, for 6/.style={for nodewalk={n=6}{#1}}, for 7/.style={for nodewalk={n=7}{#1}}, for 8/.style={for nodewalk={n=8}{#1}}, for 9/.style={for nodewalk={n=9}{#1}}, for -1/.style={for nodewalk={n'=1}{#1}}, for -2/.style={for nodewalk={n'=2}{#1}}, for -3/.style={for nodewalk={n'=3}{#1}}, for -4/.style={for nodewalk={n'=4}{#1}}, for -5/.style={for nodewalk={n'=5}{#1}}, for -6/.style={for nodewalk={n'=6}{#1}}, for -7/.style={for nodewalk={n'=7}{#1}}, for -8/.style={for nodewalk={n'=8}{#1}}, for -9/.style={for nodewalk={n'=9}{#1}}, } \forestset{ define long step={tree}{}{\forest@node@foreach{\forest@nodewalk@makestep}}, define long step={tree reversed}{}{\forest@node@foreach@reversed{\forest@nodewalk@makestep}}, define long step={tree children-first}{}{\forest@node@foreach@childrenfirst{\forest@nodewalk@makestep}}, define long step={tree children-first reversed}{}{\forest@node@foreach@childrenfirst@reversed{\forest@nodewalk@makestep}}, define long step={tree breadth-first}{}{\forest@node@foreach@breadthfirst{-1}{\forest@nodewalk@makestep}}, define long step={tree breadth-first reversed}{}{\forest@node@foreach@breadthfirst@reversed{-1}{\forest@nodewalk@makestep}}, define long step={descendants}{}{\forest@node@foreachdescendant{\forest@nodewalk@makestep}}, define long step={descendants reversed}{}{\forest@node@foreachdescendant@reversed{\forest@nodewalk@makestep}}, define long step={descendants children-first}{}{\forest@node@foreachdescendant@childrenfirst{\forest@nodewalk@makestep}}, define long step={descendants children-first reversed}{}{\forest@node@foreachdescendant@childrenfirst@reversed{\forest@nodewalk@makestep}}, define long step={descendants breadth-first}{}{\forest@node@foreach@breadthfirst{0}{\forest@nodewalk@makestep}}, define long step={descendants breadth-first reversed}{}{\forest@node@foreach@breadthfirst@reversed{0}{\forest@nodewalk@makestep}}, define long step={level}{n args=1}{% \pgfmathtruncatemacro\forest@temp{#1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst {\forest@temp}% {\noexpand\ifnum\noexpand\forestove{level}=\forest@temp\relax\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={level>}{n args=1}{% \pgfmathtruncatemacro\forest@temp{#1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst {-1}% {\noexpand\ifnum\noexpand\forestove{level}<\forest@temp\relax\noexpand\else\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={level<}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)-1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst {\forest@temp}% {\noexpand\forest@nodewalk@makestep}% }\forest@marshal }, define long step={level reversed}{n args=1}{% \pgfmathtruncatemacro\forest@temp{#1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst@reversed {\forest@temp}% {\noexpand\ifnum\noexpand\forestove{level}=\forest@temp\relax\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={level reversed>}{n args=1}{% \pgfmathtruncatemacro\forest@temp{#1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst@reversed {-1}% {\noexpand\ifnum\noexpand\forestove{level}<\forest@temp\relax\noexpand\else\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={level reversed<}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)-1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst@reversed {\forest@temp}% {\noexpand\forest@nodewalk@makestep}% }\forest@marshal }, % define long step={relative level}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst {\forest@temp}% {\noexpand\ifnum\noexpand\forestove{level}=\forest@temp\relax\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={relative level>}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst {-1}% {\noexpand\ifnum\noexpand\forestove{level}<\forest@temp\relax\noexpand\else\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={relative level<}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}-1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst {\forest@temp}% {\noexpand\forest@nodewalk@makestep}% }\forest@marshal }, define long step={relative level reversed}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst@reversed {\forest@temp}% {\noexpand\ifnum\noexpand\forestove{level}=\forest@temp\relax\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={relative level reversed>}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst@reversed {-1}% {\noexpand\ifnum\noexpand\forestove{level}<\forest@temp\relax\noexpand\else\noexpand\forest@nodewalk@makestep\noexpand\fi}% }\forest@marshal }, define long step={relative level reversed<}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}-1}% \edef\forest@marshal{% \noexpand\forest@node@foreach@breadthfirst@reversed {\forest@temp}% {\noexpand\forest@nodewalk@makestep}% }\forest@marshal }, define long step={children}{}{\forest@node@foreachchild{\forest@nodewalk@makestep}}, define long step={children reversed}{}{\forest@node@foreachchild@reversed{\forest@nodewalk@makestep}}, define long step={current and following siblings}{}{\forest@node@@forselfandfollowingsiblings{\forest@nodewalk@makestep}}, define long step={following siblings}{style}{if nodewalk valid={next}{fake=next,current and following siblings}{}}, define long step={current and preceding siblings}{}{\forest@node@@forselfandprecedingsiblings{\forest@nodewalk@makestep}}, define long step={preceding siblings}{style}{if nodewalk valid={previous}{fake=previous,current and preceding siblings}{}}, define long step={current and following siblings reversed}{}{\forest@node@@forselfandfollowingsiblings@reversed{\forest@nodewalk@makestep}}, define long step={following siblings reversed}{style}{fake=next,current and following siblings reversed}, define long step={current and preceding siblings reversed}{}{\forest@node@@forselfandprecedingsiblings@reversed{\forest@nodewalk@makestep}}, define long step={preceding siblings reversed}{style}{fake=previous,current and preceding siblings reversed}, define long step={siblings}{style}{for nodewalk'={preceding siblings},following siblings}, define long step={siblings reversed}{style}{for nodewalk'={following siblings reversed},preceding siblings reversed}, define long step={ancestors}{style}{while={}{parent},last valid}, define long step={current and ancestors}{style}{current,ancestors}, define long step={following nodes}{style}{while={}{next node},last valid}, define long step={preceding nodes}{style}{while={}{previous node},last valid}, define long step={current and following nodes}{style}{current,following nodes}, define long step={current and preceding nodes}{style}{current,preceding nodes}, } \let\forest@nodewalkstephandler@styletrueorfalse\forest@nodewalkstephandler@styletrue \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}% \ifnum\forest@cn=0 \PackageError{forest}{Cannot use a dynamic key on the invalid node}{}% \fi \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{% \forest@node@Foreach{\forest@last@node}{% \forestoleto{delay}{given options}% \forestoset{given options}{}% }% \forestOeappto{\forest@last@node}{delay}{,\unexpanded{#1}}% \forestOset{\forest@last@node}{given options}{delay={}}% } \def\forest@create@node@and@process@given@options#1{% #1=bracket representation \bracketParse{\forest@createandprocess@collectafterthought}% \forest@last@node=#1\forest@end@create@node } \def\forest@createandprocess@collectafterthought#1\forest@end@create@node{% \forest@node@Compute@numeric@ts@info{\forest@last@node}% \forest@saveandrestoremacro\forest@root{% \let\forest@root\forest@last@node \forestset{process keylist=given options}% }% } \def\forest@saveandrestoremacro#1#2{% #1 = the (zero-arg) macro to save before and restore after processing code in #2 \edef\forest@marshal{% \unexpanded{#2}% \noexpand\def\noexpand#1{\expandonce{#1}}% }\forest@marshal } \def\forest@saveandrestoreifcs#1#2{% #1 = the if cs to save before and restore after processing code in #2 \edef\forest@marshal{% \unexpanded{#2}% \ifbool{#1}{\noexpand\setbool{#1}{true}}{\noexpand\setbool{#1}{false}} }\forest@marshal } \def\forest@saveandrestoretoks#1#2{% #1 = the toks to save before and restore after processing code in #2 \edef\forest@marshal{% \unexpanded{#2}% \noexpand#1{\the#1}% }\forest@marshal } \def\forest@saveandrestoreregister#1#2{% #1 = the register to save before and restore after processing code in #2 \edef\forest@marshal{% \unexpanded{#2}% \noexpand\forestrset{#1}{\forestregister{#1}}% }\forest@marshal } \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@set@root#1#2{% \def\forest@root{#2}% } \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},}% }{}% \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}% \forest@fornode{\forest@last@node}{\forest@node@setalias{forest@last@node}}% }, create'/.code={% \forest@create@node@and@process@given@options{#1}% \forest@fornode{\forest@last@node}{\forest@node@setalias{forest@last@node}}% }, 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={% \def\forest@dynamics@copyhow{0}% \forest@appto@do@dynamics\forest@set@root{#1}% }, 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''}}, sort/.code={% \eapptotoks\forest@do@dynamics{% \noexpand\forest@nodesort \noexpand\forest@sort@ascending {\forest@cn}% {\expandonce{\forest@nodesort@by}}% }% }, sort'/.code={% \eapptotoks\forest@do@dynamics{% \noexpand\forest@nodesort \noexpand\forest@sort@descending {\forest@cn}% {\expandonce{\forest@nodesort@by}}% }% }, sort by/.store in=\forest@nodesort@by, } \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 } \def\forest@nodesort#1#2#3{% #1 = direction, #2 = parent node, #3 = sort key \def\forest@nodesort@sortkey{#3}% \forest@fornode{#2}{\forest@nodesort@#1}% } \def\forest@nodesort@#1{% % prepare the array of child ids \c@pgf@counta=0 \forestoget{@first}\forest@nodesort@id \forest@loop \ifnum\forest@nodesort@id>0 \advance\c@pgf@counta 1 \csedef{forest@nodesort@\the\c@pgf@counta}{\forest@nodesort@id}% \forestOget{\forest@nodesort@id}{@next}\forest@nodesort@id \forest@repeat % sort \forestoget{n children}\forest@nodesort@n \forest@sort\forest@nodesort@cmpnodes\forest@nodesort@let#1{1}{\forest@nodesort@n}% % remove all children \forestoget{@first}\forest@nodesort@id \forest@loop \ifnum\forest@nodesort@id>0 \forest@node@Remove{\forest@nodesort@id}% \forestoget{@first}\forest@nodesort@id \forest@repeat % insert the children in new order \c@pgf@counta=0 \forest@loop \ifnum\c@pgf@counta<\forest@nodesort@n\relax \advance\c@pgf@counta 1 \edef\temp{\csname forest@nodesort@\the\c@pgf@counta\endcsname}% \forest@node@append{\csname forest@nodesort@\the\c@pgf@counta\endcsname}% \forest@repeat } \def\forest@nodesort@cmpnodes#1#2{% \global\let\forest@nodesort@cmpresult\forest@sort@cmp@eq \foreach \forest@temp@pgfmath in \forest@nodesort@sortkey {% \forest@fornode{\csname forest@nodesort@#1\endcsname}{% \pgfmathparse{\forest@temp@pgfmath}\global\let\forest@global@tempa\pgfmathresult}% \forest@fornode{\csname forest@nodesort@#2\endcsname}{% \pgfmathparse{\forest@temp@pgfmath}\global\let\forest@global@tempb\pgfmathresult}% \ifdim\forest@global@tempa pt<\forest@global@tempb pt \global\let\forest@nodesort@cmpresult\forest@sort@cmp@lt \breakforeach \else \ifdim\forest@global@tempa pt>\forest@global@tempb pt \global\let\forest@nodesort@cmpresult\forest@sort@cmp@gt \breakforeach \fi \fi }% \forest@nodesort@cmpresult } \def\forest@nodesort@let#1#2{% \csletcs{forest@nodesort@#1}{forest@nodesort@#2}% } \def\forest@root{0} %%% begin listing region: stages \forestset{ stages/.style={ for root'={ process keylist register=default preamble, process keylist register=preamble }, process keylist=given options, process keylist=before typesetting nodes, typeset nodes stage, process keylist=before packing, pack stage, process keylist=before computing xy, compute xy stage, process keylist=before drawing tree, draw tree stage }, typeset nodes stage/.style={for root'=typeset nodes}, pack stage/.style={for root'=pack}, compute xy stage/.style={for root'=compute xy}, draw tree stage/.style={for root'=draw tree}, } %%% end listing region: stages \forestset{ process keylist/.code={% \forest@process@hook@keylist{#1}{#1 processing order/.try,processing order/.lastretry}}, process keylist'/.code 2 args={\forest@process@hook@keylist@nodynamics{#1}{#2}}, process keylist''/.code 2 args={\forest@process@hook@keylist@{#1}{#2}}, process keylist register/.code={\forest@process@keylist@register{#1}}, process delayed/.code={% \forest@havedelayedoptions{@delay}{#1}% \ifforest@havedelayedoptions \forest@process@hook@keylist@nodynamics{@delay}{#1}% \fi }, do dynamics/.code={% \the\forest@do@dynamics \forest@do@dynamics{}% \forest@node@Compute@numeric@ts@info{\forest@root}% }, declare keylist={given options}{}, declare keylist={before typesetting nodes}{}, declare keylist={before packing}{}, declare keylist={before packing node}{}, declare keylist={after packing node}{}, declare keylist={before computing xy}{}, declare keylist={before drawing tree}{}, declare keylist={delay}{}, delay n/.style 2 args={if={#1==0}{#2}{delay@n={#1}{#2}}}, delay@n/.style 2 args={ if={#1==1}{delay={#2}}{delay={delay@n/.wrap pgfmath arg={{##1}{#2}}{#1-1}}} }, if have delayed/.style 2 args={if have delayed'={processing order}{#1}{#2}}, if have delayed'/.code n args=3{% \forest@havedelayedoptionsfalse \forest@forthis{% \forest@nodewalk{#1}{% TeX={% \forestoget{delay}\forest@temp@delayed \ifdefempty\forest@temp@delayed{}{\forest@havedelayedoptionstrue}% }% }% }% \ifforest@havedelayedoptions\pgfkeysalso{#2}\else\pgfkeysalso{#3}\fi }, typeset nodes/.code={% \forest@drawtree@preservenodeboxes@false \forest@nodewalk {typeset nodes processing order/.try,processing order/.lastretry}% {TeX={\forest@node@typeset}}% }, typeset nodes'/.code={% \forest@drawtree@preservenodeboxes@true \forest@nodewalk {typeset nodes processing order/.try,processing order/.lastretry}% {TeX={\forest@node@typeset}}% }, typeset node/.code={% \forest@drawtree@preservenodeboxes@false \forest@node@typeset }, pack/.code={\forest@pack}, pack'/.code={\forest@pack@onlythisnode}, compute xy/.code={\forest@node@computeabsolutepositions}, draw tree box/.store in=\forest@drawtreebox, draw tree box, draw tree/.code={% \forest@drawtree@preservenodeboxes@false \forest@node@drawtree }, draw tree'/.code={% \forest@drawtree@preservenodeboxes@true \forest@node@drawtree }, %%% begin listing region: draw_tree_method draw tree method/.style={ for nodewalk={ draw tree nodes processing order/.try, draw tree processing order/.retry, processing order/.lastretry }{draw tree node}, for nodewalk={ draw tree edges processing order/.try, draw tree processing order/.retry, processing order/.lastretry }{draw tree edge}, for nodewalk={ draw tree tikz processing order/.try, draw tree processing order/.retry, processing order/.lastretry }{draw tree tikz} }, %%% end listing region: draw_tree_method draw tree node/.code={\forest@draw@node}, draw tree edge/.code={\forest@draw@edge}, draw tree tikz/.code={\forest@draw@tikz}, for nodewalk={processing order/.style={tree}}{}, %given options processing order/.style={processing order}, %before typesetting nodes processing order/.style={processing order}, %before packing processing order/.style={processing order}, %before computing xy processing order/.style={processing order}, %before drawing tree processing order/.style={processing order}, } \newtoks\forest@do@dynamics \newif\ifforest@havedelayedoptions \def\forest@process@hook@keylist#1#2{%,#1=keylist,#2=processing order nodewalk \safeloop \forest@fornode{\forest@root}{\forest@process@hook@keylist@{#1}{#2}}% \expandafter\ifstrempty\expandafter{\the\forest@do@dynamics}{}{% \the\forest@do@dynamics \forest@do@dynamics={}% \forest@node@Compute@numeric@ts@info{\forest@root}% }% \forest@fornode{\forest@root}{\forest@havedelayedoptions{#1}{#2}}% \ifforest@havedelayedoptions \saferepeat } \def\forest@process@hook@keylist@nodynamics#1#2{%#1=keylist,#2=processing order nodewalk % note: this macro works on (nodewalk starting at) the current node \safeloop \forest@forthis{\forest@process@hook@keylist@{#1}{#2}}% \forest@havedelayedoptions{#1}{#2}% \ifforest@havedelayedoptions \saferepeat } \def\forest@process@hook@keylist@#1#2{%#1=keylist,#2=processing order nodewalk \forest@nodewalk{#2}{% TeX={% \forestoget{#1}\forest@temp@keys \ifdefvoid\forest@temp@keys{}{% \forestoset{#1}{}% \expandafter\forestset\expandafter{\forest@temp@keys}% }% }% }% } \def\forest@process@keylist@register#1{% \edef\forest@marshal{% \noexpand\forestset{\forestregister{#1}}% }\forest@marshal } \def\forest@havedelayedoptions#1#2{%#1 = keylist, #2=nodewalk \forest@havedelayedoptionsfalse \forest@forthis{% \forest@nodewalk{#2}{% TeX={% \forestoget{delay}\forest@temp@delayed \ifdefempty\forest@temp@delayed{}{\forest@havedelayedoptionstrue}% \forestolet{#1}\forest@temp@delayed \forestoset{delay}{}% }% }% }% } \def\forest@node@typeset{% \let\forest@next\forest@node@typeset@ \forestoifdefined{@box}{% \forestoget{@box}\forest@temp \ifdefempty\forest@temp{% \locbox\forest@temp@box \forestolet{@box}\forest@temp@box }{% \ifforest@drawtree@preservenodeboxes@ \let\forest@next\relax \fi }% }{% \locbox\forest@temp@box \forestolet{@box}\forest@temp@box }% \def\forest@node@typeset@restore{}% \ifdefined\ifsa@tikz\forest@standalone@hack\fi \forest@next \forest@node@typeset@restore } \def\forest@standalone@hack{% \ifsa@tikz \let\forest@standalone@tikzpicture\tikzpicture \let\forest@standalone@endtikzpicture\endtikzpicture \let\tikzpicture\sa@orig@tikzpicture \let\endtikzpicture\sa@orig@endtikzpicture \def\forest@node@typeset@restore{% \let\tikzpicture\forest@standalone@tikzpicture \let\endtikzpicture\forest@standalone@endtikzpicture }% \fi } \newbox\forest@box \def\forest@pgf@notyetpositioned{not yet positionedPGFINTERNAL} \def\forest@node@typeset@{% \forestanchortotikzanchor{anchor}\forest@temp \edef\forest@marshal{% \noexpand\forestolet{anchor}\noexpand\forest@temp \noexpand\forest@node@typeset@@ \noexpand\forestoset{anchor}{\forestov{anchor}}% }\forest@marshal } \def\forest@node@typeset@@{% \forestoget{name}\forest@nodename \edef\forest@temp@nodeformat{\forestove{node format}}% \gdef\forest@smuggle{}% \setbox0=\hbox{% \begin{tikzpicture}[% /forest/copy command key={/tikz/anchor}{/tikz/forest@orig@anchor}, anchor/.style={% /forest/TeX={\forestanchortotikzanchor{##1}\forest@temp@anchor}, forest@orig@anchor/.expand once=\forest@temp@anchor }] \pgfpositionnodelater{\forest@positionnodelater@save}% \forest@temp@nodeformat \pgfinterruptpath \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{forestcomputenodeboundary}% \endpgfinterruptpath \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}}% \ifforest@drawtree@preservenodeboxes@ \else \forestoset{@box}{}% \fi } \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@process@hook@keylist@nodynamics{before packing node}{current}% \forest@pack@level@nonuniform \forest@pack@aligntiers \forest@pack@sibling@uniform@applyreversed \fi \fi \forestoget{after packing node}\forest@temp@keys \forest@process@hook@keylist@nodynamics{after packing node}{current}% } \def\forest@pack@onlythisnode{% \ifnum\forestove{n children}>0 \forest@pack@computetiers \forest@pack@level@nonuniform \forest@pack@aligntiers \forest@node@foreachchild{\forestoset{s}{0pt}}% \forest@pack@sibling@uniform@applyreversed \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 }% \forestoget{before packing node}\forest@temp@a \forestoget{after packing node}\forest@temp@b \expandafter\expandafter\expandafter\ifstrempty\expandafter\expandafter\expandafter{\expandafter\forest@temp@a\forest@temp@b}{% \forestolet{uniform growth}\forest@pack@cgu@uniformity }{% \forestoset{uniform growth}{0}% }% } \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 \forest@pack@sibling@uniform@main{first}{last}{next}{previous}% \else \forest@pack@sibling@uniform@main{last}{first}{previous}{next}% \fi \else \ifnum\forestove{n children}=1 \csname forest@calign@\forestove{calign}\endcsname \fi \fi } \def\forest@pack@sibling@uniform@main#1#2#3#4{% \forestoget{@#1}\forest@child \edef\forest@marshal{% \noexpand\forest@fornode{\forestove{@#1}}{% \noexpand\forest@node@getedge {positive}% {\forestove{grow}}% \noexpand\forest@temp@edge }% }\forest@marshal \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}% \safeloop \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{\forest@child}{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 \saferepeat \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 \forest@Pointanchor{\forest@temp@child}{child anchor}% \advance\pgf@xa\pgf@x\relax\advance\pgf@ya\pgf@y\relax \forest@pointanchor{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 \forest@Pointanchor{\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 \forest@Pointanchor{\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}{% \ifnum\forestove{n children}>1 \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}% \fi } \csdef{forest@calign@fixed edge angles}{% \ifnum\forestove{n children}>1 \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 \forest@pointanchor{parent anchor}% \edef\forest@ca@parent@anchor@s{\the\pgf@x}% \edef\forest@ca@parent@anchor@l{\the\pgf@y}% \forest@Pointanchor{\forest@ca@first@child}{child anchor}% \edef\forest@ca@first@child@anchor@s{\the\pgf@x}% \edef\forest@ca@first@child@anchor@l{\the\pgf@y}% \forest@Pointanchor{\forest@ca@second@child}{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{% \forest@pointanchor{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{% \forest@pointanchor{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{% \forest@pointanchor{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}% \fi } \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 \forest@pointanchor{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}}% \pgfgettransform\forest@temp@transform \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}}}}% {\forest@pointanchor{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}}% }% \pgfsettransform\forest@temp@transform \csname forest@get#1\forestove{fit}edgeofpath\endcsname\forest@node@edge\forest@node@edge \forestolet{#1@edge@#2}\forest@node@edge \fi } \def\forest@merge@intersectionloop{% \c@pgf@counta=0 \forest@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@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 \safeloop \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 \saferepeat } \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}% } \csdef{forest@compute@node@boundary@regular polygon}{% \forest@mt{corner 1}% \c@pgf@counta=\sides\relax \forest@loop \ifnum\c@pgf@counta>0 \forest@lt{corner \the\c@pgf@counta}% \advance\c@pgf@counta-1 \forest@repeat }% \def\forest@compute@node@boundary@star{% \forest@mt{outer point 1}% \c@pgf@counta=\totalstarpoints\relax \divide\c@pgf@counta2 \forest@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@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@loop \ifnum\c@pgf@counta>0 \forest@lt{puff \the\c@pgf@counta}% \advance\c@pgf@counta-1 \forest@repeat } \def\forest@compute@node@boundary@starburst{ \calculatestarburstpoints \forest@mt{outer point 1}% \c@pgf@counta=\totalpoints\relax \divide\c@pgf@counta2 \forest@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@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}% }% \csdef{forest@compute@node@boundary@rounded rectangle}{% \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}% }% \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{% \edef\forest@marshal{% \noexpand\forest@node@foreachchild{% \noexpand\forest@node@computeabsolutepositions@{\forestove{x}}{\forestove{y}}{\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 \pgfkeysgetvalue{/forest/begin draw/.@cmd}\forest@temp@begindraw \pgfkeysgetvalue{/forest/end draw/.@cmd}\forest@temp@enddraw \edef\forest@marshal{% \noexpand\forest@drawtree@beginbox \expandonce{\forest@temp@begindraw\pgfkeysnovalue\pgfeov}% \noexpand\forest@node@drawtree@ \expandonce{\forest@temp@enddraw\pgfkeysnovalue\pgfeov}% \noexpand\forest@drawtree@endbox }\forest@marshal \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@forthis{\forestset{draw tree method}}% \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 }{}% } \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\forest@cn=\forest@root\relax\else \ifnum\forestove{phantom}=0 \ifnum\forestOve{\forestove{@parent}}{phantom}=0 \edef\forest@temp{\forestove{edge path}}% \forest@temp \fi \fi \fi } \def\forest@draw@tikz{% \forestove{tikz}% } \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 \safeloop \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 \saferepeat \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 \safeloop \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}% \saferepeat \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\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 \forest@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 \forest@repeat \forest@gettightedgeofpath@getedge\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 \safeloop \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 \saferepeat } \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#1{% cs to store the edge into \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}% \safeloop \ifnum\c@pgf@counta<\forest@nminusone\relax \forest@gettightedgeofpath@getedge@loopa \saferepeat \ifnum\forest@nminusone<\forest@n\relax\else \ifnum\csname forest@pi@\forest@nminusone @n\endcsname>0 \forest@gettightedgeofpath@maybemoveto{\forest@nminusone}{0}% \fi \fi \pgfsyssoftpath@getcurrentpath#1% \pgfsyssoftpath@setcurrentpath\pgfutil@empty } \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 \safeloop \ifnum\c@pgf@countb<\csname forest@pi@\the\c@pgf@counta @n\endcsname\relax \forest@gettightedgeofpath@getedge@loopb \saferepeat \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 \safeloop \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 \saferepeat \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% \pgfsyssoftpath@setcurrentpath\pgfutil@empty } \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 \forest@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 \forest@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{% \forest@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 \forest@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 } \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@optimize@ \forest@external@optimize@true \ifforest@install@keys@to@tikz@path@ \tikzset{ fit to/.style={ /forest/for nodewalk=% {TeX={\def\forest@fitto{}},#1}% {TeX={\eappto\forest@fitto{(\forestove{name})}}}, fit/.expanded={\forest@fitto} }, } \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 \NewDocumentEnvironment{forest}{D(){stages}}{% \forest@defstages{#1}% \Collect@Body \forest@env }{} \NewDocumentCommand{\Forest}{s D(){stages} m}{% \forest@defstages{#2}% \IfBooleanTF{#1}{\let\forest@next\forest@env}{\let\forest@next\forest@group@env}% \forest@next{#3}% } \def\forest@defstages#1{% \def\forest@stages{#1}% } \def\forest@group@env#1{{\forest@env{#1}}} \newif\ifforest@externalize@tree@ \newif\ifforest@was@tikzexternalwasenable \newcommand\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 \forest@env@ \fi \fi \forest@standardnode@calibrate \forest@external@next{#1}% } \def\forest@env@{% \iftikzexternalexportnext \tikzifexternalizing{% \let\forest@external@next\forest@begin@externalizing }{% \let\forest@external@next\forest@begin@externalize }% \else \tikzexternalexportnexttrue \fi } \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{\pgfactualjobname}.}% }\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}% \IfFileExists{\tikzexternal@filenameprefix/#1}{\tikzexternal@file@isuptodatetrue}{\tikzexternal@file@isuptodatefalse}% } \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}% \expandafter\forestset\expandafter{\forest@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 \forest@cs@invalidnodeerror\fi \global\pgf@x\forestove{x}% \global\pgf@y\forestove{y}% } \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}% \ifnum\forest@cn=0 \forest@cs@invalidnodeerror\fi \forest@forestcs@anchor{#2}% } \def\forest@cs@invalidnodeerror{% \PackageError{forest}{Attempt to refer to the invalid node by "forest cs"}% } \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}% }% } \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}% \ifnum\forest@cn=0 \forest@cs@invalidnodeerror\fi \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}% } \forestset{ declare count={rotate}{0}, autoforward'={rotate}{node options}, } \newif\ifforest@anchor@snapbordertocompass \newif\ifforest@anchor@forwardtotikz \newif\ifforest@anchor@isborder \def\forestanchortotikzanchor#1#2{% #1 = forest anchor, #2 = macro to receive the tikz anchor \forest@anchor@forwardtotikzfalse \forest@anchor@do{}{#1}{\forest@cn}% \let#2\forest@temp@anchor } \pgfdeclaregenericanchor{child anchor}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{child anchor}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent anchor}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent anchor}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{anchor}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{anchor}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{children}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{children}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{children first}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{children first}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{first}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{first}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent first}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent first}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent last}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent last}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{last}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{last}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{children last}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{children last}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{children'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{children'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{children first'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{children first'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{first'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{first'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent first'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent first'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{parent last'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{parent last'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{last'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{last'}{\forest@referencednodeid}% } \pgfdeclaregenericanchor{children last'}{% \forest@anchor@forwardtotikztrue \forest@anchor@do{#1}{children last'}{\forest@referencednodeid}% } \def\forest@anchor@do#1#2#3{% #1 = shape name, #2 = (potentially) forest anchor, #3 = node id \forest@fornode{#3}{% \def\forest@temp@anchor{#2}% \forest@anchor@snapbordertocompassfalse \forest@anchor@isborderfalse \forest@anchor@to@tikz@anchor \forest@anchor@border@to@compass \ifforest@anchor@forwardtotikz \forest@anchor@forward{#1}% \else \fi }% } \def\forest@anchor@to@tikz@anchor{% \ifcsdef{forest@anchor@@\forest@temp@anchor}{% \csuse{forest@anchor@@\forest@temp@anchor}% \forest@anchor@to@tikz@anchor }{}% } \csdef{forest@anchor@@parent anchor}{% \forestoget{parent anchor}\forest@temp@anchor} \csdef{forest@anchor@@child anchor}{% \forestoget{child anchor}\forest@temp@anchor} \csdef{forest@anchor@@anchor}{% \forestoget{anchor}\forest@temp@anchor} \csdef{forest@anchor@@children'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor{\number\numexpr\forestove{grow}-\forestove{rotate}}% } \csdef{forest@anchor@@parent'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor{\number\numexpr\forestove{grow}-\forestove{rotate}+180}% } \csdef{forest@anchor@@first'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 -\else+\fi90}% } \csdef{forest@anchor@@last'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 +\else-\fi90}% } \csdef{forest@anchor@@parent first'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor@parent{\number\numexpr\forestove{grow}-\forestove{rotate}+180}% \edef\forest@temp@anchor@first{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 -\else+\fi90}% \forest@getaverageangle{\forest@temp@anchor@parent}{\forest@temp@anchor@first}\forest@temp@anchor } \csdef{forest@anchor@@parent last'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor@parent{\number\numexpr\forestove{grow}-\forestove{rotate}+180}% \edef\forest@temp@anchor@last{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 +\else-\fi90}% \forest@getaverageangle{\forest@temp@anchor@parent}{\forest@temp@anchor@last}\forest@temp@anchor } \csdef{forest@anchor@@children first'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor@first{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 -\else+\fi90}% \forest@getaverageangle{\forestove{grow}-\forestove{rotate}}{\forest@temp@anchor@first}\forest@temp@anchor } \csdef{forest@anchor@@children last'}{% \forest@anchor@isbordertrue \edef\forest@temp@anchor@last{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 +\else-\fi90}% \forest@getaverageangle{\forestove{grow}-\forestove{rotate}}{\forest@temp@anchor@last}\forest@temp@anchor } \csdef{forest@anchor@@children}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@children'}% } \csdef{forest@anchor@@parent}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@parent'}% } \csdef{forest@anchor@@first}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@first'}% } \csdef{forest@anchor@@last}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@last'}% } \csdef{forest@anchor@@parent first}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@parent first'}% } \csdef{forest@anchor@@parent last}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@parent last'}% } \csdef{forest@anchor@@children first}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@children first'}% } \csdef{forest@anchor@@children last}{% \forest@anchor@snapbordertocompasstrue \csuse{forest@anchor@@children last'}% } \def\forest@getaverageangle#1#2#3{% \edef\forest@temp{\number\numexpr #1-#2+540}% \pgfmathMod{\forest@temp}{360}\pgfmathtruncatemacro\pgfmathresult{\pgfmathresult} \edef\forest@temp{360+#2+((\pgfmathresult-180)/2)}% \pgfmathMod{\forest@temp}{360}\pgfmathtruncatemacro#3{\pgfmathresult}% } \def\forest@anchor@border@to@compass{% \ifforest@anchor@isborder \ifforest@anchor@snapbordertocompass \forest@anchor@snap@border@to@compass \else \pgfmathMod{\forest@temp@anchor}{360}% \pgfmathtruncatemacro\forest@temp@anchor{\pgfmathresult}% \fi \ifforest@anchor@forwardtotikz \ifcsname pgf@anchor% @\csname pgf@sh@ns@\pgfreferencednodename\endcsname @\csname forest@compass@\forest@temp@anchor\endcsname \endcsname \letcs\forest@temp@anchor{forest@compass@\forest@temp@anchor}% \fi \else \ifforest@anchor@snapbordertocompass \letcs\forest@temp@anchor{forest@compass@\forest@temp@anchor}% \fi \fi \fi } \csdef{forest@compass@0}{east} \csdef{forest@compass@45}{north east} \csdef{forest@compass@90}{north} \csdef{forest@compass@135}{north west} \csdef{forest@compass@180}{west} \csdef{forest@compass@225}{south west} \csdef{forest@compass@270}{south} \csdef{forest@compass@315}{south east} \csdef{forest@compass@360}{east} \def\forest@anchor@snap@border@to@compass{% \pgfmathMod{\forest@temp@anchor}{360}% \pgfmathdivide{\pgfmathresult}{45}% \pgfmathround{\pgfmathresult}% \pgfmathmultiply{\pgfmathresult}{45}% \pgfmathtruncatemacro\forest@temp@anchor{\pgfmathresult}% } \def\forest@anchor@forward#1{% #1 = shape name \ifdefempty\forest@temp@anchor{% \pgf@sh@reanchor{#1}{center}% \xdef\forest@hack@tikzshapeborder{% \noexpand\tikz@shapebordertrue \def\noexpand\tikz@shapeborder@name{\pgfreferencednodename}% }\aftergroup\forest@hack@tikzshapeborder }{% \pgf@sh@reanchor{#1}{\forest@temp@anchor}% }% } \def\forest@referencednodeid{\forest@node@Nametoid{\forest@referencednodename}}% \def\forest@referencednodename{% \expandafter\expandafter\expandafter\forest@referencednodename@\expandafter\pgfreferencednodename\forest@pgf@notyetpositioned\relax } \expandafter\def\expandafter\forest@referencednodename@\expandafter#\expandafter1\forest@pgf@notyetpositioned#2\relax{% \if\relax#1\relax\forest@referencednodename@stripafter#2\relax\fi \if\relax#2\relax#1\fi } \expandafter\def\expandafter\forest@referencednodename@stripafter\expandafter#\expandafter1\forest@pgf@notyetpositioned\relax{#1} \def\forest@Pointanchor#1#2{% #1 = node id, #2 = anchor {% \def\forest@pa@temp@name{name}% \forestOifdefined{#1}{@box}{% \forestOget{#1}{@box}\forest@temp \ifdefempty\forest@temp{}{% \def\forest@pa@temp@name{later@name}% }% }{}% \setbox0\hbox{% \begin{pgfpicture}% \if\relax\forestOve{#1}{#2}\relax \pgfpointanchor{\forestOve{#1}{\forest@pa@temp@name}}{center}% \else \pgfpointanchor{\forestOve{#1}{\forest@pa@temp@name}}{\forestOve{#1}{#2}}% \fi \xdef\forest@global@marshal{% \noexpand\global\noexpand\pgf@x=\the\pgf@x\relax \noexpand\global\noexpand\pgf@y=\the\pgf@y }% \end{pgfpicture}% }% }% \forest@global@marshal } \def\forest@pointanchor#1{% #1 = anchor \forest@Pointanchor{\forest@cn}{#1}% } \ifdefempty{\forest@compat}{}{% \RequirePackage{forest-compat} } \endinput %% %% End of file `forest.sty'.