From 7f11d08fd1940cb3e9b90139b6321e1fcaf38f9c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 30 Jan 2016 23:00:43 +0000 Subject: forest (30jan16) git-svn-id: svn://tug.org/texlive/trunk@39513 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/latex/forest/forest-compat.sty | 170 + Master/texmf-dist/tex/latex/forest/forest-doc.sty | 240 ++ .../texmf-dist/tex/latex/forest/forest-index.sty | 383 ++ .../tex/latex/forest/forest-lib-edges.sty | 74 + .../tex/latex/forest/forest-lib-linguistics.sty | 133 + Master/texmf-dist/tex/latex/forest/forest.sty | 4136 ++++++++++++++++---- 6 files changed, 4293 insertions(+), 843 deletions(-) create mode 100644 Master/texmf-dist/tex/latex/forest/forest-compat.sty create mode 100644 Master/texmf-dist/tex/latex/forest/forest-doc.sty create mode 100644 Master/texmf-dist/tex/latex/forest/forest-index.sty create mode 100644 Master/texmf-dist/tex/latex/forest/forest-lib-edges.sty create mode 100644 Master/texmf-dist/tex/latex/forest/forest-lib-linguistics.sty (limited to 'Master/texmf-dist/tex/latex/forest') diff --git a/Master/texmf-dist/tex/latex/forest/forest-compat.sty b/Master/texmf-dist/tex/latex/forest/forest-compat.sty new file mode 100644 index 00000000000..8921cf5405a --- /dev/null +++ b/Master/texmf-dist/tex/latex/forest/forest-compat.sty @@ -0,0 +1,170 @@ +% \CheckSum{12884} +% \iffalse meta-comment +% forest-index.dtx +%% `forest-compat' defines a compatibility layer of package `forest'. +%% +%% 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 file is a part of package `forest'. For the list of files +%% constituting the package see main source file of the package, +%% `forest.dtx', or the derived `forest.sty'. + +\ProvidesPackage{forest-compat} + +\def\forest@deprecated#1{% + \PackageWarning{forest}{Compatibility mode for #1}% +} +\forestset{@@deprecated/.code={\forest@deprecated{#1}}} +\def\forestcompat#1{\pgfqkeys{/forest/@compat}{#1}} +\forestcompat{ + most/.style={1.0-most}, + all/.style={1.0-all}, + none/.style={}, + silent/.style={\def\forest@deprecated##1{}}, + %%% begin listing region: compat_1.0 + 1.0-most/.style={ + 1.0-triangle,1.0-linear,1.0-nodewalk,1.0-ancestors, + 1.0-fittotree,1.0-for,1.0-forall + }, + 1.0-all/.style={ + 1.0-most, + 1.0-ignoreinvalidsteps,1.0-rotate,1.0-stages,1.0-name + }, + %%% end listing region: compat_1.0 + 1.0-triangle/.style={ + /forest/triangle/.style={ + @@deprecated={key "triangle" from v1.0.x. Use key "roof" from library "linguistics" instead}, + edge path'={% + (.north west)--(!u.south)--(.north east)--cycle + } + } + }, + 1.0-linear/.style={ + /forest/define long step={linear next}{autostep}{% + \forest@deprecated{nodewalk step "linear next" from v1.0. Use key "next node" instead.}% + \edef\forest@cn{\forest@node@linearnextid}}, + /forest/define long step={linear previous}{autostep}{% + \forest@deprecated{nodewalk step "linear previous" from v1.0. Use key "previous node" instead.}% + \edef\forest@cn{\forest@node@linearpreviousid}}, + }, + 1.0-nodewalk/.style={ + /forest/node walk/before walk/.style={}, + /forest/node walk/every step/.style={}, + /forest/node walk/after walk/.style={}, + /forest/node walk/.style={ + @@deprecated={key "node walk" from v1.0. Use key "nodewalk" instead.}, + /forest/node walk/before walk, + /forest/nodewalk/before walk/.style={/forest/node walk/before walk}, + /forest/nodewalk/every step/.style={/forest/node walk/every step}, + /forest/nodewalk/after walk/.style={/forest/node walk/after walk}, + /forest/nodewalk/node walk/.style={before walk,for nodewalk={####1,options={/forest/nodewalk/after walk}}{/forest/nodewalk/every step}}, + for nodewalk={##1,options={/forest/nodewalk/after walk}}{/forest/nodewalk/every step}, + }, + }, + 1.0-ancestors/.style={ + /forest/for ancestors'/.style={ + @@deprecated={key "for ancestors'" from v1.0.x. Use key "for current and ancestors" instead.}, + for current and ancestors={##1}}, + }, + 1.0-fittotree/.style={% + /tikz/fit to tree/.style={ + /forest/@@deprecated={key "/tikz/fit to tree" from v1.0.x. Use "/tikz/fit to=tree" instead.}, + inner sep=0pt,fit to=tree + } + }, + 1.0-for/.style={ + /forest/for/.code 2 args={% #1 = nodewalk, #2 = after walk keylist + \forest@deprecated{Key "for" from v1.0.x. Use key "for group" instead.}% + \forest@forthis{\forest@nodewalk{##1,options={##2}}{}}% + } + }, + 1.0-forall/.style={ + /forest/for all next/.style={ + @@deprecated={Key "for all next" from v1.0.x. Use key "for following siblings" instead.}, + for following siblings={##1}}, + /forest/for all previous/.style={ + @@deprecated={Key "for all previous" from v1.0.x. Use key "for preceding siblings" instead.}, + for preceding siblings={##1}}, + }, + 1.0-ignoreinvalidsteps/.code={% + \def\forest@forstepwrapper##1##2{% + \def\forest@nodewalk@config@everystep@method{independent}% + \def\forest@nodewalk@config@history@method{independent}% + \edef\forest@marshal{% + \def\noexpand\forest@nodewalk@config@oninvalid{compatfake}% + \unexpanded{\forest@Nodewalk{##1}{##2}}% + \def\noexpand\forest@cn{\forest@cn}% + \def\noexpand\forest@nodewalk@config@oninvalid{\forest@nodewalk@config@oninvalid}% + }\forest@marshal + }% + \def\forest@relatednode@option@compat@ignoreinvalidsteps##1{% + \forest@saveandrestoremacro\forest@nodewalk@oninvalid{% + \def\forest@nodewalk@oninvalid{compatfake}% + ##1% + }% + }% + }, + 1.0-rotate/.style={ + /forest/undef option=rotate, + rotate/.style={ + @@deprecate={Using non-autoforwarded key "rotate". Some keys, like "forked edges" and "folder", might produce a wrong result.}, + node options={rotate={##1}}, + }, + }, + 1.0-stages/.style={ + /forest/@@deprecated={Using v1.0.x "stages" style}, + /forest/stages/.style={ + 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, + }, + /forest/TeX={% + \def\forest@defstages##1{% + \def\forest@stages{% + begin forest, + for root'={ + process keylist register=default preamble, + process keylist register=preamble + }, + process keylist=given options, + ##1, + end forest + }% + }% + }, + }, + 1.0-name/.code={% + \forest@deprecated{key "name": using key "name" from v1.0.x, which does not enforce uniqueness. If you really need this, you're doing something wrong.}% + \def\forest@node@setname##1{% + \ifstrempty{##1}{}{% + \forestoeset{name}{##1}% + \csedef{forest@id@of@##1}{\forest@cn}% + }% + }% + \def\forest@node@setalias##1{% + \ifstrempty{##1}{}{% + \csedef{forest@id@of@##1}{\forest@cn}% + }% + }% + }, +} +\expandafter\forestcompat\expandafter{\forest@compat} diff --git a/Master/texmf-dist/tex/latex/forest/forest-doc.sty b/Master/texmf-dist/tex/latex/forest/forest-doc.sty new file mode 100644 index 00000000000..70f84563179 --- /dev/null +++ b/Master/texmf-dist/tex/latex/forest/forest-doc.sty @@ -0,0 +1,240 @@ +%% forest-doc.sty +%% `forest-doc.sty` is an auxiliary package needed to compile the documentation of package `forest`. +%% +%% 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 file is a part of package `forest'. For the list of files +%% constituting the package see main source file of the package, +%% `forest.dtx', or the derived `forest.sty'. +%% +\ProvidesPackage{forest-doc} +\RequirePackage{lstdoc} +\RequirePackage{pgfkeys} +\RequirePackage{forest-index} +% if you want index support, load package "forest-index", but later + +\lstset{language={[LaTeX]TeX},tabsize=4,gobble=2,% + basicstyle=\small\ttfamily,basewidth=0.51em,boxpos=c,pointstyle=\pstyle,moredelim=[is][\pstyle]{~}{~}} +%\lst@InstallKeywords{p}{point}{pointstyle}\relax{keywordstyle}{}ld +\def\pstyle{\color{darkgreen}} +\def\itemnosep{\vspace{-1.4ex}} +\lstset{ + rangebeginprefix=\ \ \%\%\%\ begin\ listing\ region:\ , + rangebeginsuffix=, + rangeendprefix=\ \ \%\%\%\ end\ listing\ region:\ , + rangeendsuffix=, + includerangemarker=false, + keepspaces=true, +} +\newcommand\lstinputregion[3][]{\lstinputlisting[linerange=#3-#3,#1]{#2}} +\def\lst@outputspace{{\ifx\lst@bkgcolor\empty\color{white}\else\lst@bkgcolor\fi\lst@visiblespace}}% this works for acroread, but not for atril :-( + +\lstnewenvironment{forestexample}[1][]{% + \PackageWarning{forest-doc}{Compiling example}{}% + \global\let\lst@intname\@empty + \gdef\lst@sample{}% + \def\forestexample@layout{tree on left}% + \def\forestexample@treebin{box}% + \pgfqkeys{/forestexample}{label format,#1}% + \pgfkeysgetvalue{/forestexample/counter}\forestexample@temp + \ifdefempty\forestexample@temp{}{\addtocounter{\forestexample@temp}{1}}% + \setbox\lst@samplebox=\hbox\bgroup + \pgfkeysvalueof{/forestexample/tree prefix}% + \lst@BeginAlsoWriteFile{\jobname.tmp}% +}{% + \lst@EndWriteFile + \pgfkeysvalueof{/forestexample/tree suffix}% + \egroup + \global\setbox\codebox=\box\lst@samplebox + \global\setbox + \treebox + \csname forestexample@treebin@\forestexample@treebin\endcsname + \pgfkeys{/forestexample/do layout/.expanded=\forestexample@layout}% +} +\pgfqkeys{/forestexample}{% + .unknown/.code={\lstset{\pgfkeyscurrentname={#1}}}, + index/.code={\indexex[not print]{#1}}, + index>/.code={\indexex[not print]>{#1}}, + code prefix/.code={\gdef\lst@sample{#1}}, + tree prefix/.initial={}, + tree suffix/.initial={}, + counter/.initial=lstlisting, + no label/.style={counter={}}, + label format/.store in=\@currentlabel, + label format/.default={\arabic{\pgfkeysvalueof{/forestexample/counter}}}, + tree width/.initial={\dimexpr\linewidth-\wd\codebox- + \glueexpr\pgfkeysvalueof{/forestexample/center skip}\relax\relax}, + layout/.store in=\forestexample@layout, + tree bin/.store in=\forestexample@treebin, + do layout/.is choice, + do layout/export/.code={% + \pgfkeysgetvalue{/forestexample/counter}\forestexample@temp + \ifdefempty\forestexample@temp{}{\addtocounter{\forestexample@temp}{-1}}% + }, + left skip/.initial={\glueexpr 0pt plus .4\linewidth minus \marginparsep + 0pt minus \@totalleftmargin + 0pt minus .75\marginparwidth}, + center skip/.initial={3em plus 0.1\linewidth minus 2em}, + right skip/.initial={0pt plus .4\linewidth}, + tree left skip/.initial=0pt, + tree right skip/.initial=0pt, + code left skip/.initial=0pt, + code right skip/.initial=0pt, + label y offset/.initial={\height-1ex}, % looks better to me this way + do layout/tree on left/.code={% + \begin{list}{}{\leftmargin 0pt} + \item + \@tempdima=\ifdim\totalht\treebox>\totalht\codebox + \dimexpr0.5 \totalht\treebox\relax + \else + \dimexpr0.5 \totalht\codebox\relax + \fi + \mbox{% + \mbox{\hbox to \linewidth{% + \hskip\pgfkeysvalueof{/forestexample/left skip}\relax + \textvcenter{\box\treebox}% + \hskip\pgfkeysvalueof{/forestexample/center skip}\relax + \hbox{\hskip-\@totalleftmargin\box\codebox\hskip\@totalleftmargin}% + \hskip\pgfkeysvalueof{/forestexample/right skip}\relax + }}% + \forestexample@label + }% + \end{list} + }, + v sep/.initial={1ex}, + align/.initial=center, + do layout/tree on top/.code={% + \begin{list}{}{\leftmargin 0pt \parsep 0pt \itemsep \pgfkeysvalueof{/forestexample/v sep}\relax} + \item \forestexample@align{tree}\forestexample@label + \item \forestexample@align{code} + \end{list} + }, + do layout/tree on bottom/.code={% + \begin{list}{}{\leftmargin 0pt \parsep 0pt \itemsep \pgfkeysvalueof{/forestexample/v sep}\relax} + \item \forestexample@align{code}\forestexample@label + \item \forestexample@align{tree} + \end{list} + }, + do layout/only tree/.code={% + \forestexample@align{tree}\forestexample@label + }, + do layout/only code/.code={% + \forestexample@align{code}\forestexample@label + }, +} +\newbox\treebox +\newbox\codebox +\def\forestexample@treebin@box{% + \hbox{\lst@sampleInput}% +} +\def\forestexample@treebin@minipage{% + \hbox{% + \begin{minipage}{\pgfkeysvalueof{/forestexample/tree width}}% + \lst@sampleInput + \end{minipage}% + }% +} +\def\forestexample@label{% + \pgfkeysgetvalue{/forestexample/counter}\forestexample@temp + \ifdefempty\forestexample@temp{}{% + \makebox[0pt][l]{% + \hskip-\linewidth + \hskip-\@totalleftmargin + \hskip\textwidth + \hskip\marginparsep + \raisebox + {\dimexpr\@tempdima+\depth-\pgfkeysvalueof{/forestexample/label y offset}}% + {\hbox to 0pt{\scriptsize(\@currentlabel)}}% + }% + }% +} +\def\forestexample@align#1{% + \pgfkeysgetvalue{/forestexample/align}\forestexample@temp + \mbox{\hbox to \linewidth{% + \csname forestexample@align@left@\forestexample@temp\endcsname + \hspace*{\pgfkeysvalueof{/forestexample/#1 left skip}}% + \mbox{\expandafter\box\csname #1box\endcsname}% + \hspace*{\pgfkeysvalueof{/forestexample/#1 right skip}}% + \csname forestexample@align@right@\forestexample@temp\endcsname + }}% +} +\def\forestexample@align@left@left{} +\def\forestexample@align@right@left{} +\def\forestexample@align@left@right{\hfill} +\def\forestexample@align@right@right{} +\def\forestexample@align@left@center{\hfill} +\def\forestexample@align@right@center{\hfill} +\newcommand\forestexampleimport[1][]{% + \def\forestexample@layout{tree on left}% + \pgfkeysgetvalue{/forestexample/counter}\forestexample@temp + \ifdefempty\forestexample@temp{}{\addtocounter{\forestexample@temp}{1}}% + \pgfqkeys{/forestexample}{% + label format, + do layout/.expanded=\forestexample@layout + }% +} + +\def\totalht#1{\dimexpr\ht#1 + \dp#1\relax} +\def\textvcenter#1{\raisebox{\dimexpr .5\depth-.5\height}{#1}} + +% For some reason, lstdoc's version kills all spaces in defaults ... +\def\lst@syntaxlabel@#1>#2\relax + %{\edef\lst@temp{\zap@space#2 \@empty}} + {\edef\lst@temp{#2}} + + + + +\def\getforestversion#1/#2/#3 v#4 #5\getforestversion{v#4} +\edef\forestversion{% +\expandafter\expandafter\expandafter\getforestversion + \csname ver@forest.sty\endcsname\getforestversion} + +\def\settodayfromforestdateA#1/#2/#3 v#4 #5\settodayfromforestdateA{\def\year{#1}\def\month{#2}\def\day{#3}} +\def\settodayfromforestdate{\expandafter\expandafter\expandafter\settodayfromforestdateA\csname ver@forest.sty\endcsname\settodayfromforestdateA} + +\def\TikZ;{{\rm Ti\emph{k}Z}} +\def\PGF;{\textsc{pgf}} +\def\foRest;{\textsc{Forest}} +\def\FoRest;{\textsc{Forest}} + +\let\keyname\texttt +\newcommand\cmdname[1]{\texttt{\char\escapechar#1}} + +\gdef\greaterthan{>} +\def\gobbleone#1{} + +\newcommand{\Repeat}[1]{% from tex.se http://tex.stackexchange.com/a/16194/16819 + \expandafter\@Repeat\expandafter{\the\numexpr #1\relax}% +} +\def\@Repeat#1{% + \ifnum#1>0 + \expandafter\@@Repeat\expandafter{\the\numexpr #1-1\expandafter\relax\expandafter}% + \else + \expandafter\@gobble + \fi +} +\def\@@Repeat#1#2{% + \@Repeat{#1}{#2}#2% +} +\def\spaces#1{\Repeat{#1}\space} + + +%%% Local Variables: +%%% mode: latex +%%% fill-column: 100 +%%% TeX-command-default: "Make PDF" +%%% TeX-master: "forest-doc" +%%% End: diff --git a/Master/texmf-dist/tex/latex/forest/forest-index.sty b/Master/texmf-dist/tex/latex/forest/forest-index.sty new file mode 100644 index 00000000000..116666290c4 --- /dev/null +++ b/Master/texmf-dist/tex/latex/forest/forest-index.sty @@ -0,0 +1,383 @@ +%% +%% This is file `forest-index.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% forest-index.dtx +%% +%% `forest-index' is an indexing system for the documentation of package `forest', using the package itself. +%% +%% 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 file is a part of package `forest'. For the list of files +%% constituting the package see main source file of the package, +%% `forest.dtx', or the derived `forest.sty'. +%% +\ProvidesPackage{forest-index} +\RequirePackage{forest} +\let\forestindex@LaTeX@index\index +\DeclareDocumentCommand\indexdef{O{} t> m}{% + \IfBooleanTF{#2} + {\let\forestindex@resolvekey\forestindex@resolvekey@long} + {\let\forestindex@resolvekey\forestindex@resolvekey@shortorlong}% + \forestindex@index{definition}{#1}{#3}} +\DeclareDocumentCommand\indexex{O{} t> m}{% + \IfBooleanTF{#2} + {\let\forestindex@resolvekey\forestindex@resolvekey@long} + {\let\forestindex@resolvekey\forestindex@resolvekey@shortorlong}% + \forestindex@index{example}{#1}{#3}} +\DeclareDocumentCommand\indexitem{D(){} O{} t> m}{% + \IfBooleanTF{#3} + {\let\forestindex@resolvekey\forestindex@resolvekey@long} + {\let\forestindex@resolvekey\forestindex@resolvekey@shortorlong}% + \forestindex@index{definition}{default={#1},print format=item,#2}{#4}} +\DeclareDocumentCommand\indexset{O{} t> m}{% + \IfBooleanTF{#2} + {\let\forestindex@resolvekey\forestindex@resolvekey@long} + {\let\forestindex@resolvekey\forestindex@resolvekey@shortorlong}% + \forestindex@index{not print,not index,definition}{set={#1}}{#3}} +\DeclareDocumentCommand\index{D(){} O{} t> m}{% + \IfBooleanTF{#3} + {\let\forestindex@resolvekey\forestindex@resolvekey@long} + {\let\forestindex@resolvekey\forestindex@resolvekey@shortorlong}% + \forestindex@index{#1}{#2}{#4}% +} +\def\forestindex@index#1#2#3{% + \forcsvlist{\forestindex@forkey{#1}{#2}}{#3}% +} +\def\forestindex@forkey#1#2#3{% + \forestindex@resolvekey{#3}% + \forestset{@index/.process args={__o}{#1}{#2}{\forestindex@fullkey}}% +} +\forestset{ + declare boolean register=print, + declare boolean register=index, + declare toks={key}{}, + declare toks={argument}{}, + declare toks={index key}{}, + declare toks={index form}{}, + declare toks={print form}{}, + declare keylist={index key format}{}, + declare keylist={index format}{}, + declare keylist={print format}{}, + declare autowrapped toks register=result, + format'/.style={print format'={#1}, index format'={#1}}, + format/.style={print format={#1}, index format={#1}}, + format+/.style={print format+={#1}, index format+={#1}}, + +format/.style={+print format={#1}, +index format={#1}}, + form/.style={print form={#1},index form={#1}}, + form+/.style={print form+={#1},index form+={#1}}, + +form/.style={+print form={#1},+index form={#1}}, + declare toks register=index entry type, + definition/.style={index entry type=definition}, + normal/.style={index entry type=normal}, + example/.style={index entry type=example}, + normal, + declare toks={index@hypertarget}{}, + every index begin/.style={}, + every index end/.style={}, + declare toks register=stage, + @index/.style n args={3}{ + print, index, index entry type=normal, set'={}, + for nodewalk={ + split={#3}{>}{create@main@entry@node, create@subentry@node}, + if n=0{ + content/.option=key, + }{ + content/.wrap 2 pgfmath args={##1>##2}{content("!parent")}{key}, + } + }{}, + for root'={ + for tree={ + print form/.option=key, + index key/.option=key, + index form/.option=key, + }, + for first leaf'={ + on invalid={fake}{ + every index begin, + #1, + }, + for reverse={ancestors}{on invalid={fake}{@@index/\forestoption{name}/.try}}, + if index entry type={definition}{}{% + on invalid={fake}{@@index/\forestoption{name}/.try}, + }, + on invalid={fake}{ + #2, + every index end + }, + if set={}{}{save@session}, + if index entry type={definition}{save@foridx}{}, + }, + stage={}, + if={index()||print()}{ + index@hypertarget/.expanded={.\forestoption{index key}}, + for descendants={ + index@hypertarget/.wrap 2 pgfmath args={##1.##2}% + {index@hypertarget("!parent")}{index_key}, + }, + }{}, + if index={ + begingroup, + stage=index, + for tree={ + result/.option=index key, + process keylist'={index key format}{current}, + index key/.register=result, + }, + for tree={ + result/.option=index form, + process keylist'={index format}{current}, + index form/.register=result, + }, + where index form={}{}{ + if n=0{ + temptoksb={}, + }{ + temptoksc={}, + for ancestors={ + if index form={}{}{ + temptoksb+/.expanded={\forestregister{temptoksc}% + \noexpand\protect\noexpand\hyperlinknocolor{% + \forestoption{index@hypertarget}}{\forestoption{index form}}}, + temptoksc={,\space}, + }, + }, + if temptoksb={}{}{ + +temptoksb={\protect\space\begingroup\protect\scriptsize}, + temptoksb+={\endgroup}, + }, + }, + temptoksa={}, + result={}, + if n children=0{tempboola}{not tempboola}, + where index form={}{}{ + if tempboola={temptoksd/.expanded={\noexpand\protect\noexpand\hypertarget{% + \forestoption{index@hypertarget}}{}}}{temptoksd={}}, + result+/.expanded={% + \forestregister{temptoksa}% + \forestoption{index key}% + =\forestoption{index form}% + \forestregister{temptoksd}% + \forestregister{temptoksb}% + }, + temptoksa={>}, + temptoksb={}, + }, + result+/.expanded={|indexpagenumber\forestregister{index entry type}}, + TeX/.expanded={\noexpand\forestindex@LaTeX@index{\forestregister{result}}}, + }, + endgroup + }{}, + if print={ + begingroup, + stage=print, + for tree={ + result/.option=print form, + process keylist'={print format}{current}, + print form/.register=result, + }, + for first leaf'={TeX={\forestoption{print form}}}, + endgroup, + }{}, + } + }, + create@main@entry@node/.style={% #1 = subentry + set root={[]}, + do dynamics, for root'={process delayed=tree}, + root', + setup@entry@node={#1} + }, + create@subentry@node/.style={ + append={[]}, + do dynamics, for root'={process delayed=tree}, + n=1, + setup@entry@node={#1} + }, + setup@entry@node/.style={ + options={ + split={#1}{=}{key,argument}, + if n=0{ + name'/.option=key, + content={#1}, + }{ + name'/.wrap 2 pgfmath args={##1>##2}{name("!parent")}{key}, + content/.wrap pgfmath arg={##1>#1}{content("!parent")}, + }, + } + }, +} +\forestset{ + declare keylist register=set, + Autoforward register={set}{##1}, + save@session/.style={@@index/\forestoption{name}/.global style/.register=set}, + save@foridx/.style={ + if={strequal(name("!root"),"@unknown")}{}{ + if set={}{}{ + TeX={% + \immediate\write\forestindex@out{% + \string\indexloadsettings{\forestoption{name}}{\forestregister{set}}% + }% + }, + }, + if={strequal(key(),content())}{}{ + TeX={% + \immediate\write\forestindex@out{% + \string\indexdefineshortkey{\forestoption{key}}{\forestoption{content}}% + }% + } + } + } + }, +} +\def\indexloadsettings#1#2{% + \pgfkeysifdefined{/forest/@@index/#1/.@cmd}{% + \forestindex@loadsettings@warning{#1}% + }{}% + \forestset{@@index/#1/.global style={#2}}% +} +\def\forestindex@loadsettings@warning#1{% + \PackageWarning{forest-index}{Forest index key "#1" was configured more than once! + I'm using the last configuration.}% +} +\def\indexdefineshortkey#1#2{% + \def\forestindex@temp@short{#1}% + \def\forestindex@temp@long{#2}% + \ifx\forestindex@temp@short\forestindex@temp@long + \else + \ifcsdef{index@long@#1}{% + \global\cslet{index@long@#1}\relax + \csgappto{index@alllong@#1}{,#2}% + }{% + \global\csgdef{index@long@#1}{#2}% + \global\csgdef{index@alllong@#1}{#2}% + }% + \fi +} +\def\forestindex@resolvekey@long#1{\def\forestindex@fullkey{#1}} +\def\forestindex@resolvekey@shortorlong#1{% + \pgfutil@in@>{#1}% + \ifpgfutil@in@ + \expandafter\def\expandafter\forestindex@fullkey + \else + \expandafter\forestindex@resolvekey@short + \fi + {#1}% +} +\def\forestindex@resolvekey@short#1{% + \forestset{split={#1}{=}{index@resolveshortkey@key,index@resolveshortkey@arg}}% +} +\forestset{ + index@resolveshortkey@key/.code={% + \ifcsvoid{index@long@#1}{% + \forestindex@resolveshortkey@warning{#1}% + \def\forestindex@fullkey{@unknown>#1}% + }{% + \letcs\forestindex@fullkey{index@long@#1}% + }% + }, + index@resolveshortkey@arg/.code={% + \appto\forestindex@fullkey{=#1}% + }, +} +\def\forestindex@resolveshortkey@warning#1{% + \PackageWarning{forest-index}{Cannot resolve short forest index key "#1". + These are the definitions I found (from the previous run): + "\csuse{index@alllong@#1}"}% +} +\forestset{ + normal color/.initial=blue, + definition color/.initial=red, + example color/.initial=darkgreen, + print in color/.style={if stage={print}{result=\protect\textcolor{% + \pgfkeysvalueof{/forest/#1 color}}{##1}}{}}, + print in color/.default=\forestregister{index entry type}, + hyper/.style={ + if stage={index}{}{ + if index entry type={definition}{ + result/.expanded={\noexpand\hypertarget{\forestoption{name}}% + {\noexpand\hyperlink{\forestoption{index@hypertarget}}{\forestregister{result}}}} + }{ + result/.expanded=\noexpand\hyperlink{\forestoption{name}}{\forestregister{result}} + } + } + }, +} +\ifdef\hyperpage{% + \newcommand\indexpagenumbernormal[1]{{% + \hypersetup{linkcolor=\pgfkeysvalueof{/forest/normal color}}\hyperpage{#1}}} + \newcommand\indexpagenumberdefinition[1]{{% + \hypersetup{linkcolor=\pgfkeysvalueof{/forest/definition color}}\hyperpage{#1}}} + \newcommand\indexpagenumberexample[1]{{% + \hypersetup{linkcolor=\pgfkeysvalueof{/forest/example color}}\hyperpage{#1}}} +}{ + \newcommand\indexpagenumbernormal[1]{% + \textcolor{\pgfkeysvalueof{/forest/normal color}}{#1}} + \newcommand\indexpagenumberdefinition[1]{% + \textcolor{\pgfkeysvalueof{/forest/definition color}}{#1}} + \newcommand\indexpagenumberexample[1]{% + \textcolor{\pgfkeysvalueof{/forest/example color}}{#1}} +} +\providecommand\hyperlink[2]{#2} +\providecommand\hypertarget[2]{#2} +\providecommand\hypersetup[1]{} +\newcommand\hyperlinknocolor[2]{{\hypersetup{linkcolor=black}\hyperlink{#1}{#2}}} +\forestset{ + declare toks register=default, + default={}, + item/.style={result/.wrap 4 pgfmath args={% + \item[,##2,##3]{##4}% + }{}{default}{print_form("!parent")}{result}, + }, +} +\pgfkeys{/handlers/.global style/.code=\pgfkeys{\pgfkeyscurrentpath/.global code=\pgfkeysalso{#1}}} +\pgfkeysdef{/handlers/.global code}{\pgfkeysglobaldef{\pgfkeyscurrentpath}{#1}} +\long\def\pgfkeysglobaldef#1#2{% + \long\def\pgfkeys@temp##1\pgfeov{#2}% + \pgfkeysgloballet{#1/.@cmd}{\pgfkeys@temp}% + \pgfkeysglobalsetvalue{#1/.@body}{#2}% +} +\def\pgfkeysgloballet#1#2{% + \expandafter\global\expandafter\let\csname pgfk@#1\endcsname#2% +} +\long\def\pgfkeysglobalsetvalue#1#2{% + \pgfkeys@temptoks{#2}\expandafter\xdef\csname pgfk@#1\endcsname{\the\pgfkeys@temptoks}% +} +\forestset{ + begingroup/.code={\begingroup}, + endgroup/.code={\endgroup}, +} +\index(not print,not index)[% + set={ + index key=unknown, + form={\textbf{unknown!!}}, + for first={format={result/.expanded=\noexpand\textbf{\forestregister{result}??}}} + }, + ]>{@unknown} +\def\forestindex@filename{\jobname.foridx} +\IfFileExists{\forestindex@filename}{% + \input\forestindex@filename +}{}% +\newwrite\forestindex@out +\immediate\openout\forestindex@out=\forestindex@filename +\AtEndDocument{% + \immediate\closeout\forestindex@out +} +\endinput +%% +%% End of file `forest-index.sty'. diff --git a/Master/texmf-dist/tex/latex/forest/forest-lib-edges.sty b/Master/texmf-dist/tex/latex/forest/forest-lib-edges.sty new file mode 100644 index 00000000000..5c737aabfeb --- /dev/null +++ b/Master/texmf-dist/tex/latex/forest/forest-lib-edges.sty @@ -0,0 +1,74 @@ +%% +%% This is file `forest-lib-edges.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% forest-libs.dtx (with options: `edges') +%% +%% `forest-libs' is a collection of libraries for package `forest'. +%% +%% 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 file is a part of package `forest'. For the list of files +%% constituting the package see main source file of the package, +%% `forest.dtx', or the derived `forest.sty'. +%% +\RequirePackage{forest} +\ProvidesForestLibrary{edges}[2015/11/14 v0.1] +\forestset{ + declare dimen={fork sep}{0.5em}, + forked edge/.style={ + edge={rotate/.pgfmath=grow()}, + edge path'={(!u.parent anchor) -- ++(\forestoption{fork sep},0) |- (.child anchor)}, + }, + forked edges/.style={ + for tree={parent anchor=children}, + for descendants={child anchor=parent,forked edge} + }, +} +\forestset{ + declare dimen register=folder indent, + folder indent=.45em, + folder/.style={ + parent anchor=parent last, + anchor=parent first, + calign=child, + calign primary child=1, + for children={ + child anchor=parent, + anchor=parent first, + edge={rotate/.pgfmath=grow()}, + edge path'/.expanded={ + ([xshift=\forestregister{folder indent}]!u.parent anchor) |- (.child anchor) + }, + }, + after packing node={ + if n children=0{}{ + tempdiml=l_sep()-l("!1"), + tempdims={-abs(max_s("","")-min_s("",""))-s_sep()}, + for children={ + l+=tempdiml, + s+=tempdims()*(reversed()-0.5)*2, + }, + }, + }, + } +} +\endinput +%% +%% End of file `forest-lib-edges.sty'. diff --git a/Master/texmf-dist/tex/latex/forest/forest-lib-linguistics.sty b/Master/texmf-dist/tex/latex/forest/forest-lib-linguistics.sty new file mode 100644 index 00000000000..9632361e964 --- /dev/null +++ b/Master/texmf-dist/tex/latex/forest/forest-lib-linguistics.sty @@ -0,0 +1,133 @@ +%% +%% This is file `forest-lib-linguistics.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% forest-libs.dtx (with options: `linguistics') +%% +%% `forest-libs' is a collection of libraries for package `forest'. +%% +%% 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 file is a part of package `forest'. For the list of files +%% constituting the package see main source file of the package, +%% `forest.dtx', or the derived `forest.sty'. +%% +\RequirePackage{forest} +\ProvidesForestLibrary{linguistics}[2015/11/14 v0.1] +\forestset{ + libraries/linguistics/defaults/.style={ + default preamble={ + sn edges, + baseline, + for tree={align=center}, + }, + }, +} +\forestset{ + define long step={c-commanded}{style}{branch'={siblings,descendants}}, + define long step={c-commanders}{style}{while nodewalk valid={parent}{siblings,fake=parent}}, +} +\forestset{ + sn edges/.style={ + for tree={ + parent anchor=children, child anchor=parent + } + }, +} +\forestset{ + roof/.style={edge path'={% + (.parent first)--(!u.children)--(.parent last)--cycle + } + }, +} +\forestset{ + nice empty nodes/.style={ + for tree={calign=fixed edge angles}, + delay={where content={}{shape=coordinate,for parent={ + for children={anchor=north}}}{}} + }, +} +\providecommand\text[1]{\mbox{\scriptsize#1}} +\forestset{ + draw brackets compact/.code={\let\drawbracketsspace\relax}, + draw brackets wide/.code={\let\drawbracketsspace\space}, + draw brackets/.style={ + for tree'={ + TeX={[% + \edef\forestdrawbracketscontentformat{\foresteoption{content format}}% + }, + if n children=0{ + TeX={\drawbracketsspace\forestdrawbracketscontentformat\drawbracketsspace} + }{ + TeX={\textsubscript{\text{\forestdrawbracketscontentformat}}\drawbracketsspace} + }, + }{ + TeX={]\drawbracketsspace}, + } + }, + draw brackets wide +} +\newbox\standardnodestrutbox +\setbox\standardnodestrutbox=\hbox to 0pt{\phantom{\forestOve{standard node}{content}}} +\def\standardnodestrut{\copy\standardnodestrutbox} +\forestset{ + GP1/.style 2 args={ + for n={1}{baseline}, + s sep=0pt, l sep=0pt, + for descendants={ + l sep=0pt, l={#1}, + anchor=base,calign=first,child anchor=north, + inner xsep=1pt,inner ysep=2pt,outer sep=0pt,s sep=0pt, + }, + delay={ + if content={}{phantom}{for children={no edge}}, + for tree={ + if content={O}{tier=OR}{}, + if content={R}{tier=OR}{}, + if content={N}{tier=N}{}, + if content={x}{ + tier=x,content={$\times$},outer xsep={#2}, + for tree={calign=center}, + for descendants={content format={\noexpand\standardnodestrut\forestoption{content}}}, + before drawing tree={outer xsep=0pt,delay={typeset node}}, + s sep=4pt + }{}, + }, + }, + before drawing tree={where content={}{parent anchor=center,child anchor=center}{}}, + }, + GP1/.default={5ex}{8.0pt}, + associate/.style={% + tikz+={\draw[densely dotted](!)--(!#1);}}, + spread/.style={ + before drawing tree={tikz+={\draw[dotted](!)--(!#1);}}}, + govern/.style={ + before drawing tree={tikz+={\draw[->](!)--(!#1);}}}, + p-govern/.style={ + before drawing tree={tikz+={\draw[->](.north) to[out=150,in=30] (!#1.north);}}}, + no p-govern/.style={ + before drawing tree={tikz+={\draw[->,loosely dashed](.north) to[out=150,in=30] (!#1.north);}}}, + encircle/.style={before drawing tree={circle,draw,inner sep=0pt}}, + fen/.style={pin={[font=\footnotesize,inner sep=1pt,pin edge=<-]10:\textsc{Fen}}}, + el/.style={content=\textsc{\textbf{##1}}}, + head/.style={content=\textsc{\textbf{\underline{##1}}}} +} +\endinput +%% +%% End of file `forest-lib-linguistics.sty'. diff --git a/Master/texmf-dist/tex/latex/forest/forest.sty b/Master/texmf-dist/tex/latex/forest/forest.sty index bcba9acc8b8..6fdbb025c1b 100644 --- a/Master/texmf-dist/tex/latex/forest/forest.sty +++ b/Master/texmf-dist/tex/latex/forest/forest.sty @@ -22,16 +22,31 @@ %% and version 1.3 or later is part of all distributions of LaTeX %% version 2005/12/01 or later. %% -%% This work has the LPPL maintenance status `maintained'. +%% This work has the LPPL maintenance status `author-maintained'. %% -%% The Current Maintainer of this work is Saso Zivanovic. +%% 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. %% -%% This work consists of the files forest.dtx and forest.ins -%% and the derived file forest.sty. -%% -\ProvidesPackage{forest}[2015/07/15 v1.0.10 Drawing (linguistic) trees] +\ProvidesPackage{forest}[2015/01/30 v2.0.0 Drawing (linguistic) trees] -\RequirePackage{tikz}[2010/10/13] +\RequirePackage{tikz}[2013/12/13] \usetikzlibrary{shapes} \usetikzlibrary{fit} \usetikzlibrary{calc} @@ -41,255 +56,65 @@ \RequirePackage{etoolbox}[2010/08/21] \RequirePackage{elocalloc}% for \locbox \RequirePackage{environ} +\RequirePackage{xparse} + - %\usepackage[trace]{trace-pgfkeys} \pgfkeys{/forest/.is family} \def\forestset#1{\pgfqkeys{/forest}{#1}} -\long\def\forest@original@pgfkeysdefnargs@#1#2#3#4{% - \ifcase#2\relax - \pgfkeyssetvalue{#1/.@args}{}% - \or - \pgfkeyssetvalue{#1/.@args}{##1}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% - \else - \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% - \fi - \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs - \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% - \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% - % eliminate the \pgfeov at the end such that TeX gobbles spaces - % by using - % \pgfkeysdef{#1}{\pgfkeysvalueof{#1/.@@body}##1} - % (with expansion of '#1'): - \edef\pgfkeys@tempargs{\noexpand\pgfkeysvalueof{#1/.@@body}}% - \def\pgfkeys@temp{\pgfkeysdef{#1}}% - \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs##1}% - \pgfkeyssetvalue{#1/.@body}{#3}% +\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}% + }% + }, } - -\long\def\forest@patched@pgfkeysdefnargs@#1#2#3#4{% - \ifcase#2\relax - \pgfkeyssetvalue{#1/.@args}{}% - \or - \pgfkeyssetvalue{#1/.@args}{##1}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% - %%%%% removed: - %%%%% \or - %%%%% \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% - \else - \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% - \fi - \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs - \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% - \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% - % eliminate the \pgfeov at the end such that TeX gobbles spaces - % by using - % \pgfkeysdef{#1}{\pgfkeysvalueof{#1/.@@body}##1} - % (with expansion of '#1'): - \edef\pgfkeys@tempargs{\noexpand\pgfkeysvalueof{#1/.@@body}}% - \def\pgfkeys@temp{\pgfkeysdef{#1}}% - \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs##1}% - \pgfkeyssetvalue{#1/.@body}{#3}% -} -\ifx\pgfkeysdefnargs@\forest@original@pgfkeysdefnargs@ - \let\pgfkeysdefnargs@\forest@patched@pgfkeysdefnargs@ -\fi -\def\forest@original@pgfpointintersectionoflines#1#2#3#4{% - { - % - % Compute orthogonal vector to #1--#2 - % - \pgf@process{#2}% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% - \pgf@process{#1}% - \advance\pgf@xa by-\pgf@x% - \advance\pgf@ya by-\pgf@y% - \pgf@ya=-\pgf@ya% - % Normalise a bit - \c@pgf@counta=\pgf@xa% - \ifnum\c@pgf@counta<0\relax% - \c@pgf@counta=-\c@pgf@counta\relax% - \fi% - \c@pgf@countb=\pgf@ya% - \ifnum\c@pgf@countb<0\relax% - \c@pgf@countb=-\c@pgf@countb\relax% - \fi% - \advance\c@pgf@counta by\c@pgf@countb\relax% - \divide\c@pgf@counta by 65536\relax% - \ifnum\c@pgf@counta>0\relax% - \divide\pgf@xa by\c@pgf@counta\relax% - \divide\pgf@ya by\c@pgf@counta\relax% - \fi% - % - % Compute projection - % - \pgf@xc=\pgf@sys@tonumber{\pgf@ya}\pgf@x% - \advance\pgf@xc by\pgf@sys@tonumber{\pgf@xa}\pgf@y% - % - % The orthogonal vector is (\pgf@ya,\pgf@xa) - % - % - % Compute orthogonal vector to #3--#4 - % - \pgf@process{#4}% - \pgf@xb=\pgf@x% - \pgf@yb=\pgf@y% - \pgf@process{#3}% - \advance\pgf@xb by-\pgf@x% - \advance\pgf@yb by-\pgf@y% - \pgf@yb=-\pgf@yb% - % Normalise a bit - \c@pgf@counta=\pgf@xb% - \ifnum\c@pgf@counta<0\relax% - \c@pgf@counta=-\c@pgf@counta\relax% - \fi% - \c@pgf@countb=\pgf@yb% - \ifnum\c@pgf@countb<0\relax% - \c@pgf@countb=-\c@pgf@countb\relax% - \fi% - \advance\c@pgf@counta by\c@pgf@countb\relax% - \divide\c@pgf@counta by 65536\relax% - \ifnum\c@pgf@counta>0\relax% - \divide\pgf@xb by\c@pgf@counta\relax% - \divide\pgf@yb by\c@pgf@counta\relax% - \fi% - % - % Compute projection - % - \pgf@yc=\pgf@sys@tonumber{\pgf@yb}\pgf@x% - \advance\pgf@yc by\pgf@sys@tonumber{\pgf@xb}\pgf@y% - % - % The orthogonal vector is (\pgf@yb,\pgf@xb) - % - % Setup transformation matrx (this is just to use the matrix - % inversion) - % - \pgfsettransform{{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{0pt}{0pt}}% - \pgftransforminvert% - \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xc}{\pgf@yc}}}% +\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}% + }% }% } -\def\forest@patched@pgfpointintersectionoflines#1#2#3#4{% - {% added the percent sign in this line - % - % Compute orthogonal vector to #1--#2 - % - \pgf@process{#2}% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% - \pgf@process{#1}% - \advance\pgf@xa by-\pgf@x% - \advance\pgf@ya by-\pgf@y% - \pgf@ya=-\pgf@ya% - % Normalise a bit - \c@pgf@counta=\pgf@xa% - \ifnum\c@pgf@counta<0\relax% - \c@pgf@counta=-\c@pgf@counta\relax% - \fi% - \c@pgf@countb=\pgf@ya% - \ifnum\c@pgf@countb<0\relax% - \c@pgf@countb=-\c@pgf@countb\relax% - \fi% - \advance\c@pgf@counta by\c@pgf@countb\relax% - \divide\c@pgf@counta by 65536\relax% - \ifnum\c@pgf@counta>0\relax% - \divide\pgf@xa by\c@pgf@counta\relax% - \divide\pgf@ya by\c@pgf@counta\relax% - \fi% - % - % Compute projection - % - \pgf@xc=\pgf@sys@tonumber{\pgf@ya}\pgf@x% - \advance\pgf@xc by\pgf@sys@tonumber{\pgf@xa}\pgf@y% - % - % The orthogonal vector is (\pgf@ya,\pgf@xa) - % - % - % Compute orthogonal vector to #3--#4 - % - \pgf@process{#4}% - \pgf@xb=\pgf@x% - \pgf@yb=\pgf@y% - \pgf@process{#3}% - \advance\pgf@xb by-\pgf@x% - \advance\pgf@yb by-\pgf@y% - \pgf@yb=-\pgf@yb% - % Normalise a bit - \c@pgf@counta=\pgf@xb% - \ifnum\c@pgf@counta<0\relax% - \c@pgf@counta=-\c@pgf@counta\relax% - \fi% - \c@pgf@countb=\pgf@yb% - \ifnum\c@pgf@countb<0\relax% - \c@pgf@countb=-\c@pgf@countb\relax% - \fi% - \advance\c@pgf@counta by\c@pgf@countb\relax% - \divide\c@pgf@counta by 65536\relax% - \ifnum\c@pgf@counta>0\relax% - \divide\pgf@xb by\c@pgf@counta\relax% - \divide\pgf@yb by\c@pgf@counta\relax% - \fi% - % - % Compute projection - % - \pgf@yc=\pgf@sys@tonumber{\pgf@yb}\pgf@x% - \advance\pgf@yc by\pgf@sys@tonumber{\pgf@xb}\pgf@y% - % - % The orthogonal vector is (\pgf@yb,\pgf@xb) - % - % Setup transformation matrx (this is just to use the matrix - % inversion) - % - \pgfsettransform{{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@yb}{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@xb}{0pt}{0pt}}% - \pgftransforminvert% - \pgf@process{\pgfpointtransformed{\pgfpoint{\pgf@xc}{\pgf@yc}}}% - }% +\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}}% } - -\ifx\pgfpointintersectionoflines\forest@original@pgfpointintersectionoflines - \let\pgfpointintersectionoflines\forest@patched@pgfpointintersectionoflines -\fi - - % hah: hacking forest --- it depends on some details of PGF implementation -\def\forest@pgf@notyetpositioned{not yet positionedPGFINTERNAL}% -\expandafter\ifstrequal\expandafter{\pgfversion}{2.10}{% - \def\forest@pgf@notyetpositioned{not yet positioned@}% -}{} \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 @@ -309,17 +134,66 @@ }% }% }% +\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 -\newloop\forest@loopa -\newloop\forest@loopb -\newloop\forest@loopc -\newloop\forest@sort@loop -\newloop\forest@sort@loopA \newdimen\forest@temp@dimen \newcount\forest@temp@count \newcount\forest@n \newif\ifforest@temp \newcount\forest@temp@global@count +\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}} @@ -415,6 +289,153 @@ \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 @@ -450,6 +471,8 @@ 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 @@ -493,10 +516,11 @@ }% \forest@sort@marshal } +\def\forest@sort@aux{aux} \def\forest@sort@xch#1#2{% - \forest@sort@let{aux}{#1}% + \forest@sort@let{\forest@sort@aux}{#1}% \forest@sort@let{#1}{#2}% - \forest@sort@let{#2}{aux}% + \forest@sort@let{#2}{\forest@sort@aux}% } \def\forest@insertionsort#1#2{% \forest@sort@m=#1 @@ -509,7 +533,7 @@ } \newif\ifforest@insertionsort@loop \def\forest@insertionsort@Qbody{% - \forest@sort@let{aux}{\the\forest@sort@m}% + \forest@sort@let{\forest@sort@aux}{\the\forest@sort@m}% \forest@sort@k\forest@sort@m \advance\forest@sort@k -1 \forest@insertionsort@looptrue @@ -518,10 +542,10 @@ \forest@insertionsort@qbody \forest@sort@repeat \advance\forest@sort@k 1 - \forest@sort@let{\the\forest@sort@k}{aux}% + \forest@sort@let{\the\forest@sort@k}{\forest@sort@aux}% } \def\forest@insertionsort@qbody{% - \forest@sort@cmp{\the\forest@sort@k}{aux}% + \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 @@ -580,12 +604,12 @@ \c@pgf@countc=#2 \c@pgf@countd=#3 \advance\c@pgf@countd -1 - \forest@loopa + \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 - \forest@repeata + \saferepeat } \def\bracketset#1{\pgfqkeys{/bracket}{#1}}% \bracketset{% @@ -599,9 +623,9 @@ action character, new node/.code n args={3}{% #1=preamble, #2=node spec, #3=cs receiving the id \forest@node@new#3% - \forestOset{#3}{given options}{content'=#2}% + \forestOeset{#3}{given options}{\forest@contentto=\unexpanded{#2}}% \ifblank{#1}{}{% - \forestOpreto{#3}{given options}{#1,}% + \forestrset{preamble}{#1}% }% }, set afterthought/.code 2 args={% #1=node id, #2=afterthought @@ -837,9 +861,14 @@ % 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\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{% @@ -862,6 +891,11 @@ \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{% @@ -895,6 +929,37 @@ \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 @@ -919,7 +984,7 @@ \let\forestoinit@orig\forestoinit \def\forest@node@copy#1#2{% #1=from node id, cs receiving the new node id \advance\forest@node@maxid1 - \def\forestoinit##1{\forestoletO{##1}{#1}{##1}}% + \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}}}% @@ -1039,13 +1104,6 @@ \edef\forest@node@marshal{\edef\noexpand\forest@cn{#1}\unexpanded{#2}\def\noexpand\forest@cn}% \expandafter\forest@node@marshal\expandafter{\forest@cn}% } -\def\forest@fornode@ifexists#1#2{% - \edef\forest@node@temp{#1}% - \ifnum\forest@node@temp=0 - \else - \@escapeif{\expandnumberarg\forest@fornode{\forest@node@temp}{#2}}% - \fi -} \def\forest@node@foreachchild#1{\forest@node@Foreachchild{\forest@cn}{#1}} \def\forest@node@Foreachchild#1#2{% \forest@fornode{\forestOve{#1}{@first}}{\forest@node@@forselfandfollowingsiblings{#2}}% @@ -1060,30 +1118,176 @@ }% \fi } -\def\forest@node@foreach#1{\forest@node@Foreach{\forest@cn}{#1}} -\def\forest@node@Foreach#1#2{% - \forest@fornode{#1}{\forest@node@@foreach{#2}}% +\def\forest@node@@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@@foreach#1{% - \forest@forthis{#1}% - \ifnum\forestove{@first}=0 - \else\@escapeif{% - \edef\forest@cn{\forestove{@first}}% - \forest@node@@forselfandfollowingsiblings{\forest@node@@foreach{#1}}% +\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@foreachdescendant#1{\forest@node@Foreachdescendant{\forest@cn}{#1}} +\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}% + \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 - \fornode{#1}{\forest@node@@compute@numeric@ts@info@nbar}% + \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}% } @@ -1226,6 +1430,7 @@ \@escapeif{\expandnumberarg\forest@node@nextleafid@Godown{\forestOve{#1}{@first}}}% \fi } + \def\forest@node@linearnextid{% \ifnum\forestove{@first}=0 \expandafter\forest@node@linearnextnotdescendantid @@ -1238,11 +1443,16 @@ } \def\forest@node@Linearnextnotdescendantid#1{% \ifnum\forestOve{#1}{@next}=0 - \@escapeif{\expandnumberarg\forest@node@Linearnextnotdescendantid{\forestOve{#1}{@parent}}}% + \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}% @@ -1265,201 +1475,10 @@ \fi \forest@ifancestorof@next{#2}{#3}% } -\newloop\forest@nodewalk@loop -\forestset{ - @handlers@save@currentpath/.code={% - \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% - \let\forest@currentkey\pgfkeyscurrentkey - \pgfkeys@split@path - \edef\forest@currentpath{\pgfkeyscurrentpath}% - \let\forest@currentname\pgfkeyscurrentname - }, - /handlers/.step 0 args/.style={ - /forest/@handlers@save@currentpath, - \forest@currentkey/.code={#1\forestset{node walk/every step}}, - /forest/for \forest@currentname/.style/.expanded={% - for={\forest@currentname}{####1}% - } - }, - /handlers/.step 1 arg/.style={% - /forest/@handlers@save@currentpath, - \forest@currentkey/.code={#1\forestset{node walk/every step}}, - /forest/for \forest@currentname/.style 2 args/.expanded={% - for={\forest@currentname=####1}{####2}% - } - }, - node walk/.code={% - \forestset{% - node walk/before walk,% - node walk/.cd, - #1,% - /forest/.cd, - node walk/after walk - }% - }, - for/.code 2 args={% - \forest@forthis{% - \pgfkeysalso{% - node walk/before walk/.style={},% - node walk/every step/.style={},% - node walk/after walk/.style={/forest,if id=0{}{#2}},% - %node walk/after walk/.style={#2},% - node walk={#1}% - }% - }% - }, - node walk/.cd, - before walk/.code={}, - every step/.code={}, - after walk/.code={}, - current/.step 0 args={}, - current/.default=1, - next/.step 0 args={\edef\forest@cn{\forestove{@next}}}, - next/.default=1, - previous/.step 0 args={\edef\forest@cn{\forestove{@previous}}}, - previous/.default=1, - parent/.step 0 args={\edef\forest@cn{\forestove{@parent}}}, - parent/.default=1, - first/.step 0 args={\edef\forest@cn{\forestove{@first}}}, - first/.default=1, - last/.step 0 args={\edef\forest@cn{\forestove{@last}}}, - last/.default=1, - n/.step 1 arg={% - \def\forest@nodewalk@temp{#1}% - \ifx\forest@nodewalk@temp\pgfkeysnovalue@text - \edef\forest@cn{\forestove{@next}}% - \else - \edef\forest@cn{\forest@node@nthchildid{#1}}% - \fi - }, - n'/.step 1 arg={\edef\forest@cn{\forest@node@nbarthchildid{#1}}}, - sibling/.step 0 args={% - \edef\forest@cn{% - \ifnum\forestove{@previous}=0 - \forestove{@next}% - \else - \forestove{@previous}% - \fi - }% - }, - previous leaf/.step 0 args={\edef\forest@cn{\forest@node@previousleafid}}, - previous leaf/.default=1, - next leaf/.step 0 args={\edef\forest@cn{\forest@node@nextleafid}}, - next leaf/.default=1, - linear next/.step 0 args={\edef\forest@cn{\forest@node@linearnextid}}, - linear previous/.step 0 args={\edef\forest@cn{\forest@node@linearpreviousid}}, - first leaf/.step 0 args={% - \forest@nodewalk@loop - \edef\forest@cn{\forestove{@first}}% - \unless\ifnum\forestove{@first}=0 - \forest@nodewalk@repeat - }, - last leaf/.step 0 args={% - \forest@nodewalk@loop - \edef\forest@cn{\forestove{@last}}% - \unless\ifnum\forestove{@last}=0 - \forest@nodewalk@repeat - }, - to tier/.step 1 arg={% - \def\forest@nodewalk@giventier{#1}% - \forest@nodewalk@loop - \forestoget{tier}\forest@nodewalk@tier - \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier - \forestoget{@parent}\forest@cn - \forest@nodewalk@repeat - }, - next on tier/.step 0 args={\forest@nodewalk@nextontier}, - next on tier/.default=1, - previous on tier/.step 0 args={\forest@nodewalk@previousontier}, - previous on tier/.default=1, - name/.step 1 arg={\edef\forest@cn{\forest@node@Nametoid{#1}}}, - root/.step 0 args={\edef\forest@cn{\forest@node@rootid}}, - root'/.step 0 args={\edef\forest@cn{\forest@root}}, - id/.step 1 arg={\edef\forest@cn{#1}}, - % maybe it's not wise to have short-step sequences and names potentially clashing - % .unknown/.code={% - % \forest@node@Ifnamedefined{\pgfkeyscurrentname}% - % {\pgfkeysalso{name=\pgfkeyscurrentname}}% - % {\expandafter\forest@nodewalk@shortsteps\pgfkeyscurrentname\forest@nodewalk@endshortsteps}% - % }, - .unknown/.code={% - \expandafter\forest@nodewalk@shortsteps\pgfkeyscurrentname\forest@nodewalk@endshortsteps - }, - node walk/.style={/forest/node walk={#1}}, - trip/.code={\forest@forthis{\pgfkeysalso{#1}}}, - group/.code={\forest@go{#1}\forestset{node walk/every step}}, - % repeat is taken later from /forest/repeat - p/.style={previous=1}, - %n/.style={next=1}, % defined in "long" n - u/.style={parent=1}, - s/.style={sibling}, - c/.style={current=1}, - r/.style={root}, - P/.style={previous leaf=1}, - N/.style={next leaf=1}, - F/.style={first leaf=1}, - L/.style={last leaf=1}, - >/.style={next on tier=1}, - 0 - \advance\forest@temp@count-1 - \csedef{forest@repeat@key@\the\forest@repeat@key@depth}{\the\forest@temp@count}% - \pgfkeysalso{#2}% + \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}% }% - \expandafter\forest@marshal\csname forest@repeat@key@repeat@\the\forest@repeat@key@depth\endcsname - \advance\forest@repeat@key@depth-1 }, -} -\pgfkeysgetvalue{/forest/repeat/.@cmd}\forest@temp -\pgfkeyslet{/forest/node walk/repeat/.@cmd}\forest@temp -\pgfmathdeclarefunction{strequal}{2}{% - \ifstrequal{#1}{#2}{\def\pgfmathresult{1}}{\def\pgfmathresult{0}}% -} -\pgfmathdeclarefunction{instr}{2}{% - \pgfutil@in@{#1}{#2}% - \ifpgfutil@in@\def\pgfmathresult{1}\else\def\pgfmathresult{0}\fi -} + 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}% - \forestoget{#2}\pgfmathresult + \ifnum\forest@cn=0 + \def\pgfmathresult{}% + \else + \forestoget{#2}\pgfmathresult + \fi }% } \def\forest@pgfmathhelper@attribute@dimen#1#2{% \forest@forthis{% \forest@nameandgo{#1}% - \forestoget{#2}\forest@temp - \pgfmathparse{+\forest@temp}% + \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}% - \forestoget{#2}\forest@temp - \pgfmathtruncatemacro\pgfmathresult{\forest@temp}% + \ifnum\forest@cn=0 + \def\pgfmathresult{0}% + \else + \forestoget{#2}\forest@temp + \pgfmathtruncatemacro\pgfmathresult{\forest@temp}% + \fi }% } \pgfmathdeclarefunction{id}{1}{% @@ -2113,8 +2973,1123 @@ \pgfkeysalso{#3}% \fi }, - where id/.style n args={3}{for tree={if id={#1}{#2}{#3}}} -} + 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% @@ -2129,6 +4104,9 @@ \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 @@ -2137,17 +4115,48 @@ \bracketParse{\forest@create@collectafterthought}% \forest@last@node=#1\forest@end@create@node } -\def\forest@create@collectafterthought#1\forest@end@create@node{% - \forestOletO{\forest@last@node}{delay}{\forest@last@node}{given options}% - \forestOset{\forest@last@node}{given options}{}% - \forestOeappto{\forest@last@node}{delay}{,\unexpanded{#1}}% -} \def\forest@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}% @@ -2168,6 +4177,9 @@ \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 @@ -2179,14 +4191,20 @@ \forestOepreto{\forest@last@node}{delay} {for id={\forest@node@Nametoid{forest@last@node}}{alias=forest@last@node},}% }{}% - \forest@havedelayedoptionstrue \edef\forest@marshal{% \noexpand\apptotoks\noexpand\forest@do@dynamics{% \noexpand#1{\forest@cn}{\forest@last@node}}% }\forest@marshal } \forestset{% - create/.code={\forest@create@node{#1}}, + 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}}, @@ -2205,16 +4223,29 @@ \expandafter\forest@remove@node\expandafter{\forest@cn}}% }, set root/.code={% - \forest@nodehandleby@name@nodewalk@or@bracket{#1}% - \edef\forest@marshal{% - \noexpand\apptotoks\noexpand\forest@do@dynamics{% - \def\noexpand\forest@root{\forest@last@node}% - }% - }\forest@marshal + \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 @@ -2228,8 +4259,70 @@ }% \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, @@ -2237,33 +4330,68 @@ process keylist=before computing xy, compute xy stage, process keylist=before drawing tree, - draw tree stage, + 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}, - process keylist/.code={\forest@process@hook@keylist{#1}}, +} + %%% 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/.append code={\forest@havedelayedoptionstrue}, 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/.code 2 args={% - \ifforest@havedelayedoptions\pgfkeysalso{#1}\else\pgfkeysalso{#2}\fi + 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@node@foreach{\forest@node@typeset}}, + \forest@nodewalk + {typeset nodes processing order/.try,processing order/.lastretry}% + {TeX={\forest@node@typeset}}% + }, typeset nodes'/.code={% \forest@drawtree@preservenodeboxes@true - \forest@node@foreach{\forest@node@typeset}}, + \forest@nodewalk + {typeset nodes processing order/.try,processing order/.lastretry}% + {TeX={\forest@node@typeset}}% + }, typeset node/.code={% \forest@drawtree@preservenodeboxes@false \forest@node@typeset @@ -2281,45 +4409,101 @@ \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{% - \forest@loopa - \forest@havedelayedoptionsfalse - \forest@do@dynamics={}% - \forest@fornode{\forest@root}{\forest@process@hook@keylist@{#1}}% +\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@havedelayedoptionstrue }% + \forest@fornode{\forest@root}{\forest@havedelayedoptions{#1}{#2}}% \ifforest@havedelayedoptions - \forest@node@Foreach{\forest@root}{% - \forestoget{delay}\forest@temp@delayed - \forestolet{#1}\forest@temp@delayed - \forestoset{delay}{}% + \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}% + }% }% - \forest@repeata + }% } -\def\forest@process@hook@keylist@#1{% - \forest@node@foreach{% - \forestoget{#1}\forest@temp@keys - \ifdefvoid\forest@temp@keys{}{% - \forestoset{#1}{}% - \expandafter\forestset\expandafter{\forest@temp@keys}% +\def\forest@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}{% - \ifforest@drawtree@preservenodeboxes@ - \let\forest@next\relax - \fi + \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 + \forestolet{@box}\forest@temp@box }% \def\forest@node@typeset@restore{}% \ifdefined\ifsa@tikz\forest@standalone@hack\fi @@ -2339,52 +4523,38 @@ \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}% + \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 - %\forest@compute@node@boundary\forest@temp - %\xappto\forest@smuggle{\noexpand\forestoset{boundary}{\expandonce\forest@temp}}% - \if\relax\forestove{parent anchor}\relax - \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{center}% - \else - \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{\forestove{parent anchor}}% - \fi - \xappto\forest@smuggle{% - \noexpand\forestoset{parent@anchor}{% - \noexpand\noexpand\noexpand\pgf@x=\the\pgf@x\relax - \noexpand\noexpand\noexpand\pgf@y=\the\pgf@y\relax}}% - \if\relax\forestove{child anchor}\relax - \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{center}% - \else - \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{\forestove{child anchor}}% - \fi - \xappto\forest@smuggle{% - \noexpand\forestoeset{child@anchor}{% - \noexpand\noexpand\noexpand\pgf@x=\the\pgf@x\relax - \noexpand\noexpand\noexpand\pgf@y=\the\pgf@y\relax}}% - \if\relax\forestove{anchor}\relax - \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{center}% - \else - \pgfpointanchor{\forest@pgf@notyetpositioned\forest@nodename}{\forestove{anchor}}% - \fi - \xappto\forest@smuggle{% - \noexpand\forestoeset{@anchor}{% - \noexpand\noexpand\noexpand\pgf@x=\the\pgf@x\relax - \noexpand\noexpand\noexpand\pgf@y=\the\pgf@y\relax}}% \end{tikzpicture}% }% - \setbox\forestove{box}=\box\forest@box % smuggle the box - \forestolet{boundary}\forest@global@boundary + \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}, @@ -2417,13 +4587,17 @@ \else \let\forest@boxorcopy\box \fi - \forestoget{box}\forest@temp + \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 @@ -2432,24 +4606,28 @@ } \def\forest@@pack{% \ifnum\forestove{n children}>0 - \ifnum\forestove{uniform growth}>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@pack@sibling@uniform@applyreversed + \forest@pack@level@nonuniform + \forest@pack@aligntiers + \forest@node@foreachchild{\forestoset{s}{0pt}}% + \forest@pack@sibling@uniform@applyreversed \fi } \def\forest@pack@computegrowthuniformity{% @@ -2470,7 +4648,13 @@ \fi \fi }% - \forestolet{uniform growth}\forest@pack@cgu@uniformity + \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 @@ -2571,9 +4755,9 @@ \def\forest@pack@sibling@uniform@applyreversed{% \ifnum\forestove{n children}>1 \ifnum\forestove{reversed}=0 - \pack@sibling@uniform@main{first}{last}{next}{previous}% + \forest@pack@sibling@uniform@main{first}{last}{next}{previous}% \else - \pack@sibling@uniform@main{last}{first}{previous}{next}% + \forest@pack@sibling@uniform@main{last}{first}{previous}{next}% \fi \else \ifnum\forestove{n children}=1 @@ -2581,28 +4765,28 @@ \fi \fi } -\def\pack@sibling@uniform@main#1#2#3#4{% +\def\forest@pack@sibling@uniform@main#1#2#3#4{% \forestoget{@#1}\forest@child - \edef\forest@temp{% + \edef\forest@marshal{% \noexpand\forest@fornode{\forestove{@#1}}{% \noexpand\forest@node@getedge - {positive} - {\forestove{grow}} + {positive}% + {\forestove{grow}}% \noexpand\forest@temp@edge }% - }\forest@temp + }\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}% - \forest@loopb + \safeloop \unless\ifnum\forest@child=0 \edef\forest@temp{% \noexpand\forest@fornode{\forest@child}{% \noexpand\forest@node@getedge - {negative} - {\forestove{grow}} + {negative}% + {\forestove{grow}}% \noexpand\forest@temp@edge }% }\forest@temp @@ -2616,7 +4800,7 @@ \else \advance\pgfutil@tempdimb-\forest@csdistance\relax \advance\pgfutil@tempdimb\forestove{s sep}\relax - \forestOeset{\forest@child}{s}{\the\dimexpr\forestove{s}-\forest@csdistance+\forestove{s sep}}% + \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}% @@ -2626,8 +4810,8 @@ \edef\forest@temp{% \noexpand\forest@fornode{\forest@child}{% \noexpand\forest@node@getedge - {positive} - {\forestove{grow}} + {positive}% + {\forestove{grow}}% \noexpand\forest@temp@edge }% }\forest@temp @@ -2635,7 +4819,7 @@ \forest@extendpath\forest@previous@positive@edge\forest@temp@edge{}% \forest@getpositivetightedgeofpath\forest@previous@positive@edge\forest@previous@positive@edge \forestOget{\forest@child}{@#3}\forest@child - \forest@repeatb + \saferepeat \csname forest@calign@\forestove{calign}\endcsname } \def\forest@pack@pgfpoint@childsposition#1{% @@ -2670,9 +4854,9 @@ \pgftransformrotate{\forestove{grow}}% \pgfpointtransformed{\pgfqpoint{\forestOve{\forest@temp@child}{l}}{\forestOve{\forest@temp@child}{s}}}% \pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax - \forestOve{\forest@temp@child}{child@anchor}% + \forest@Pointanchor{\forest@temp@child}{child anchor}% \advance\pgf@xa\pgf@x\relax\advance\pgf@ya\pgf@y\relax - \forestove{parent@anchor}% + \forest@pointanchor{parent anchor}% \advance\pgf@xa-\pgf@x\relax\advance\pgf@ya-\pgf@y\relax \edef\forest@marshal{% \noexpand\pgftransformreset @@ -2697,13 +4881,13 @@ \pgftransformrotate{\forestove{grow}}% \pgfpointtransformed{\pgfqpoint{\forestOve{\forest@temp@firstchild}{l}}{\forestOve{\forest@temp@firstchild}{s}}}% \pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax - \forestOve{\forest@temp@firstchild}{child@anchor}% + \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 - \forestOve{\forest@temp@secondchild}{child@anchor}% + \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{% @@ -2779,16 +4963,13 @@ \fi \forestOget{\forest@ca@first@child}{l}\forest@ca@first@l \forestOget{\forest@ca@second@child}{l}\forest@ca@second@l - \forestoget{parent@anchor}\forest@ca@parent@anchor - \forest@ca@parent@anchor + \forest@pointanchor{parent anchor}% \edef\forest@ca@parent@anchor@s{\the\pgf@x}% \edef\forest@ca@parent@anchor@l{\the\pgf@y}% - \forestOget{\forest@ca@first@child}{child@anchor}\forest@ca@first@child@anchor - \forest@ca@first@child@anchor + \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}% - \forestOget{\forest@ca@second@child}{child@anchor}\forest@ca@second@child@anchor - \forest@ca@second@child@anchor + \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})*% @@ -2805,8 +4986,7 @@ \ifdim\forest@ca@actual@s@distance=0pt \forestoget{n children}\forest@temp@n@children \forest@node@foreachchild{% - \forestoget{child@anchor}\forest@temp@child@anchor - \forest@temp@child@anchor + \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}% @@ -2817,8 +4997,7 @@ \pgfmathsetmacro\forest@ca@ratio{% \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}% \forest@node@foreachchild{% - \forestoget{child@anchor}\forest@temp@child@anchor - \forest@temp@child@anchor + \forest@pointanchor{child anchor}% \edef\forest@temp@child@anchor@s{\the\pgf@x}% \pgfmathsetlengthmacro\forest@temp{% \forest@ca@ratio*(% @@ -2838,8 +5017,7 @@ \pgfmathsetlengthmacro\forest@ca@ratio{% \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}% \forest@node@foreachchild{% - \forestoget{child@anchor}\forest@temp@child@anchor - \forest@temp@child@anchor + \forest@pointanchor{child anchor}% \edef\forest@temp@child@anchor@l{\the\pgf@y}% \pgfmathsetlengthmacro\forest@temp{% \forest@ca@ratio*(% @@ -2871,7 +5049,7 @@ %{% \forest@setupgrowline{#1}% \ifnum\forestove{ignore}=0 - \forestoget{boundary}\forest@node@boundary + \forestoget{@boundary}\forest@node@boundary \else \def\forest@node@boundary{}% \fi @@ -2886,10 +5064,11 @@ \def\get@edges@merge#1#2{% \ifnum\forestove{n children}>0 \forestoget{#1@edge@#2}\forest@node@edge - \forestove{parent@anchor}% + \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{}% @@ -2900,7 +5079,7 @@ \ifnum\forestove{ignore edge}=0 \pgfpointadd {\pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}}% - {\forestove{child@anchor}}% + {\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}% @@ -2916,23 +5095,23 @@ \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 } -\newloop\forest@merge@loop \def\forest@merge@intersectionloop{% \c@pgf@counta=0 - \forest@merge@loop + \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@merge@repeat + \forest@repeat } \def\forest@node@getboundingrectangle@ls#1{% - \forestoget{boundary}\forest@node@boundary + \forestoget{@boundary}\forest@node@boundary \forest@path@getboundingrectangle@ls\forest@node@boundary{#1}% } \def\forest@pgfpathtransformed#1{% @@ -3079,7 +5258,7 @@ \def\forest@pack@tiers@computeprocessingorder{% \def\forest@tiers@processingorder{}% \forestoget{tiers}\forest@tiers@cpo@tierstodo - \forest@loopa + \safeloop \ifdefempty\forest@tiers@cpo@tierstodo{\forest@tempfalse}{\forest@temptrue}% \ifforest@temp \def\forest@tiers@cpo@tiersremaining{}% @@ -3089,7 +5268,7 @@ \PackageError{forest}{Circular tiers!}{}}{}% \forlistloop\forest@pack@tiers@cpo@forhandlerB\forest@tiers@cpo@tiersremaining \let\forest@tiers@cpo@tierstodo\forest@tiers@cpo@tiersremaining - \forest@repeata + \saferepeat } \def\forest@pack@tiers@cpo@forhandlerA#1{% \ifcsempty{forest@tiers@higher@#1}{% @@ -3170,7 +5349,7 @@ '\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.}{} + alignment.}% } \pgfdeclaregenericanchor{forestcomputenodeboundary}{% \letcs\forest@temp@boundary@macro{forest@compute@node@boundary@#1}% @@ -3237,26 +5416,25 @@ \forest@lt{arc end}% \forest@lt{arc start}% } -\newloop\forest@computenodeboundary@loop \csdef{forest@compute@node@boundary@regular polygon}{% \forest@mt{corner 1}% \c@pgf@counta=\sides\relax - \forest@computenodeboundary@loop + \forest@loop \ifnum\c@pgf@counta>0 \forest@lt{corner \the\c@pgf@counta}% \advance\c@pgf@counta-1 - \forest@computenodeboundary@repeat + \forest@repeat }% \def\forest@compute@node@boundary@star{% \forest@mt{outer point 1}% \c@pgf@counta=\totalstarpoints\relax \divide\c@pgf@counta2 - \forest@computenodeboundary@loop + \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@computenodeboundary@repeat + \forest@repeat }% \csdef{forest@compute@node@boundary@isosceles triangle}{% \forest@mt{apex}% @@ -3300,23 +5478,23 @@ \getradii \forest@mt{puff 1}% \c@pgf@counta=\puffs\relax - \forest@computenodeboundary@loop + \forest@loop \ifnum\c@pgf@counta>0 \forest@lt{puff \the\c@pgf@counta}% \advance\c@pgf@counta-1 - \forest@computenodeboundary@repeat + \forest@repeat } \def\forest@compute@node@boundary@starburst{ \calculatestarburstpoints \forest@mt{outer point 1}% \c@pgf@counta=\totalpoints\relax \divide\c@pgf@counta2 - \forest@computenodeboundary@loop + \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@computenodeboundary@repeat + \forest@repeat }% \def\forest@compute@node@boundary@signal{% \forest@mt{east}% @@ -3459,11 +5637,9 @@ \forest@lt{before south west}% }% \def\forest@node@computeabsolutepositions{% - \forestoset{x}{0pt}% - \forestoset{y}{0pt}% \edef\forest@marshal{% \noexpand\forest@node@foreachchild{% - \noexpand\forest@node@computeabsolutepositions@{0pt}{0pt}{\forestove{grow}}% + \noexpand\forest@node@computeabsolutepositions@{\forestove{x}}{\forestove{y}}{\forestove{grow}}% }% }\forest@marshal } @@ -3557,7 +5733,7 @@ \fi } \def\forest@node@drawtree@{% - \forest@node@foreach{\forest@draw@node}% + \forest@forthis{\forestset{draw tree method}}% \forest@node@Ifnamedefined{forest@baseline@node}{% \edef\forest@temp{% \noexpand\pgfsetbaselinepointlater{% @@ -3567,8 +5743,6 @@ }% }\forest@temp }{}% - \forest@node@foreachdescendant{\forest@draw@edge}% - \forest@node@foreach{\forest@draw@tikz}% } \def\forest@draw@node{% \ifnum\forestove{phantom}=0 @@ -3583,70 +5757,18 @@ \fi } \def\forest@draw@edge{% - \ifnum\forestove{phantom}=0 - \ifnum\forestOve{\forestove{@parent}}{phantom}=0 - \edef\forest@temp{\forestove{edge path}}% - \forest@temp + \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}% } -\def\forest@tikz@parse@node#1(#2){% - \pgfutil@in@.{#2}% - \ifpgfutil@in@ - \expandafter\forest@tikz@parse@node@checkiftikzname@withdot - \else% - \expandafter\forest@tikz@parse@node@checkiftikzname@withoutdot - \fi% - #1(#2)\forest@end -} -\def\forest@tikz@parse@node@checkiftikzname@withdot#1(#2.#3)\forest@end{% - \forest@tikz@parse@node@checkiftikzname#1{#2}{.#3}} -\def\forest@tikz@parse@node@checkiftikzname@withoutdot#1(#2)\forest@end{% - \forest@tikz@parse@node@checkiftikzname#1{#2}{}} -\def\forest@tikz@parse@node@checkiftikzname#1#2#3{% - \expandafter\ifx\csname pgf@sh@ns@#2\endcsname\relax - \forest@forthis{% - \forest@nameandgo{#2}% - \edef\forest@temp@relativenodename{\forestove{name}}% - }% - \else - \def\forest@temp@relativenodename{#2}% - \fi - \expandafter\forest@original@tikz@parse@node\expandafter#1\expandafter(\forest@temp@relativenodename#3)% -} -\def\forest@nameandgo#1{% - \pgfutil@in@!{#1}% - \ifpgfutil@in@ - \forest@nameandgo@(#1)% - \else - \ifstrempty{#1}{}{\edef\forest@cn{\forest@node@Nametoid{#1}}}% - \fi -} -\def\forest@nameandgo@(#1!#2){% - \ifstrempty{#1}{}{\edef\forest@cn{\forest@node@Nametoid{#1}}}% - \forest@go{#2}% -} -\pgfdeclaregenericanchor{parent anchor}{% - \forest@generic@parent@child@anchor{parent }{#1}} -\pgfdeclaregenericanchor{child anchor}{% - \forest@generic@parent@child@anchor{child }{#1}} -\pgfdeclaregenericanchor{anchor}{% - \forest@generic@parent@child@anchor{}{#1}} -\def\forest@generic@parent@child@anchor#1#2{% - \forestOget{\forest@node@Nametoid{\pgfreferencednodename}}{#1anchor}\forest@temp@parent@anchor - \ifdefempty\forest@temp@parent@anchor{% - \pgf@sh@reanchor{#2}{center}% - \xdef\forest@hack@tikzshapeborder{% - \noexpand\tikz@shapebordertrue - \def\noexpand\tikz@shapeborder@name{\pgfreferencednodename}% - }\aftergroup\forest@hack@tikzshapeborder - }{% - \pgf@sh@reanchor{#2}{\forest@temp@parent@anchor}% - }% -} \newdimen\forest@xg \newdimen\forest@yg \newdimen\forest@xs @@ -3705,7 +5827,7 @@ \edef\forest@ppi@inputprefix{#1}% \c@pgf@counta=0 \c@pgf@countb=-1 - \loop + \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}% @@ -3741,7 +5863,7 @@ \cslet{#1\the\c@pgf@counta xp}\relax \cslet{#1\the\c@pgf@counta yp}\relax \advance\c@pgf@counta 1 - \repeat + \saferepeat \cslet{#1n}\relax \advance\c@pgf@countb 1 \csedef{#2n}{\the\c@pgf@countb}% @@ -3814,7 +5936,7 @@ \def\forest@breakpath@step{-1}% \def\forest@breakpath@test{\forest@temp@count>\forest@i\relax}% \fi - \loop + \safeloop \advance\forest@temp@count\forest@breakpath@step\relax \expandafter\ifnum\forest@breakpath@test \pgfpointintersectionoflines @@ -3837,7 +5959,7 @@ \forest@last@x\forest@last@y {\forest@bp@prefix\the\forest@temp@count @}% \csedef{\forest@bp@prefix(\the\pgf@x,\the\pgf@y)}{\the\forest@temp@count}% - \repeat + \saferepeat \fi \forest@breakpath@op{#1}{#2}% \def\forest@previous@x{#1}% @@ -3864,34 +5986,32 @@ \forest@breakpath#1{forest@pi@}\forest@brokenpath \forest@sort@inner@arrays{forest@pi@}#2% \forest@pathtodict\forest@brokenpath{forest@pi@}% - \forest@gettightedgeofpath@getedge - \pgfsyssoftpath@getcurrentpath\forest@edge + \forest@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 - \loop + \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 - \repeat - \forest@gettightedgeofpath@getedge - \pgfsyssoftpath@getcurrentpath\forest@edge + \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 - }% + \global\let\forest@gep@global@firstedge\forest@gep@firstedge + \global\let\forest@gep@global@secondedge\forest@gep@secondedge + }% \let#2\forest@gep@global@firstedge \let#3\forest@gep@global@secondedge } \def\forest@sort@inner@arrays#1#2{% \c@pgf@counta=0 - \forest@loopa + \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 @@ -3901,7 +6021,7 @@ \forest@sort\forest@ppi@cmp\forest@ppi@let#2{0}{\the\c@pgf@countb}% \fi \advance\c@pgf@counta 1 - \forest@repeata + \saferepeat } \def\forest@ppi@deflet#1{% \edef\forest@ppi@let##1##2{% @@ -3936,7 +6056,7 @@ \def\forest@pathtodict@from{(#1,#2)-}% \def\forest@pathtodict@subpathstart{}% } -\def\forest@gettightedgeofpath@getedge{% +\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 @@ -3944,24 +6064,26 @@ \forest@temp@count=\forest@pi@n\relax \advance\forest@temp@count -1 \edef\forest@nminusone{\the\forest@temp@count}% - \forest@loopa + \safeloop \ifnum\c@pgf@counta<\forest@nminusone\relax \forest@gettightedgeofpath@getedge@loopa - \forest@repeata + \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 - \forest@loopb + \safeloop \ifnum\c@pgf@countb<\csname forest@pi@\the\c@pgf@counta @n\endcsname\relax \forest@gettightedgeofpath@getedge@loopb - \forest@repeatb + \saferepeat \fi \advance\c@pgf@counta 1 } @@ -3970,7 +6092,7 @@ \advance\c@pgf@counta 1 \edef\forest@aplusone{\the\c@pgf@counta}% \advance\c@pgf@counta -1 - \forest@loopc + \safeloop \ifnum\c@pgf@countc<\csname forest@pi@\forest@aplusone @n\endcsname\relax \forest@tempfalse \expandafter\ifx\csname forest@pi@(% @@ -4001,7 +6123,7 @@ \c@pgf@countb=\csname forest@pi@\the\c@pgf@counta @n\endcsname \fi \advance\c@pgf@countc 1 - \forest@repeatc + \saferepeat \advance\c@pgf@countb 1 } \def\forest@gettightedgeofpath@maybemoveto#1#2{% @@ -4035,6 +6157,7 @@ \fi \forest@restore@pgfsyssoftpath@tokendefs \pgfsyssoftpath@getcurrentpath#2% + \pgfsyssoftpath@setcurrentpath\pgfutil@empty } \def\forest@simplifypath@moveto#1#2{% \ifx\forest@last@x\relax\else @@ -4165,7 +6288,7 @@ % compute the distance \let\forest@distance\relax \c@pgf@countc=0 - \loop + \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 @@ -4181,7 +6304,7 @@ \fi \fi \advance\c@pgf@countc 1 - \repeat + \forest@repeat \let#3\forest@distance } % merge projections: we need two projection arrays, both containing @@ -4274,13 +6397,13 @@ \forest@dbep@mp@iterateone\forest@input@prefix@two\c@pgf@countb\forest@output@prefix@two } \def\forest@dbep@mp@iterateone#1#2#3{% - \loop + \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 - \repeat + \forest@repeat } \newif\ifforest@equaltotolerance \def\forest@equaltotolerance#1#2{{% @@ -4375,15 +6498,6 @@ \ifdim#2<\pgf@ya\relax\pgf@ya=#2 \fi \ifdim#2>\pgf@yb\relax\pgf@yb=#2 \fi } -\newif\ifforesttikzcshack -\foresttikzcshacktrue -\newif\ifforest@install@keys@to@tikz@path@ -\forest@install@keys@to@tikz@path@true -\forestset{package@options/.cd, - external/.is if=forest@external@, - tikzcshack/.is if=foresttikzcshack, - tikzinstallkeys/.is if=forest@install@keys@to@tikz@path@, -} \pgfkeys{/forest/external/.cd, copy command/.initial={cp "\source" "\target"}, optimize/.is if=forest@external@optimize@, @@ -4404,12 +6518,17 @@ }{}% \fi } -\newif\ifforest@external@ \newif\ifforest@external@optimize@ \forest@external@optimize@true -\ProcessPgfPackageOptions{/forest/package@options} \ifforest@install@keys@to@tikz@path@ - \tikzset{fit to tree/.style={/forest/fit to tree}} +\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 @@ -4447,13 +6566,23 @@ }% }% \fi -\newenvironment{forest}{\pgfkeysalso{/forest/begin forest}\Collect@Body\forest@env}{} -\long\def\Forest{\pgfkeysalso{/forest/begin forest}\@ifnextchar*{\forest@nogroup}{\forest@group}} -\def\forest@group#1{{\forest@env{#1}}} -\def\forest@nogroup*#1{\forest@env{#1}} +\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 -\long\def\forest@env#1{% +\newcommand\forest@env[1]{% \let\forest@external@next\forest@begin \forest@was@tikzexternalwasenablefalse \ifdefined\tikzexternal@tikz@replacement @@ -4465,16 +6594,23 @@ \forest@externalize@tree@false \ifforest@external@ \ifforest@was@tikzexternalwasenable - \tikzifexternalizing{% - \let\forest@external@next\forest@begin@externalizing - }{% - \let\forest@external@next\forest@begin@externalize - }% + \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 @@ -4570,8 +6706,7 @@ } \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}'}% + %\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}% @@ -4599,9 +6734,7 @@ } \def\forest@do{% \forest@node@Compute@numeric@ts@info{\forest@root}% - \forestset{process keylist=given options}% - \forestset{stages}% - \pgfkeysalso{/forest/end forest}% + \expandafter\forestset\expandafter{\forest@stages}% \ifforest@was@tikzexternalwasenable \tikzexternalenable \fi @@ -4698,11 +6831,9 @@ } } \def\forest@forestcs@resetxy{% - \ifnum\forest@cn=0 - \else - \global\pgf@x\forestove{x}% - \global\pgf@y\forestove{y}% - \fi + \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 @@ -4725,8 +6856,12 @@ } \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 @@ -4735,6 +6870,321 @@ \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'. -- cgit v1.2.3