summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/forest/forest.sty
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2016-12-06 00:28:11 +0000
committerKarl Berry <karl@freefriends.org>2016-12-06 00:28:11 +0000
commit98c0bc5c3d62d24f3f39fcc797792e70029c65aa (patch)
tree25cf0a9b31ec1d1c699632069b6a07cd2fcb8446 /Master/texmf-dist/tex/latex/forest/forest.sty
parent0490ce6a2a0e554c8e241df1699801decea844b8 (diff)
forest (5dec16)
git-svn-id: svn://tug.org/texlive/trunk@42640 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/forest/forest.sty')
-rw-r--r--Master/texmf-dist/tex/latex/forest/forest.sty2839
1 files changed, 2287 insertions, 552 deletions
diff --git a/Master/texmf-dist/tex/latex/forest/forest.sty b/Master/texmf-dist/tex/latex/forest/forest.sty
index 16c96a52e44..dedd3159561 100644
--- a/Master/texmf-dist/tex/latex/forest/forest.sty
+++ b/Master/texmf-dist/tex/latex/forest/forest.sty
@@ -8,7 +8,7 @@
%%
%% `forest' is a `pgf/tikz'-based package for drawing (linguistic) trees.
%%
-%% Copyright (c) 2015 Saso Zivanovic
+%% Copyright (c) 2016 Saso Zivanovic
%% (Sa\v{s}o \v{Z}ivanovi\'{c})
%% saso.zivanovic@guest.arnes.si
%%
@@ -44,7 +44,7 @@
%% - LICENCE
%% To use the package, only the files marked with + need to be installed.
%%
-\ProvidesPackage{forest}[2016/04/09 v2.0.3 Drawing (linguistic) trees]
+\ProvidesPackage{forest}[2016/12/05 v2.1 Drawing (linguistic) trees]
\RequirePackage{tikz}[2013/12/13]
\usetikzlibrary{shapes}
@@ -58,7 +58,74 @@
\RequirePackage{environ}
\RequirePackage{xparse}
-
+\RequirePackage{inlinedef}
+\newtoks\ID@usercommands{}
+\newcommand\NewInlineCommand[3][0]{%
+ \newcommand#2[#1]{#3}%
+ \ID@usercommands\xa{%
+ \the\ID@usercommands
+ \ifx\@foo#2%
+ \def\next{\ID@expandunsafe#2}%
+ \fi
+ }%
+}
+\def\@ExpandIfTF#1{%
+ \csname
+ % I'm not 100% sure if this plays well in every situation
+ \csname if#1\endcsname
+ @firstoftwo%
+ \else
+ @secondoftwo%
+ \fi
+ \endcsname
+}
+\patchcmd{\ID@switch}
+ {\ifcat\noexpand\@foo\space}
+ {\the\ID@usercommands\ifcat\noexpand\@foo\space}
+ {%
+ \NewInlineCommand[2]\ExpandIfT{%
+ \MultiExpand{3}{%
+ \@ExpandIfTF{#1}{#2}{}%
+ }%
+ }
+ \NewInlineCommand[2]\ExpandIfF{%
+ \MultiExpand{3}{%
+ \@ExpandIfTF{#1}{}{#2}%
+ }%
+ }
+ \NewInlineCommand[3]\ExpandIfTF{%
+ \MultiExpand{3}{%
+ \@ExpandIfTF{#1}{#2}{#3}%
+ }%
+ }%
+ \newcommand\InlineNoDef[1]{%
+ \begingroup
+ % Define a few ``quarks''
+ \def\Expand{\Expand}\def\Super{\Super}%
+ \def\UnsafeExpand{\UnsafeExpand}\def\MultiExpand{\MultiExpand}%
+ \def\Recurse{\Recurse}\def\NoExpand{\NoExpand}%
+ \def\Q@END{\Q@END}%
+ % Define a toks register
+ \ID@toks{}%
+ % Signal that we need to look for a star
+ \@testtrue\ID@starfalse\ID@starstarfalse\ID@bangfalse
+ % Start scanning for \def or \gdef
+ \ID@scan#1\Q@END{}%
+ \expandafter\endgroup
+ %\expandafter\@firstofone
+ \the\ID@toks
+ }%
+ }%
+ {%
+ \PackageWarning{forest}{Could not patch inlinedef! Disabling it. Except in some special situations (nested arrays), stuff will probably still work, but there's no guarantee. Please report this situation to the author (but check first if a new version already exists).}{}%
+ \let\Inline\relax
+ \def\Expand#1{#1}%
+ \def\MultiExpand#1#2{#2}%
+ \def\InlineNoDef#1{#1}%
+ \def\ExpandIfT#1#2{\@ExpandIfTF{#1}{#2}{}}%
+ \def\ExpandIfF#1#2{\@ExpandIfTF{#1}{}{#2}}%
+ \def\ExpandIfTF#1#2#3{\@ExpandIfTF{#1}{#2}{#3}}%
+ }
\pgfkeys{/forest/.is family}
\def\forestset#1{\pgfqkeys{/forest}{#1}}
\newif\ifforest@external@
@@ -66,12 +133,15 @@
\newif\ifforest@install@keys@to@tikz@path@
\newif\ifforestdebugnodewalks
\newif\ifforestdebugdynamics
+\newif\ifforestdebugprocess
+\newif\ifforestdebugtemp
+\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@,
- compat/.store in=\forest@compat,
+ compat/.code={\appto\forest@compat{,#1}},
compat/.default=most,
.unknown/.code={% load library
\eappto\forest@loadlibrarieslater{%
@@ -79,10 +149,11 @@
\noexpand\forestapplylibrarydefaults{\pgfkeyscurrentname}%
}%
},
- debug/.code={\pgfqkeys{/forest/package@options/debug}{#1}},
- debug/.default={nodewalks,dynamics},
+ debug/.code={\forestdebugtrue\pgfqkeys{/forest/package@options/debug}{#1}},
+ debug/.default={nodewalks,dynamics,process},
debug/nodewalks/.is if=forestdebugnodewalks,
debug/dynamics/.is if=forestdebugdynamics,
+ debug/process/.is if=forestdebugprocess,
}
\forest@install@keys@to@tikz@path@true
\foresttikzcshacktrue
@@ -93,10 +164,17 @@
\forcsvlist\useforestlibrary@@{#3}%
\IfBooleanT{#1}{\forestapplylibrarydefaults{#3}}%
}
-\def\useforestlibrary@#1#2{\RequirePackage[#1]{forest-lib-#2}}
+\def\useforestlibrary@#1#2{%
+ \RequirePackage[#1]{forest-lib-#2}%
+ \csuse{forest@compat@libraries@#2}%
+}
\def\forestapplylibrarydefaults#1{\forcsvlist\forestapplylibrarydefaults@{#1}}
\def\forestapplylibrarydefaults@#1{\forestset{libraries/#1/defaults/.try}}
-\NewDocumentCommand\ProvidesForestLibrary{m O{}}{\ProvidesPackage{forest-lib-#1}[#2]}
+\NewDocumentCommand\ProvidesForestLibrary{m O{}}{%
+ \ProvidesPackage{forest-lib-#1}[#2]%
+ \csdef{forest@libraries@loaded@#1}{}%
+}
+\def\forest@iflibraryloaded#1#2#3{\ifcsdef{forest@libraries@loaded@#1}{#2}{#3}}
\ProcessPgfPackageOptions{/forest/package@options}
\def\forest@patch#1#2#3#4#5{%
% #1 = cs to be patched
@@ -120,9 +198,25 @@
}{%
\edef#1{{\pgf@pt@aa}{\pgf@pt@ab}{\pgf@pt@ba}{\pgf@pt@bb}{\the\pgf@pt@x}{\the\pgf@pt@y}}%
}
+\def\forest@empty{}
\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\forest@repeat@n@times#1{% #1=n, #2=code
+ \expandafter\forest@repeat@n@times@\expandafter{\the\numexpr#1}}
+\def\forest@repeat@n@times@#1{%
+ \ifnum#1>0
+ \@escapeif{%
+ \expandafter\forest@repeat@n@times@@\expandafter{\the\numexpr#1-1}%
+ }%
+ \else
+ \expandafter\@gobble
+ \fi
+}
+\def\forest@repeat@n@times@@#1#2{%
+ #2%
+ \forest@repeat@n@times@{#1}{#2}%
+}
\def\newloop#1{%
\count@=\escapechar
\escapechar=-1
@@ -398,6 +492,7 @@
\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\pgfkeysalso\expandafter\expandafter\expandafter{\expandafter\forest@temp@macro\expandafter{\forest@temp@value}}% ??? how many expansions are really needed?
\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfkeysalso\expandafter\expandafter\expandafter{\expandafter\forest@temp@macro\expandafter{\forest@temp@value}}%
}%
}{}%
@@ -449,6 +544,690 @@
\fi
}%
}
+\forestset{
+ show register/.code={%
+ \forestrget{#1}\foresttemp
+ \typeout{Forest register "#1"=\expandafter\detokenize\expandafter{\foresttemp}}%
+ },
+}
+\def\forest@newarray#1{%
+ \forest@tempfalse % non-global
+ {%
+ \escapechar=-1
+ \expandafter\escapechar\expandafter\count@\expandafter
+ }%
+ \expandafter\forest@newarray@\expandafter{\string#1}%
+}
+\def\forest@newglobalarray#1{%
+ \forest@temptrue % global
+ {%
+ \escapechar=-1
+ \expandafter\escapechar\expandafter\count@\expandafter
+ }%
+ \expandafter\forest@newarray@\expandafter{\string#1}%
+}
+\def\forest@array@empty@error#1{%
+ \PackageError{forest}{Cannot pop from empty array "#1".}{}}%
+\def\forest@array@oub@error#1#2{%
+ \PackageError{forest}{#2 is out of bounds of array "#1"
+ (\the\csuse{#1M}--\the\csuse{#1N}).}{}}%
+\def\forest@newarray@#1{%
+ % array bounds: M <= i < N
+ \expandafter\newcount\csname#1M\endcsname
+ \expandafter\newcount\csname#1N\endcsname
+ \csedef{#1clear}{%
+ \ifforest@temp\global\fi\expandonce{\csname#1M\endcsname}0
+ \ifforest@temp\global\fi\expandonce{\csname#1N\endcsname}0
+ }%
+ \csedef{#1ifempty}{%
+ \noexpand\ifnum\expandonce{\csname#1M\endcsname}<\expandonce{\csname#1N\endcsname}\relax
+ \unexpanded{\expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi}%
+ }%
+ \csedef{#1length}{% a numexpr
+ \noexpand\numexpr\expandonce{\csname#1N\endcsname}-\expandonce{\csname#1M\endcsname}\relax
+ }%
+ \csedef{#1checkrange}##1##2{% args can be \numexprs
+ \noexpand\forest@tempfalse
+ \noexpand\ifnum\numexpr##1<\expandonce{\csname#1M\endcsname}\relax
+ \noexpand\forest@temptrue
+ \noexpand\fi
+ \noexpand\ifnum\numexpr##2>\expandonce{\csname#1N\endcsname}\relax
+ \noexpand\forest@temptrue
+ \noexpand\fi
+ \noexpand\ifforest@temp
+ \noexpand\forest@array@oub@error{#1}{Range "\noexpand\number\noexpand\numexpr##1\relax--\noexpand\number\noexpand\numexpr##2\relax"}%
+ \noexpand\fi
+ }%
+ \csedef{#1checkindex}##1{% arg can be a \numexpr
+ \noexpand\forest@tempfalse
+ \noexpand\ifnum\numexpr##1<\expandonce{\csname#1M\endcsname}\relax
+ \noexpand\forest@temptrue
+ \noexpand\fi
+ \noexpand\ifnum\numexpr##1<\expandonce{\csname#1N\endcsname}\relax
+ \noexpand\else
+ \noexpand\forest@temptrue
+ \noexpand\fi
+ \noexpand\ifforest@temp
+ \noexpand\forest@array@oub@error{#1}{Index "\noexpand\number\noexpand\numexpr##1\relax"}%
+ \noexpand\fi
+ }%
+ \csedef{#1get}##1##2{% ##1 = index, ##2 = receiving cs
+ \expandonce{\csname#1checkindex\endcsname}{##1}%
+ \noexpand\letcs##2{#1##1}%
+ }%
+ \csedef{#1get@}##1##2{% ##1 = index, ##2 = receiving cs (don't check bounds)
+ \noexpand\letcs##2{#1##1}%
+ }%
+ \csedef{#1toppop}##1{% ##1 = receiving cs
+ \expandonce{\csname#1ifempty\endcsname}{%
+ \noexpand\forest@array@empty@error{#1}%
+ }{%
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1N\endcsname}-1
+ \noexpand\letcs\noexpand##1{#1\noexpand\the\expandonce{\csname#1N\endcsname}}%
+ }%
+ }%
+ \InlineNoDef{\csdef{#1bottompop}##1{% ##1 = receiving cs
+ \Expand{\csname#1ifempty\endcsname}{%
+ \forest@array@empty@error{#1}%
+ }{%
+ \letcs##1{#1\the\Expand{\csname#1M\endcsname}}%
+ \ExpandIfT{forest@temp}\global\advance\Expand{\csname#1M\endcsname 1}%
+ }%
+ }}%
+ % \csdef{#1bottompop}##1{}% we need this as \Inline chokes on \let\macro=\relax
+ % \expandafter\Inline\expandafter\def\csname#1bottompop\endcsname##1{% ##1 = receiving cs
+ % \Expand{\csname#1ifempty\endcsname}{%
+ % \forest@array@empty@error{#1}%
+ % }{%
+ % \letcs##1{#1\the\Expand{\csname#1M\endcsname}}%
+ % \ExpandIfT{forest@temp}\global\advance\Expand{\csname#1M\endcsname 1}%
+ % }%
+ % }%
+ % \csedef{#1bottompop}##1{% ##1 = receiving cs
+ % \expandonce{\csname#1ifempty\endcsname}{%
+ % \noexpand\forest@array@empty@error{#1}%
+ % }{%
+ % \noexpand\letcs\noexpand##1{#1\noexpand\the\expandonce{\csname#1M\endcsname}}%
+ % \ifforest@temp\global\fi\advance\expandonce{\csname#1M\endcsname}1
+ % }%
+ % }%
+ \csedef{#1setappend}##1{% ##1 = definition
+ \ifforest@temp\noexpand\csxdef\else\noexpand\csedef\fi
+ {#1\noexpand\the\expandonce{\csname#1N\endcsname}}%
+ {\noexpand\unexpanded{##1}}%
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1N\endcsname}1
+ }%
+ \csedef{#1setappend@}##1##2{% ##1 = continue by, ##2 = definition
+ \ifforest@temp\noexpand\csxdef\else\noexpand\csedef\fi
+ {#1\noexpand\the\expandonce{\csname#1N\endcsname}}%
+ {\noexpand\unexpanded{##2}}%
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1N\endcsname}1
+ ##1%
+ }%
+ \csedef{#1setprepend}##1{% ##1 = definition
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1M\endcsname}-1
+ \ifforest@temp\noexpand\csxdef\else\noexpand\csedef\fi
+ {#1\noexpand\the\expandonce{\csname#1M\endcsname}}%
+ {\noexpand\unexpanded{##1}}%
+ }%
+ \csedef{#1esetappend}##1{% ##1 = definition
+ \ifforest@temp\noexpand\csxdef\else\noexpand\csedef\fi{#1\noexpand\the\expandonce{\csname#1N\endcsname}}{##1}%
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1N\endcsname}1
+ }%
+ \csedef{#1esetprepend}##1{% ##1 = definition
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1M\endcsname}-1
+ \ifforest@temp\noexpand\csxdef\else\noexpand\csedef\fi{#1\noexpand\the\expandonce{\csname#1M\endcsname}}{##1}%
+ }%
+ \csedef{#1letappend}##1{% ##1 = cs
+ \ifforest@temp\noexpand\expandafter\noexpand\global\fi\noexpand\expandafter\noexpand\let
+ \noexpand\csname#1\noexpand\the\expandonce{\csname#1N\endcsname}\noexpand\endcsname
+ ##1%
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1N\endcsname}1
+ }%
+ \csedef{#1letprepend}##1{% ##1 = cs
+ \ifforest@temp\global\fi\advance\expandonce{\csname#1M\endcsname}-1
+ \ifforest@temp\noexpand\expandafter\noexpand\global\fi\noexpand\expandafter\noexpand\let
+ \noexpand\csname#1\noexpand\the\expandonce{\csname#1M\endcsname}\noexpand\endcsname
+ ##1%
+ }%
+ \csedef{#1values}{%
+ \noexpand\expandafter\noexpand\expandafter\noexpand\expandafter\expandonce{\csname#1valuesfromrange\endcsname}%
+ \noexpand\expandafter\noexpand\expandafter\noexpand\expandafter{%
+ \noexpand\expandafter\noexpand\the
+ \noexpand\expandafter\expandonce{\csname#1M\endcsname}%
+ \noexpand\expandafter}%
+ \noexpand\expandafter{\noexpand\the\expandonce{\csname#1N\endcsname}}%
+ }%
+ \csedef{#1valuesfromrange}##1##2{% ##1/##2 = lower/upper bounds (we receive them expanded)
+ \noexpand\ifnum##1<##2
+ {\noexpand\expandafter\noexpand\expandonce\noexpand\expandafter{\noexpand\csname#1##1\noexpand\endcsname}}% here we add braces (for the general case, we might want an arbitrary prefix&suffix)
+ \noexpand\expandafter\noexpand\@escapeif\noexpand\expandafter{\noexpand\expandafter\expandonce{\csname#1valuesfromrange\endcsname}%
+ \noexpand\expandafter{\noexpand\number\noexpand\numexpr##1+1}{##2}}%
+ \noexpand\fi
+ }%
+ \csdef{#1topextend}{\def\forest@array@currentarray{#1}\forest@array@topextend}%
+}
+\def\forest@array@topextend{\futurelet\forest@ate@next@token\forest@ate@checkforspace}
+\def\forest@ate@checkforspace{%
+ \expandafter\ifx\space\forest@ate@next@token
+ \expandafter\forest@ate@havespace
+ \else
+ \expandafter\forest@ate@checkforgroup
+ \fi
+}
+\def\forest@ate@havespace{\expandafter\forest@array@topextend\romannumeral-`0}%
+\def\forest@ate@checkforgroup{%
+ \ifx\forest@ate@next@token\bgroup
+ \expandafter\forest@ate@appendgroup
+ \else
+ \expandafter\forest@ate@checkforeov
+ \fi
+}
+\def\forest@ate@appendgroup{%
+ \expandonce{\csname\forest@array@currentarray setappend@\endcsname}\forest@array@topextend
+}
+\def\forest@ate@checkforeov{%
+ \ifx\forest@ate@next@token\forest@eov
+ \expandafter\forest@ate@finish
+ \else
+ \expandafter\forest@ate@appendtoken
+ \fi
+}
+\def\forest@ate@appendtoken#1{%
+ \expandonce{\csname\forest@array@currentarray setappend\endcsname}{#1}%
+ \forest@array@topextend
+}
+\def\forest@ate@finish\forest@eov{\forest@topextend@next}
+\let\forest@topextend@next\relax
+\forest@newarray\forest@temparray@
+\forest@newglobalarray\forest@global@temparray@
+\def\forest@eon{ }
+\newif\ifforest@isnum@minus
+\newif\ifforest@isnum
+\def\forest@isnum#1{%
+ \forest@isnum@minusfalse
+ \let\forest@isnum@next\forest@isnum@finish
+ \edef\forest@isnum@temp{#1}%
+ \expandafter\forest@isnum@a\forest@isnum@temp\forest@eon\forest@eon\forest@END
+ \ifforest@isnum
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+\def\forest@isnum@a{\futurelet\forest@isnum@token\forest@isnum@b}
+\def\forest@isnum@minustoggle{%
+ \ifforest@isnum@minus\forest@isnum@minusfalse\else\forest@isnum@minustrue\fi
+}
+\def\forest@isnum@b{%
+ \let\forest@next\forest@isnum@p
+ \ifx-\forest@isnum@token
+ \forest@isnum@minustoggle
+ \let\forest@next\forest@isnum@c
+ \else
+ \ifx+\forest@isnum@token
+ \let\forest@next\forest@isnum@c
+ \else
+ \expandafter\ifx\space\forest@isnum@token
+ \let\forest@next\forest@isnum@s
+ \fi
+ \fi
+ \fi
+ \forest@next
+}
+\def\forest@isnum@c#1{\forest@isnum@a}%
+\def\forest@isnum@s#1{\forest@isnum@a#1}%
+\newcount\forest@isnum@count
+\def\forest@isnum@p{%
+ \ifx0\forest@isnum@token
+ \let\forest@next\forest@isnum@next
+ \else
+ \let\forest@next\forest@isnum@nz@
+ \fi
+ \forest@isnumtrue
+ \afterassignment\forest@isnum@q\forest@isnum@count\ifforest@isnum@minus-\fi0%
+}
+\def\forest@isnum@q{%
+ \futurelet\forest@isnum@token\forest@next
+}
+\def\forest@isnum@nz@{%
+ \ifnum\forest@isnum@count=0
+ \forest@isnumfalse
+ \fi
+ \forest@isnum@next
+}
+\def\forest@isnum@finish#1\forest@END{%
+ \ifx\forest@isnum@token\forest@eon
+ \else
+ \forest@isnumfalse
+ \fi
+}
+\newcount\forest@isdim@nonintpart
+\newif\ifforest@isdim
+\def\forest@isdim#1{%
+ \forest@isdimfalse
+ \forest@isnum@minusfalse
+ \def\forest@isdim@leadingzeros{}%
+ \forest@isdim@nonintpart=0
+ \def\forest@isdim@unit{pt}%
+ \let\forest@isnum@next\forest@isdim@checkfordot
+ \edef\forest@isnum@temp{#1}%
+ \expandafter\forest@isnum@a\forest@isnum@temp\forest@eon\forest@eon\forest@eon\forest@eon\forest@END
+ \ifforest@isdim
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+\def\forest@isdim@checkfordot{%
+ \ifx.\forest@isnum@token
+ \expandafter\forest@isdim@dot
+ \else
+ \ifx,\forest@isnum@token
+ \expandafter\expandafter\expandafter\forest@isdim@dot
+ \else
+ \expandafter\expandafter\expandafter\forest@isdim@nodot
+ \fi
+ \fi
+}
+\def\forest@isdim@nodot{%
+ \ifforest@isnum
+ \expandafter\forest@isdim@checkforunit
+ \else
+ \expandafter\forest@isdim@finish@nodim
+ \fi
+}
+\def\forest@isdim@dot#1{% #1=. or ,
+ \futurelet\forest@isnum@token\forest@isdim@collectzero
+}
+\def\forest@isdim@collectzero{%
+ \ifx0\forest@isnum@token
+ \expandafter\forest@isdim@collectzero@
+ \else
+ \expandafter\forest@isdim@getnonintpart
+ \fi
+}
+\def\forest@isdim@collectzero@#1{% #1 = 0
+ \appto\forest@isdim@leadingzeros{0}%
+ \futurelet\forest@isnum@token\forest@isdim@collectzero
+}
+\def\forest@isdim@getnonintpart{%
+ \afterassignment\forest@isdim@checkforunit\forest@isdim@nonintpart0%
+}
+\def\forest@def@unit#1{\csdef{forest@unit@#1}{#1}}
+\forest@def@unit{em}
+\forest@def@unit{ex}
+\forest@def@unit{pt}
+\forest@def@unit{pc}
+\forest@def@unit{in}
+\forest@def@unit{bp}
+\forest@def@unit{cm}
+\forest@def@unit{mm}
+\forest@def@unit{dd}
+\forest@def@unit{cc}
+\forest@def@unit{sp}
+\def\forest@isdim@checkforunit#1#2{%
+ \lowercase{\edef\forest@isnum@temp{\detokenize{#1#2}}}%
+ \ifcsname forest@unit@\forest@isnum@temp\endcsname
+ \let\forest@isdim@next\forest@isdim@finish@dim
+ \edef\forest@isdim@unit{\csname forest@unit@\forest@isnum@temp\endcsname}%
+ \else
+ \ifx#1\forest@eon
+ \let\forest@isdim@next\forest@isdim@finish@dim
+ \else
+ \let\forest@isdim@next\forest@isdim@finish@nodim
+ \fi
+ \fi
+ \forest@isdim@next
+}
+\def\forest@isdim@finish@dim{%
+ \futurelet\forest@isnum@token\forest@isdim@finish@dim@a
+}
+\def\forest@isdim@finish@dim@a{%
+ \expandafter\ifx\space\forest@isnum@token
+ \expandafter\forest@isdim@finish@dim@b
+ \else
+ \expandafter\forest@isdim@finish@dim@c
+ \fi
+}
+\expandafter\def\expandafter\forest@isdim@finish@dim@b\space{% eat one space
+ \futurelet\forest@isnum@token\forest@isdim@finish@dim@c
+}
+\def\forest@isdim@finish@dim@c#1\forest@END{%
+ \ifx\forest@isnum@token\forest@eon
+ \forest@isdimtrue
+ \forest@isdim@dimen\the\forest@isnum@count.\forest@isdim@leadingzeros\the\forest@isdim@nonintpart\forest@isdim@unit\relax
+ \else
+ \forest@isdimfalse
+ \fi
+}
+\def\forest@isdim@finish@nodim#1\forest@END{%
+ \forest@isdimfalse
+}
+\newdimen\forest@isdim@dimen
+ % \long\def\@firstofthree#1#2#3{#3} % defined by LaTeX
+\long\def\@firstofthree#1#2#3{#1}
+\long\def\@secondofthree#1#2#3{#2}
+\def\forest@isnumdim#1{%
+ \forest@isdim{#1}{%
+ \forest@isnumdim@
+ }{%
+ \@thirdofthree
+ }%
+}
+\def\forest@isnumdim@{%
+ \ifforest@isnum
+ \expandafter\@firstofthree
+ \else
+ \expandafter\@secondofthree
+ \fi
+}
+\def\forestmathtype@generic{_} % generic (token list)
+\def\forestmathtype@count{n} % integer
+\def\forestmathtype@dimen{d} % a dimension: <decimal> pt
+\def\forestmathtype@unitless{P} % <decimal> (a unitless dimension) (P because pgfmath returns such numbers)
+\def\forestmathtype@textasc{t} % text (ascending)
+\def\forestmathtype@textdesc{T} % text (descending)
+\def\forestmathtype@array{a} % array - internal
+\def\forestmathtype@none{} % internal (for requests - means whatever)
+\def\forestmathresult{}
+\let\forestmathresulttype\forestmathtype@generic
+\def\forest@tryprocess{%
+ \expandafter\forest@tryprocess@a\romannumeral-`0}
+\def\forest@tryprocess@a{\futurelet\forest@temp@token\forest@tryprocess@b}
+\def\forest@tryprocess@b{%
+ \ifx>\forest@temp@token
+ \expandafter\forest@tryprocess@yes
+ \else
+ \expandafter\forest@tryprocess@no
+ \fi
+}
+\def\forest@spacegen{ \forest@spacegen}
+\def\forest@tryprocess@yes#1#2\forest@spacegen{%
+ \forest@process{false}#2\forest@eov
+ \@firstoftwo
+}
+\def\forest@tryprocess@no#1\forest@spacegen{\@secondoftwo}
+\def\forestmathsetcount#1#2{%
+ \forest@tryprocess#2\forest@spacegen{%
+ #1=\forest@process@result\relax
+ }{%
+ \forestmathsetcount@#1{#2}%
+ }%
+}
+\def\forestmathsetcount@#1#2{%
+ \forest@isnum{#2}{%
+ #1=\forest@isnum@count
+ }{%
+ \pgfmathsetcount#1{#2}%
+ }%
+}
+\def\forestmathsetlength#1#2{%
+ \forest@tryprocess#2\forest@spacegen{%
+ #1=\forest@process@result\relax
+ }{%
+ \forestmathsetlength@#1{#2}%
+ }%
+}
+\def\forestmathsetlength@#1#2{%
+ \forest@isdim{#2}{%
+ #1=\forest@isdim@dimen
+ }{%
+ \pgfmathsetlength#1{#2}%
+ }%
+}
+\def\forestmathtruncatemacro#1#2{%
+ \forest@tryprocess#2\forest@spacegen{%
+ \forest@temp@count=\forest@process@result\relax
+ \edef#1{\the\forest@temp@count}%
+ }{%
+ \forestmathtruncatemacro@#1{#2}%
+ }%
+}
+\def\forestmathtruncatemacro@#1#2{%
+ \forest@isnum{#2}{%
+ \edef#1{\the\forest@isnum@count}%
+ }{%
+ \pgfmathtruncatemacro#1{#2}%
+ }%
+}
+\def\forestmathsetlengthmacro#1#2{%
+ \forest@tryprocess#2\forest@spacegen{%
+ \forest@temp@dimen=\forest@process@result\relax
+ \edef#1{\the\forest@temp@dimen}%
+ }{%
+ \forestmathsetlengthmacro@#1{#2}%
+ }%
+}
+\def\forestmathsetlengthmacro@#1#2{%
+ \forest@isdim{#2}{%
+ \edef#1{\the\forest@isdim@dimen}%
+ }{%
+ \pgfmathsetlengthmacro#1{#2}%
+ }%
+}
+\def\forestmathsetmacro#1#2{%
+ \forest@tryprocess#2\forest@spacegen{%
+ \let#1\forest@process@result
+ \let\forestmathresulttype\forest@process@result@type
+ }{%
+ \forestmathsetmacro@#1{#2}%
+ \def\forestmathresulttype{P}%
+ }%
+}
+\def\forestmathsetmacro@#1#2{%
+ \forest@isdim{#2}{%
+ \edef#1{\expandafter\Pgf@geT\the\forest@isdim@dimen}%
+ }{%
+ \pgfmathsetmacro#1{#2}%
+ }%
+}
+\def\forestmathparse#1{%
+ \forest@tryprocess#1\forest@spacegen{%
+ \let\forestmathresult\forest@process@result
+ \let\forestmathresulttype\forest@process@result@type
+ }{%
+ \forestmathparse@{#1}%
+ \def\forestmathresulttype{P}%
+ }%
+}
+\def\forestmathparse@#1{%
+ \forest@isdim{#1}{%
+ \edef\forestmathresult{\expandafter\Pgf@geT\the\forest@isdim@dimen}%
+ }{%
+ \pgfmathsetmacro\forestmathresult{#1}%
+ }%
+}
+\csdef{forest@bh@0}{0}
+\csdef{forest@bh@false}{0}
+\csdef{forest@bh@1}{1}
+\csdef{forest@bh@true}{1}
+\def\forestmath@if#1{%
+ \ifcsdef{forest@bh@\detokenize{#1}}{%
+ \let\forest@next\forestmath@if@fast
+ }{%
+ \let\forest@next\forestmath@if@slow
+ }%
+ \forest@next{#1}%
+ \ifnum\forest@temp=0
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi
+}
+\def\forestmath@if@fast#1{\letcs\forest@temp{forest@bh@\detokenize{#1}}}
+\def\forestmath@if@slow#1{\forestmathtruncatemacro\forest@temp{#1}}
+\def\forestmath@convert@fromto#1#2#3{%
+ \edef\forestmathresult{\csname forestmath@convert@from@#1@to@#2\endcsname{#3}}}
+\def\forestmath@convert@from#1{\forestmath@convert@fromto{#1}{\forestmathresulttype}}
+\def\forestmath@convert@to{\forestmath@convert@fromto{\forestmathresulttype}}
+\def\forestmath@convert@from@n@to@n#1{#1}
+\def\forestmath@convert@from@n@to@d#1{#1\pgfmath@pt}
+\def\forestmath@convert@from@n@to@P#1{#1}
+\def\forestmath@convert@from@d@to@n#1{%
+ \expandafter\forestmath@convert@uptodot\Pgf@geT#1.\forest@eov}
+\def\forestmath@convert@from@d@to@d#1{#1}
+\def\forestmath@convert@from@d@to@P#1{\Pgf@geT#1}
+\def\forestmath@convert@from@P@to@n#1{%
+ \forestmath@convert@uptodot#1.\forest@eov}
+\def\forestmath@convert@from@P@to@d#1{#1\pgfmath@pt}
+\def\forestmath@convert@from@P@to@P#1{#1}
+\def\forestmath@convert@uptodot#1.#2\forest@eov{#1}
+\def\forestmathzero{\forestmath@convert@from\forestmathtype@count{0}}
+\csdef{forestmath@convert@from@n@to@_}#1{\unexpanded{#1}}
+\csdef{forestmath@convert@from@d@to@_}#1{\unexpanded{#1}}
+\csdef{forestmath@convert@from@P@to@_}#1{\unexpanded{#1}}
+\def\forestmathsettypefrom#1{%
+ \forest@isnumdim{%
+ \let\forestmathresulttype\forest@result@type@numexpr
+ }{%
+ \let\forestmathresulttype\forest@result@type@dimexpr
+ }{%
+ \let\forestmathresulttype\forest@result@type@pgfmath
+ }%
+}
+\def\forestmathadd#1#2{\edef\forestmathresult{%
+ \csname forestmathadd@\forestmathresulttype\endcsname{#1}{#2}}}
+\def\forestmathadd@#1#2#3{\edef\forestmathresult{%
+ \csname forestmathadd@#1\endcsname{#2}{#3}}}
+\def\forestmathadd@n#1#2{\the\numexpr#1+#2\relax}
+\def\forestmathadd@d#1#2{\the\dimexpr#1+#2\relax}
+\def\forestmathadd@P#1#2{\expandafter\Pgf@geT\the\dimexpr#1pt+#2pt\relax}
+\def\forestmathmultiply#1#2{%
+ \csname forestmathmultiply@\forestmathresulttype\endcsname{#1}{#2}}
+\def\forestmathmultiply@#1#2#3{%
+ \csname forestmathmultiply@#1\endcsname{#2}{#3}}
+\def\forestmathmultiply@n#1#2{\edef\forestmathresult{%
+ \the\numexpr#1*#2\relax}}
+\def\forestmathmultiply@d#1#2{%
+ \edef\forestmath@marshal{\forestmathmultiply@d@{#1}{#2}}\forestmath@marshal
+}
+\def\forestmathmultiply@d@#1#2{%
+ \edef\forestmath@marshal{%
+ \noexpand\pgfmathmultiply@{\Pgf@geT#1}{\Pgf@geT#2}%
+ }\forestmath@marshal
+ \edef\forestmathresult{\pgfmathresult\pgfmath@pt}%
+}
+\def\forestmathmultiply@P#1#2{%
+ \pgfmathmultiply@{#1}{#2}%
+ \let\forestmathresult\pgfmathresult
+}
+\def\forestmathdivide#1#2{%
+ \csname forestmathdivide@\forestmathresulttype\endcsname{#1}{#2}}
+\def\forestmathdivide@#1#2#3{%
+ \csname forestmathdivide@#1\endcsname{#2}{#3}}
+\def\forestmathdivide@n#1#2{\edef\forestmathresult{%
+ \the\numexpr#1/#2\relax}}
+\def\forestmathdivide@d#1#2{\edef\forestmathresult{%
+ \the\dimexpr#1/#2\relax}}
+\def\forestmathdivide@P#1#2{%
+ \edef\forest@marshal{%
+ \noexpand\pgfmathdivide{+#1}{+#2}%
+ }\forest@marshal
+ \let\forestmathresult\pgfmathresult
+}
+\def\forestmathtrue{%
+ \def\forestmathresult{1}%
+ \let\forestmathresulttype\forestmathtype@count}
+\def\forestmathfalse{%
+ \def\forestmathresult{0}%
+ \let\forestmathresulttype\forestmathtype@count}
+\def\forestmath@if@lt@n#1#2{\ifnum#1<#2\relax
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@lt@d#1#2{\ifdim#1<#2\relax
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@lt@P#1#2{\ifdim#1pt<#2pt
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@lt@t#1#2{\ifnum\pdfstrcmp{#1}{#2}<0
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@lt@T#1#2{\ifnum\pdfstrcmp{#1}{#2}>0
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forest@cmp@error#1#2{\PackageError{forest}{Comparison
+ ("<" or ">") of generic type arguments "#1" and "#2"
+ makes no sense}{Use one of argument processor instructions
+ "n", "d", "P" or "t" to change the type. Use package option
+ "debug=process" to see what's happening here.}}
+\cslet{forestmath@if@lt@_}\forest@cmp@error
+\def\forestmath@if@eq@n#1#2{\ifnum#1=#2\relax
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@eq@d#1#2{\ifdim#1=#2\relax
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@eq@P#1#2{\ifdim#1pt=#2pt
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmath@if@eq@t#1#2{\ifnum\pdfstrcmp{#1}{#2}=0
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\let\forestmath@if@eq@T\forestmath@if@eq@t
+\csdef{forestmath@if@eq@_}#1#2{%
+ \def\forestmath@tempa{#1}%
+ \def\forestmath@tempb{#2}%
+ \ifx\forestmath@tempa\forestmath@tempb
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+\def\forestmathlt#1#2{%
+ \csname forestmath@if@lt@\forestmathresulttype\endcsname{#1}{#2}%
+ \forestmathtrue
+ \forestmathfalse}
+\def\forestmathlt@#1#2#3{%
+ \csname forestmath@if@lt@#1\endcsname{#2}{#3}%
+ \forestmathtrue
+ \forestmathfalse}
+\def\forestmathgt#1#2{%
+ \csname forestmath@if@lt@\forestmathresulttype\endcsname{#2}{#1}%
+ \forestmathtrue
+ \forestmathfalse}
+\def\forestmathgt@#1#2#3{%
+ \csname forestmath@if@lt@#1\endcsname{#3}{#2}%
+ \forestmathtrue
+ \forestmathfalse}
+\def\forestmatheq#1#2{%
+ \csname forestmath@if@eq@\forestmathresulttype\endcsname{#1}{#2}%
+ \forestmathtrue
+ \forestmathfalse}
+\def\forestmatheq@#1#2#3{%
+ \csname forestmath@if@eq@#1\endcsname{#2}{#3}%
+ \forestmathtrue
+ \forestmathfalse}
+\def\forestmathmin{\forestmath@minmax{min}{\forestmathresulttype}}
+\def\forestmathmax{\forestmath@minmax{max}{\forestmathresulttype}}
+\def\forestmathmin@{\forestmath@minmax{min}}
+\def\forestmathmax@{\forestmath@minmax{max}}
+\def\forestmath@minmax#1#2#3#4{% #1=min/max, #2=type, #3,#4=args
+ \edef\forestmath@tempa{#3}%
+ \edef\forestmath@tempb{#4}%
+ \if\relax\detokenize\expandafter{\forestmath@tempa}\relax
+ \forestmath@minmax@one{#1}{#2}\forestmath@tempb
+ \else
+ \if\relax\detokenize\expandafter{\forestmath@tempb}\relax
+ \forestmath@minmax@one{#1}{#2}\forestmath@tempa
+ \else
+ \csname forestmath@#1\endcsname{#2}%
+ \fi
+ \fi
+}
+\def\forestmath@minmax@one#1#2#3{% #1=min/max, #2=type, #3 = the (possibly) non-empty arg
+ \ifcsname forestmath@#1@one@#2\endcsname
+ \csname forestmath@#1@one@#2\endcsname#3%
+ \else
+ \let\forestmathresult#3%
+ \fi
+}
+\def\forestmath@min@one@t#1{\let\forestmathresult\forest@empty}
+\def\forestmath@max@one@t#1{\let\forestmathresult#1}
+\def\forestmath@min@one@T#1{\let\forestmathresult#1}
+\def\forestmath@max@one@T#1{\let\forestmathresult\forest@empty}
+
+\def\forestmath@min#1{% #1 = type
+ \csname forestmath@if@lt@#1\endcsname\forestmath@tempa\forestmath@tempb
+ {\let\forestmathresult\forestmath@tempa}%
+ {\let\forestmathresult\forestmath@tempb}%
+}
+\def\forestmath@max#1{% #1 = type
+ \csname forestmath@if@lt@#1\endcsname\forestmath@tempa\forestmath@tempb
+ {\let\forestmathresult\forestmath@tempb}%
+ {\let\forestmathresult\forestmath@tempa}%
+}
\def\forest@sort#1#2#3#4#5{%
\let\forest@sort@cmp#1\relax
\let\forest@sort@let#2\relax
@@ -869,51 +1648,37 @@
\bracket@afterthought={}%
}
% full expansion expands precisely to the value
-\def\forestov#1{\expandafter\expandafter\expandafter\expandonce
- \pgfkeysvalueof{/forest/@node/\forest@cn/#1}}
+\def\forestov#1{\expandafter\expandonce\csname fRsT\forest@cn/#1\endcsname}
% full expansion expands all the way
-\def\forestove#1{\pgfkeysvalueof{/forest/@node/\forest@cn/#1}}
+\def\forestove#1{\csname fRsT\forest@cn/#1\endcsname}
% full expansion expands to the cs holding the value
-\def\forestom#1{\expandafter\expandonce\expandafter{\pgfkeysvalueof{/forest/@node/\forest@cn/#1}}}
-\def\forestoget#1#2{\pgfkeysgetvalue{/forest/@node/\forest@cn/#1}{#2}}
-\def\forestolet#1#2{\pgfkeyslet{/forest/@node/\forest@cn/#1}{#2}}
-\def\forestocslet#1#2{%
- \edef\forest@marshal{%
- \noexpand\pgfkeyslet{/forest/@node/\forest@cn/#1}{\expandonce{\csname#2\endcsname}}%
- }\forest@marshal
-}
-\def\forestoset#1#2{\pgfkeyssetvalue{/forest/@node/\forest@cn/#1}{#2}}
-\def\forestoeset#1#2{%
- \edef\forest@option@temp{%
- \noexpand\pgfkeyssetvalue{/forest/@node/\forest@cn/#1}{#2}%
- }\forest@option@temp
-}
+\def\forestom#1{\expandonce{\csname fRsT\forest@cn/#1\endcsname}}
+\def\forestoget#1#2{\expandafter\let\expandafter#2\csname fRsT\forest@cn/#1\endcsname}
+\def\forestolet#1#2{\expandafter\let\csname fRsT\forest@cn/#1\endcsname#2}
+\def\forestoset#1#2{\expandafter\edef\csname fRsT\forest@cn/#1\endcsname{\unexpanded{#2}}}
+\def\forestoeset#1%#2
+ {\expandafter\edef\csname fRsT\forest@cn/#1\endcsname
+ %{#2}
+ }
\def\forestoappto#1#2{%
\forestoeset{#1}{\forestov{#1}\unexpanded{#2}}%
}
-\def\forestoifdefined#1#2#3{%
- \pgfkeysifdefined{/forest/@node/\forest@cn/#1}{#2}{#3}%
+\def\forestoifdefined#1%#2#3
+{%
+ \ifcsdef{fRsT\forest@cn/#1}%{#2}{#3}%
}
\let\forestoption\forestov
\let\foresteoption\forestove
-\def\forestOv#1#2{\expandafter\expandafter\expandafter\expandonce
- \pgfkeysvalueof{/forest/@node/#1/#2}}
-\def\forestOve#1#2{\pgfkeysvalueof{/forest/@node/#1/#2}}
+\def\forestOv#1#2{\expandafter\expandonce\csname fRsT#1/#2\endcsname}
+\def\forestOve#1#2{\csname fRsT#1/#2\endcsname}
% full expansion expands to the cs holding the value
-\def\forestOm#1#2{\expandafter\expandonce\expandafter{\pgfkeysvalueof{/forest/@node/#1/#2}}}
-\def\forestOget#1#2#3{\pgfkeysgetvalue{/forest/@node/#1/#2}{#3}}
-\def\forestOget#1#2#3{\pgfkeysgetvalue{/forest/@node/#1/#2}{#3}}
-\def\forestOlet#1#2#3{\pgfkeyslet{/forest/@node/#1/#2}{#3}}
-\def\forestOcslet#1#2#3{%
- \edef\forest@marshal{%
- \noexpand\pgfkeyslet{/forest/@node/#1/#2}{\expandonce{\csname#3\endcsname}}%
- }\forest@marshal
-}
-\def\forestOset#1#2#3{\pgfkeyssetvalue{/forest/@node/#1/#2}{#3}}
-\def\forestOeset#1#2#3{%
- \edef\forestoption@temp{%
- \noexpand\pgfkeyssetvalue{/forest/@node/#1/#2}{#3}%
- }\forestoption@temp
+\def\forestOm#1#2{\expandonce{\csname fRsT#1/#2\endcsname}}
+\def\forestOget#1#2#3{\expandafter\let\expandafter#3\csname fRsT#1/#2\endcsname}
+\def\forestOlet#1#2#3{\expandafter\let\csname fRsT#1/#2\endcsname#3}
+\def\forestOset#1#2#3{\expandafter\edef\csname fRsT#1/#2\endcsname{\unexpanded{#3}}}
+\def\forestOeset#1#2%#3
+{\expandafter\edef\csname fRsT#1/#2\endcsname
+ % {#3}
}
\def\forestOappto#1#2#3{%
\forestOeset{#1}{#2}{\forestOv{#1}{#2}\unexpanded{#3}}%
@@ -927,8 +1692,9 @@
\def\forestOepreto#1#2#3{%
\forestOeset{#1}{#2}{#3\forestOv{#1}{#2}}%
}
-\def\forestOifdefined#1#2#3#4{%
- \pgfkeysifdefined{/forest/@node/#1/#2}{#3}{#4}%
+\def\forestOifdefined#1#2%#3#4
+{%
+ \ifcsdef{fRsT#1/#2}%{#3}{#4}%
}
\def\forestOletO#1#2#3#4{% option #2 of node #1 <-- option #4 of node #3
\forestOget{#3}{#4}\forestoption@temp
@@ -942,34 +1708,57 @@
\def\forestoleto#1#2{%
\forestoget{#2}\forestoption@temp
\forestolet{#1}\forestoption@temp}
+\def\forestRNOget#1#2{% #1=rn!option, #2 = receiving cs
+ \pgfutil@in@{.}{#1}%
+ \ifpgfutil@in@
+ \forestRNOget@rn#2#1\forest@END
+ \else
+ \forestoget{#1}#2%
+ \fi
+}
+\def\forestRNOget@rn#1#2.#3\forest@END{%
+ \forest@forthis{%
+ \forest@nameandgo{#2}%
+ \forestoget{#3}#1%
+ }%
+}
+\def\forestRNO@getvalueandtype#1#2#3{% #1=rn.option, #2,#3 = receiving css
+ \pgfutil@in@{.}{#1}%
+ \ifpgfutil@in@
+ \forestRNO@getvalueandtype@rn#2#3#1\forest@END
+ \else
+ \forestoget{#1}#2%
+ \pgfkeysgetvalue{/forest/#1/@type}#3%
+ \fi
+}
+\def\forestRNO@getvalueandtype@rn#1#2#3.#4\forest@END{%
+ % #1,#2=receiving css, #3=relative node name, #4=option name
+ \forest@forthis{%
+ \forest@nameandgo{#3}%
+ \forestoget{#4}#1%
+ }%
+ \pgfkeysgetvalue{/forest/#4/@type}#2%
+}
% full expansion expands precisely to the value
-\def\forestrv#1{\expandafter\expandafter\expandafter\expandonce
- \pgfkeysvalueof{/forest/@node/register/#1}}
+\def\forestrv#1{\expandafter\expandonce\csname fRsT/#1\endcsname}
% full expansion expands all the way
-\def\forestrve#1{\pgfkeysvalueof{/forest/@node/register/#1}}
+\def\forestrve#1{\csname fRsT/#1\endcsname}
% 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\forestrm#1{\expandonce{\csname fRsT/#1\endcsname}}
+\def\forestrget#1#2{\expandafter\let\expandafter#2\csname fRsT/#1\endcsname}
+\def\forestrlet#1#2{\expandafter\let\csname fRsT/#1\endcsname#2}
+\def\forestrset#1#2{\expandafter\edef\csname fRsT/#1\endcsname{\unexpanded{#2}}}
+\def\forestreset#1%#2
+ {\expandafter\edef\csname fRsT/#1\endcsname}%{#2}
\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\forestrifdefined#1%#2#3
+{%
+ \ifcsdef{fRsT/#1}%{#2}{#3}%
}
\def\forestregister#1{\forestrv{#1}}
\def\foresteregister#1{\forestrve{#1}}
@@ -1498,7 +2287,12 @@
}
\NewDocumentCommand\forestdebugtypeouttrees{o}{%
\forestdebug@typeouttrees\forest@temp
- \typeout{\IfValueTF{#1}{#1: }{}\forest@temp}%
+ \typeout{%
+ \forestdebugtypeouttreesprefix
+ \IfValueTF{#1}{#1: }{}%
+ \detokenize\expandafter{\forest@temp}%
+ \forestdebugtypeouttreessuffix
+ }%
}
\def\forestdebug@typeouttrees#1{% #1 = cs to store the result
\begingroup
@@ -1514,12 +2308,12 @@
\expandafter\endgroup
\expandafter\edef\expandafter\forest@cn\expandafter{\forest@cn}%
\forestdebug@typeouttree@build
- \appto\forest@temp@message{\space}%
+ \appto\forest@temp@message{ }%
}%
}%
\repeat
\expandafter\endgroup
- \expandafter\edef\expandafter#1\expandafter{\forest@temp@message}%
+ \expandafter\def\expandafter#1\expandafter{\forest@temp@message}%
}
\def\forestdebug@typeouttrees@findroot{%
\let\forestdebug@typeouttrees@next\relax
@@ -1546,9 +2340,9 @@
\typeout{\IfValueTF{#1}{#1: }{}\forest@temp}%
}
\def\forestdebug@typeouttree@build{%
- \eappto\forest@temp@message{[\forest@cn%]
+ \eappto\forest@temp@message{[\forestdebugtypeouttreenodeinfo%]
\ifcsdef{forestdebug@typeouttree@used@\forest@cn}{*}{}%
- }%
+ }%
\ifcsdef{forestdebug@typeouttree@used@\forest@cn}{}{%
\csdef{forestdebug@typeouttree@used@\forest@cn}{}%
\forest@node@foreachchild{\forestdebug@typeouttree@build}%
@@ -1556,6 +2350,9 @@
\eappto\forest@temp@message{%[
]}%
}
+\def\forestdebugtypeouttreenodeinfo{\forest@cn}
+\def\forestdebugtypeouttreesprefix{}
+\def\forestdebugtypeouttreessuffix{}
\def\forest@declarehandler#1#2#3{%#1=handler for specific type,#2=option name,#3=default value
\pgfkeyssetvalue{/forest/#2}{#3}%
\appto\forest@node@init{\forestoinit{#2}}%
@@ -1635,6 +2432,7 @@
\pgfkeyssetvalue{#1/option@name}{#3}%
\pgfkeyssetvalue{#1+/option@name}{#3}%
\pgfkeyssetvalue{#2/+#3/option@name}{#3}%
+ \pgfkeyslet{#1/@type}\forestmathtype@generic % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@toks{##1}{#3}}%
}
\def\forest@declareautowrappedtoks@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix
@@ -1664,25 +2462,44 @@
\pgfkeysalso{##3}%
\fi
},
+ #2/if #3</.code n args={3}{%
+ \forestoget{#3}\forest@temp@option@value
+ \ifdim\forest@temp@option@value>##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
+ #2/if #3>/.code n args={3}{%
+ \forestoget{#3}\forest@temp@option@value
+ \ifdim\forest@temp@option@value<##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
#2/where #3/.style n args={3}{for tree={#2/if #3={##1}{##2}{##3}}},
+ #2/where #3</.style n args={3}{for tree={#2/if #3<={##1}{##2}{##3}}},
+ #2/where #3>/.style n args={3}{for tree={#2/if #3>={##1}{##2}{##3}}},
}%
+ \pgfkeyslet{#1/@type}\forestmathtype@dimen % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@dimen{##1}{#3}}%
}
\def\forest@declaredimen@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname
\forest@declarereadonlydimen@handler{#1}{#2}{#3}{#4}%
\pgfkeysalso{%
#1/.code={%
- \pgfmathsetlengthmacro\forest@temp{##1}%
+ \forestmathsetlengthmacro\forest@temp{##1}%
\forestOlet{\forest@setter@node}{#3}\forest@temp
},
#1+/.code={%
- \pgfmathsetlengthmacro\forest@temp{##1}%
+ \forestmathsetlengthmacro\forest@temp{##1}%
\pgfutil@tempdima=\forestove{#3}
\advance\pgfutil@tempdima\forest@temp\relax
\forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}%
},
#1-/.code={%
- \pgfmathsetlengthmacro\forest@temp{##1}%
+ \forestmathsetlengthmacro\forest@temp{##1}%
\pgfutil@tempdima=\forestove{#3}
\advance\pgfutil@tempdima-\forest@temp\relax
\forestOeset{\forest@setter@node}{#3}{\the\pgfutil@tempdima}%
@@ -1739,37 +2556,56 @@
\pgfkeysalso{##3}%
\fi
},
+ #2/if #3</.code n args={3}{%
+ \forestoget{#3}\forest@temp@option@value
+ \ifnum\forest@temp@option@value>##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
+ #2/if #3>/.code n args={3}{%
+ \forestoget{#3}\forest@temp@option@value
+ \ifnum\forest@temp@option@value<##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
#2/where #3/.style n args={3}{for tree={#2/if #3={##1}{##2}{##3}}},
+ #2/where #3</.style n args={3}{for tree={#2/if #3<={##1}{##2}{##3}}},
+ #2/where #3>/.style n args={3}{for tree={#2/if #3>={##1}{##2}{##3}}},
}%
+ \pgfkeyslet{#1/@type}\forestmathtype@count % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@count{##1}{#3}}%
}
\def\forest@declarecount@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname
\forest@declarereadonlycount@handler{#1}{#2}{#3}{#4}%
\pgfkeysalso{
#1/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\forestOlet{\forest@setter@node}{#3}\forest@temp
},
#1+/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestove{#3}\relax
\advance\c@pgf@counta\forest@temp\relax
\forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}%
},
#1-/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestove{#3}\relax
\advance\c@pgf@counta-\forest@temp\relax
\forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}%
},
#1*/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestove{#3}\relax
\multiply\c@pgf@counta\forest@temp\relax
\forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}%
},
#1:/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestove{#3}\relax
\divide\c@pgf@counta\forest@temp\relax
\forestOeset{\forest@setter@node}{#3}{\the\c@pgf@counta}%
@@ -1813,30 +2649,27 @@
\def\forest@declareboolean@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname
\pgfkeysalso{%
#1/.code={%
- \ifstrequal{##1}{1}{%
- \forestOset{\forest@setter@node}{#3}{1}%
+ \forestmath@if{##1}{%
+ \def\forest@temp{1}%
}{%
- \ifstrequal{##1}{0}{%
- \forestOset{\forest@setter@node}{#3}{0}%
- }{%
- \pgfmathifthenelse{##1}{1}{0}%
- \forestOlet{\forest@setter@node}{#3}\pgfmathresult
- }%
+ \def\forest@temp{0}%
}%
+ \forestOlet{\forest@setter@node}{#3}\forest@temp
},
#1/.default=1,
#2/not #3/.code={\forestOset{\forest@setter@node}{#3}{0}},
#2/if #3/.code 2 args={%
\forestoget{#3}\forest@temp@option@value
- \ifnum\forest@temp@option@value=1
- \pgfkeysalso{##1}%
- \else
+ \ifnum\forest@temp@option@value=0
\pgfkeysalso{##2}%
+ \else
+ \pgfkeysalso{##1}%
\fi
},
#2/where #3/.style 2 args={for tree={#2/if #3={##1}{##2}}}
}%
\pgfkeyssetvalue{#1/option@name}{#3}%
+ \pgfkeyslet{#1/@type}\forestmathtype@count % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@attribute@count{##1}{#3}}%
}
\forestset{
@@ -1850,31 +2683,35 @@
\forest@declarehandler\forest@declarekeylist@handler{#1}{#2}%
},
declare readonly dimen/.code 2 args={%
- \pgfmathsetlengthmacro\forest@temp{#2}%
+ \forestmathsetlengthmacro\forest@temp{#2}%
\edef\forest@marshal{%
\unexpanded{\forest@declarehandler\forest@declarereadonlydimen@handler{#1}}{\forest@temp}%
}\forest@marshal
},
declare dimen/.code 2 args={%
- \pgfmathsetlengthmacro\forest@temp{#2}%
+ \forestmathsetlengthmacro\forest@temp{#2}%
\edef\forest@marshal{%
\unexpanded{\forest@declarehandler\forest@declaredimen@handler{#1}}{\forest@temp}%
}\forest@marshal
},
declare readonly count/.code 2 args={%
- \pgfmathtruncatemacro\forest@temp{#2}%
+ \forestmathtruncatemacro\forest@temp{#2}%
\edef\forest@marshal{%
\unexpanded{\forest@declarehandler\forest@declarereadonlycount@handler{#1}}{\forest@temp}%
}\forest@marshal
},
declare count/.code 2 args={%
- \pgfmathtruncatemacro\forest@temp{#2}%
+ \forestmathtruncatemacro\forest@temp{#2}%
\edef\forest@marshal{%
\unexpanded{\forest@declarehandler\forest@declarecount@handler{#1}}{\forest@temp}%
}\forest@marshal
},
declare boolean/.code 2 args={%
- \pgfmathtruncatemacro\forest@temp{#2}%
+ \forestmath@if{#2}{%
+ \def\forest@temp{1}%
+ }{%
+ \def\forest@temp{0}%
+ }%
\edef\forest@marshal{%
\unexpanded{\forest@declarehandler\forest@declareboolean@handler{#1}}{\forest@temp}%
}\forest@marshal
@@ -1898,17 +2735,22 @@
\pgfkeysalso{\forest@handlers@wrap@currentpath/.expand once=\forest@wrapped@value}%
},
/handlers/.option/.code={%
- \edef\forest@marshal{%
- \noexpand\pgfkeysalso{\pgfkeyscurrentpath={\forestoption{#1}}}%
- }\forest@marshal
+ \edef\forest@temp{\pgfkeyscurrentpath}%
+ \expandafter\forest@handlers@option\expandafter{\forest@temp}{#1}%
},
+}
+\def\forest@handlers@option#1#2{%#1=pgfkeyscurrentpath,#2=relative node name
+ \forestRNOget{#2}\forest@temp
+ \pgfkeysalso{#1/.expand once={\forest@temp}}%
+}%
+\forestset{
/handlers/.register/.code={%
\edef\forest@marshal{%
\noexpand\pgfkeysalso{\pgfkeyscurrentpath={\forestregister{#1}}}%
}\forest@marshal
},
/handlers/.wrap pgfmath arg/.code 2 args={%
- \pgfmathparse{#2}\let\forest@wrap@arg@i\pgfmathresult
+ \forestmathparse{#2}\let\forest@wrap@arg@i\forestmathresult
\edef\forest@wrap@args{{\expandonce\forest@wrap@arg@i}}%
\def\forest@wrap@code##1{#1}%
% here we don't call \forest@wrap@pgfmath@args@@@wrapandpasson, as compat-2.0.2-wrappgfmathargs changes that to achieve the old, confusing state of affairs, which *didn't* apply at *1*-arg pgfmath wrapping
@@ -1916,8 +2758,8 @@
\expandafter\pgfkeysalso\expandafter{\expandafter\pgfkeyscurrentpath\expandafter=\expandafter{\the\forest@temp@toks}}%
},
/handlers/.wrap 2 pgfmath args/.code n args={3}{%
- \pgfmathparse{#2}\let\forest@wrap@arg@i\pgfmathresult
- \pgfmathparse{#3}\let\forest@wrap@arg@ii\pgfmathresult
+ \forestmathparse{#2}\let\forest@wrap@arg@i\forestmathresult
+ \forestmathparse{#3}\let\forest@wrap@arg@ii\forestmathresult
\edef\forest@wrap@args{{\expandonce\forest@wrap@arg@i}{\expandonce\forest@wrap@arg@ii}}%
\def\forest@wrap@code##1##2{#1}%
\forest@wrap@pgfmath@args@@@wrapandpasson
@@ -1940,19 +2782,16 @@
/handlers/.wrap 8 pgfmath args/.code n args={9}{%
\forest@wrap@n@pgfmath@args{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}{8}%
\forest@wrap@n@pgfmath@do{#1}{8}},
- /handlers/.process args/.code={%
- \forest@processargs#1\forest@eov\forest@END
- },
}
\def\forest@wrap@n@pgfmath@args#1#2#3#4#5#6#7#8#9{%
- \pgfmathparse{#1}\let\forest@wrap@arg@i\pgfmathresult
- \ifnum#9>1 \pgfmathparse{#2}\let\forest@wrap@arg@ii\pgfmathresult\fi
- \ifnum#9>2 \pgfmathparse{#3}\let\forest@wrap@arg@iii\pgfmathresult\fi
- \ifnum#9>3 \pgfmathparse{#4}\let\forest@wrap@arg@iv\pgfmathresult\fi
- \ifnum#9>4 \pgfmathparse{#5}\let\forest@wrap@arg@v\pgfmathresult\fi
- \ifnum#9>5 \pgfmathparse{#6}\let\forest@wrap@arg@vi\pgfmathresult\fi
- \ifnum#9>6 \pgfmathparse{#7}\let\forest@wrap@arg@vii\pgfmathresult\fi
- \ifnum#9>7 \pgfmathparse{#8}\let\forest@wrap@arg@viii\pgfmathresult\fi
+ \forestmathparse{#1}\let\forest@wrap@arg@i\forestmathresult
+ \ifnum#9>1 \forestmathparse{#2}\let\forest@wrap@arg@ii\forestmathresult\fi
+ \ifnum#9>2 \forestmathparse{#3}\let\forest@wrap@arg@iii\forestmathresult\fi
+ \ifnum#9>3 \forestmathparse{#4}\let\forest@wrap@arg@iv\forestmathresult\fi
+ \ifnum#9>4 \forestmathparse{#5}\let\forest@wrap@arg@v\forestmathresult\fi
+ \ifnum#9>5 \forestmathparse{#6}\let\forest@wrap@arg@vi\forestmathresult\fi
+ \ifnum#9>6 \forestmathparse{#7}\let\forest@wrap@arg@vii\forestmathresult\fi
+ \ifnum#9>7 \forestmathparse{#8}\let\forest@wrap@arg@viii\forestmathresult\fi
\edef\forest@wrap@args{%
{\expandonce\forest@wrap@arg@i}
\ifnum#9>1 {\expandonce\forest@wrap@arg@ii}\fi
@@ -1985,117 +2824,498 @@
\expandafter\pgfkeyscurrentpath\expandafter=\expandafter{%
\the\forest@temp@toks}}%
}
-\newtoks\forest@processargs@result
-\newtoks\forest@processargs@current
-\newif\ifforest@processargs@append
-\def\forest@eov{\forest@eov}
-\def\forest@processargs#1#2\forest@END{% #1 = processing instructions, #2 = args
- \forest@processargs@result{}%
- \forest@processargs@current{}%
- \forest@processargs@appendfalse
- \forest@processargs@getins#1.\forest@END#2\forest@END
-}
-\def\forest@processargs@maybeappend{%
- \ifforest@processargs@append
- \eapptotoks\forest@processargs@result{{\the\forest@processargs@current}}%
- \forest@processargs@current{}%
- \fi
-}
-\def\forest@processargs@getins#1#2\forest@END#3\forest@END{% #1 = first instruction, #2 = rest of instructions, #3 = args
- \csname forest@processargs@ins@#1\endcsname#2\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@.}\forest@END#1\forest@END{%
- \forest@processargs@maybeappend
- \forest@processargs@appremainingargs#1\forest@END
-}
-\def\forest@processargs@appremainingargs#1#2\forest@END{%
- \edef\forest@temp{\unexpanded{#1}}%
- \ifx\forest@temp\forest@eov
- \let\forest@processargs@next\forest@processargs@done
+\def\forest@process@catregime{} % filled by processor defs
+\forest@newarray\forest@process@left@ % processed args
+\forest@newarray\forest@process@right@ % unprocessed args
+\forest@newarray\forest@process@saved@ % used by instructions |S| and |U|
+\let\forest@process@savedtype\forestmathtype@none
+\forest@newglobalarray\forest@process@result@
+\newif\ifforest@process@returnarray@
+\def\forest@process#1#2#{% #1 = true/false (should we return an array?)
+ % #2 = processing instructions (if non-empty),
+ % (initial) args follow
+ \ifblank{#2}{\forest@process@a{#1}}{\forest@process@a{#1}{#2}}%
+}
+\Inline\def\forest@process@a#1#2{%
+ \begingroup
+ \forest@process@left@clear
+ \forest@process@right@clear
+ \forest@process@saved@clear
+ \let\forest@process@savedtype\forestmathtype@generic
+ \ExpandIfT{forestdebug}{%
+ \edef\forest@process@debug@args{\unexpanded{#2}}%
+ \typeout{[forest .process] Start "\unexpanded{#2}"}%
+ }%
+ \csname forest@process@returnarray@#1\endcsname
+ \def\forest@topextend@next{%
+ \forest@process@catregime
+ \endlinechar=-1
+ \scantokens{#2}%
+ \forest@process@finish
+ }%
+ \forest@process@right@topextend
+}
+\pgfkeys{%
+ /handlers/.process/.code={%
+ \forest@process{true}#1\forest@eov
+ \edef\forest@marshal{%
+ \noexpand\pgfkeysalso{\noexpand\pgfkeyscurrentpath=\forest@process@result@values}%
+ }\forest@marshal
+ },
+ /forest/copy command key={/handlers/.process}{/handlers/.process args},
+}
+\def\forest@process@finish{%
+ \ifforest@process@returnarray@
+ \forest@process@finish@array
+ \global\let\forest@process@result@type\forest@result@type@array
\else
- \apptotoks\forest@processargs@result{{#1}}%
- \let\forest@processargs@next\forest@processargs@appremainingargs
- \fi
- \forest@processargs@next#2\forest@END
-}
-\def\forest@processargs@done#1\forest@END{%
- \pgfkeysalso{\pgfkeyscurrentpath/.expanded=\the\forest@processargs@result}%
-}
-\csdef{forest@processargs@ins@_}#1\forest@END#2#3\forest@END{% no processing
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \forest@processargs@current{#2}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@x}#1\forest@END#2#3\forest@END{% expand
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \etotoks\forest@processargs@current{#2}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@o}#1\forest@END#2#3\forest@END{% expand once
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \expandafter\forest@processargs@current\expandafter{#2}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@O}#1\forest@END#2#3\forest@END{% option
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \etotoks\forest@processargs@current{\forestoption{#2}}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@R}#1\forest@END#2#3\forest@END{% register
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \etotoks\forest@processargs@current{\forestregister{#2}}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@P}#1\forest@END#2#3\forest@END{% pgfmath expression
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \pgfmathparse{#2}%
- \expandafter\forest@processargs@current\expandafter{\pgfmathresult}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
-}
-\csdef{forest@processargs@ins@+}#1\forest@END#2\forest@END{% join processors
- \forest@processargs@appendfalse
+ \forest@process@finish@single
+ \fi
+ \ifforestdebugprocess\forest@process@debug@end\fi
+ \endgroup
+}
+\def\forest@process@finish@single{%
+ \edef\forest@temp{forest@process@finish@single@%
+ \the\numexpr\forest@process@left@N-\forest@process@left@M\relax
+ \the\numexpr\forest@process@right@N-\forest@process@right@M\relax
+ }%
+ \ifcsname\forest@temp\endcsname
+ \csname\forest@temp\endcsname
+ \global\let\forest@process@result\forest@temp
+ \else
+ \forest@process@lengtherror
+ \fi
+ \global\let\forest@process@result@type\forestmathresulttype
+}
+\csdef{forest@process@finish@single@10}{\forest@process@left@toppop\forest@temp}
+\csdef{forest@process@finish@single@01}{\forest@process@right@toppop\forest@temp}
+\def\forest@process@finish@array{%
+ \forest@process@result@clear
+ \forest@temp@count\forest@process@left@M\relax
+ \forest@loop
+ \ifnum\forest@temp@count<\forest@process@left@N\relax
+ \forest@process@left@get@{\the\forest@temp@count}\forest@temp
+ \forest@process@result@letappend\forest@temp
+ \advance\forest@temp@count1
+ \forest@repeat
+ \forest@temp@count\forest@process@right@M\relax
+ \forest@loop
+ \ifnum\forest@temp@count<\forest@process@right@N\relax
+ \forest@process@right@get@{\the\forest@temp@count}\forest@temp
+ \forest@process@result@letappend\forest@temp
+ \advance\forest@temp@count1
+ \forest@repeat
+}
+\ifforestdebug
+ \let\forest@process@d\forest@process@b
+ \def\forest@process@b#1\forest@eov{% save and print initial arguments
+ \edef\forest@process@debug@args{\unexpanded{#1}}%
+ \typeout{[forest .process] Start "\unexpanded{#1}"}%
+ \forest@process@d#1\forest@eov
+ }
+\fi
+\def\forest@process@debug@end{%
+ \typeout{[forest .process] \space\space\space End "\expandonce{\forest@process@debug@args}" -> "\forest@process@left@values\forest@process@right@values"}%
+}
+\def\forest@process@lengtherror{%
+ \PackageError{forest}{%
+ The ".process" expression was expected to evaluate to a single argument,
+ but the result is \the\forest@process@result@N
+ \space items long.}{}%
+}
+\def\forest@def@processor#1{%
+ {%
+ \def\forest@dp@double##1{%
+ \gdef\forest@global@temp{\forest@def@processor@{#1}{##1}}%
+ }%
+ \let\\\forest@dp@double
+ \catcode`#1=13
+ \scantokens{\\#1}%
+ }%
+ \forest@global@temp
+}
+\def\forest@def@processor@#1#2{%
+ % #1 = instruction char (normal catcode), #2 = instruction char (active)
+ % #3 = default n (optional numeric arg, which precedes any other args;
+ % if the default is empty, this means no optional n)
+ % #4 = args spec,
+ % #5 = code
+ \eappto\forest@process@catregime{%
+ \unexpanded{\let#2}\expandonce{\csname forest@processor@#1\endcsname}%
+ \unexpanded{\catcode`#1=13 }%
+ }%
+ \def\forest@def@processor@inschar{#1}%
+ \forest@def@processor@@
+}
+\def\forest@def@processor@@#1{%
+ \ifstrempty{#1}{%
+ \forest@def@processor@@non
+ }{%
+ \def\forest@def@processor@@default@n{#1}%
+ \forest@def@processor@@n
+ }%
+}
+\def\forest@def@processor@@non#1#2{% #1=args spec, #2=code
+ \csedef{forest@processor@\forest@def@processor@inschar}#1{%
+ \relax %% we need this (see above)
+ \unexpanded{#2}%
+ \expandafter\forest@def@processor@debuginfo\expandafter{%
+ \expandafter"\forest@def@processor@inschar"\ifstrempty{#1}{}{(#1)}}%
+ \ignorespaces
+ }%
+}
+\def\forest@def@processor@@n{%
+ \@ifnextchar*%
+ {\forest@temptrue\forest@def@processor@@n@}%
+ {\forest@tempfalse\forest@def@processor@@n@@}%
+}
+\def\forest@def@processor@@n@*{\forest@def@processor@@n@@}
+\def\forest@def@processor@@n@@#1#2{% #1=args spec, #2=code
+ \csedef{forest@processor@\forest@def@processor@inschar}{%
+ \relax %% we need this (see above)
+ \noexpand\forestprocess@get@n
+ {\forest@def@processor@@default@n}%
+ \expandonce{\csname forest@processor@\forest@def@processor@inschar @\endcsname}%
+ }%
+ \ifforest@temp
+ \csedef{forest@processor@\forest@def@processor@inschar @}{%
+ \noexpand\forest@repeat@n@times{\forest@process@n}{%
+ \expandonce{\csname forest@processor@\forest@def@processor@inschar @rep\endcsname}%
+ }%
+ }%
+ \fi
+ \edef\forest@temp{%
+ \forest@def@processor@inschar
+ \ifforest@temp\else\noexpand\the\forest@process@n\fi
+ "}%
+ \csedef{forest@processor@\forest@def@processor@inschar @\ifforest@temp rep\fi}#1{%
+ \unexpanded{#2}%
+ \expandafter\forest@def@processor@debuginfo\expandafter{%
+ \forest@temp
+ \ifstrempty{#1}{}{(#1)}}%
+ }%
+}
+\def\forest@def@processor@debuginfo#1{% #1 = instruction call
+ \ifforestdebug
+ \expandonce{\forest@processor@debuginfo@template{#1}}%
+ \fi
+}
+\def\forest@processor@debuginfo@template#1{%
+ \ifforestdebugprocess
+ \edef\forest@temp@left{\forest@process@left@values}%
+ \edef\forest@temp@right{\forest@process@right@values}%
+ \edef\forest@temp@saved{\forest@process@saved@values}%
+ \typeout{[forest .process]\space\space\space\space After #1: left="\expandonce{\forest@temp@left}", right="\expandonce{\forest@temp@right}", saved="\expandonce{\forest@temp@saved}", type=\forestmathresulttype}%
+ \fi
+}
+\newcount\forest@process@n
+\def\forestprocess@get@n#1#2{%
+ \def\forestprocess@default@n{#1}%
+ \let\forestprocess@after@get@n@#2%
+ \afterassignment\forestprocess@get@n@\forest@process@n=0%
+}
+\def\forestprocess@get@n@{%
+ \ifnum\forest@process@n=0
+ \forest@process@n\forestprocess@default@n\relax
+ \fi
+ \forestprocess@after@get@n@
+}
+\forest@def@processor{_}{1}*{}{% no processing, no type
+ \forest@process@right@bottompop\forest@temp
+ \forest@process@left@letappend\forest@temp
+}
+\forest@def@processor{n}{1}*{}{% numexpr
+ \forest@process@right@bottompop\forest@temp
+ \forest@process@left@esetappend{\number\numexpr\forest@temp}%
+ \let\forestmathresulttype\forestmathtype@count
+}
+\forest@def@processor{d}{1}*{}{% dimexpr
+ \forest@process@right@bottompop\forest@temp
+ \forest@process@left@esetappend{\the\dimexpr\forest@temp}%
+ \let\forestmathresulttype\forestmathtype@dimen
+}
+\forest@def@processor{P}{1}*{}{% pgfmath expression
+ \forest@process@right@bottompop\forest@temp
+ \pgfmathparse{\forest@temp}%
+ \forest@process@left@letappend\pgfmathresult
+ \let\forestmathresulttype\forestmathtype@unitless
+}
+\forest@def@processor{t}{1}*{}{% text
+ \forest@process@right@bottompop\forest@temp
+ \forest@process@left@letappend\forest@temp
+ \let\forestmathresulttype\forestmathtype@textasc
+}
+\forest@def@processor{-}{}{}{% toggle ascending/descending
+ \forest@process@left@toppop\forestmathresult
+ \csname forest@processor@-@\forestmathresulttype\endcsname
+ \forest@process@left@letappend\forestmathresult
+}
+\cslet{forest@processor@-@\forestmathtype@generic}\relax
+\csdef{forest@processor@-@\forestmathtype@count}{%
+ \forestmathadd{\forestmathzero}{-\forestmathresult}}
+\csletcs{forest@processor@-@\forestmathtype@dimen}
+ {forest@processor@-@\forestmathtype@count}
+\csletcs{forest@processor@-@\forestmathtype@unitless}
+ {forest@processor@-@\forestmathtype@count}
+\csdef{forest@processor@-@\forestmathtype@textasc}{%
+ \let\forestmathresulttype\forestmathtype@textdesc}
+\csdef{forest@processor@-@\forestmathtype@textdesc}{%
+ \let\forestmathresulttype\forestmathtype@textasc}
+
+\forest@def@processor{c}{}{}{% to lowercase
+ \forest@process@right@bottompop\forest@temp
+ \expandafter\lowercase\expandafter{\expandafter\def\expandafter\forest@temp\expandafter{\forest@temp}}%
+ \forest@process@left@letappend\forest@temp
+}
+\forest@def@processor{C}{}{}{% to uppercase
+ \forest@process@right@bottompop\forest@temp
+ \expandafter\uppercase\expandafter{\expandafter\def\expandafter\forest@temp\expandafter{\forest@temp}}%
+ \forest@process@left@letappend\forest@temp
+}
+\forest@def@processor{x}{}{}{% expand
+ \forest@process@right@bottompop\forest@temp
+ \forest@process@left@esetappend{\forest@temp}%
+ \let\forestmathresulttype\forestmathtype@generic
+}
+\forest@def@processor{o}{1}{}{% expand once (actually, \forest@count@n times)
+ \forest@process@right@bottompop\forest@temp
+ \forest@repeat@n@times{\forest@process@n}{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter\forest@temp
+ \expandafter\expandafter\expandafter{\forest@temp}%
+ }%
+ \expandafter\forest@process@left@setappend\expandafter{\forest@temp}%
+ \let\forestmathresulttype\forestmathtype@generic
+}
+\forest@def@processor{O}{1}*{}{% option
+ \forest@process@right@bottompop\forest@temp
+ \expandafter\forestRNO@getvalueandtype\expandafter{\forest@temp}\forest@tempvalue\forest@temp@type
+ \let\forestmathresulttype\forest@temp@type
+ \forest@process@left@letappend\forest@tempvalue
+}
+\forest@def@processor{R}{1}*{}{% register
+ \forest@process@right@bottompop\forest@temp
+ \forestrget{\forest@temp}\forest@tempvalue
+ \forest@process@left@letappend\forest@tempvalue
+ \pgfkeysgetvalue{/forest/\forest@temp/@type}\forest@temp@type
+ \let\forestmathresulttype\forest@temp@type
+}
+\forest@def@processor{+}{1}*{}{% join processors = pop one from result
+ \forest@process@left@toppop\forest@temp
+ \forest@process@right@letprepend\forest@temp
+}
+\forest@def@processor{u}{}{}{% ungroup: remove braces and leave in the argument list
+ \forest@process@right@bottompop\forest@temp
+ \forest@temparray@clear
+ \let\forestmathresulttype\forestmathtype@generic
+ \let\forest@topextend@next\forest@processor@u@
+ \expandafter\forest@temparray@topextend\forest@temp\forest@eov
+}
+\def\forest@processor@u@{%
+ \forest@loop
+ \ifnum\forest@temparray@N>0
+ \forest@temparray@toppop\forest@temp
+ \expandafter\forest@process@right@setprepend\expandafter{\expandafter{\forest@temp}}%
+ \forest@repeat
+}
+\def\forest@process@check@mn#1#2#3#4{%
+ % #1 = processor, #2 = given n, #3/#4 = lower/upper bound (inclusive)
+ \ifnum#3>#2\relax
+ \forest@process@check@n@error{#1}{#2}{#3<=}{<=#4}%
+ \else
+ \ifnum#4<#2\relax
+ \forest@process@check@n@error{#1}{#2}{#3<=}{<=#4}%
+ \fi
+ \fi
+}
+\def\forest@process@check@m#1#2#3{%
+ % #1 = processor, #2 = given n, #3 = lower bound (inclusive)
+ \ifnum#2<#3\relax
+ \forest@process@check@n@error{#1}{#2}{#3<=}{}%
+ \fi
+}
+\def\forest@process@check@n@error#1#2#3#4{%
+ \PackageError{forest}{'.process' instruction '#1' requires a numeric modifier #3n#4, but n="#2" was given.}{}%
+}
+\newif\ifforest@process@W
+\forest@def@processor{w}{1}{}{% consuming wrap: first test 1<=#1<=9
+ \forest@process@Wtrue
+ \forest@process@check@mn{w}{0\the\forest@process@n}{1}{9}%
+ \expandafter\forest@processor@wW@\expandafter{\the\forest@process@n}%
+}
+\forest@def@processor{W}{1}{}{% nonconsuming wrap: first test 1<=#1<=9
+ \forest@process@Wfalse
+ \forest@process@check@mn{W}{0\the\forest@process@n}{1}{9}%
+ \expandafter\forest@processor@wW@\expandafter{\the\forest@process@n}%
+}
+\def\forest@processor@wW@#1{%
+ \forest@process@left@checkindex{\forest@process@left@N-#1}%
\edef\forest@marshal{%
- \unexpanded{\forest@processargs@getins#1\forest@END}{\the\forest@processargs@current}\unexpanded{#2\forest@END}%
+ \edef\noexpand\forest@temp@args{%
+ \noexpand\forest@process@left@valuesfromrange
+ {\number\numexpr\forest@process@left@N-#1}%
+ {\the\forest@process@left@N}%
+ }%
}\forest@marshal
+ \ifforest@process@W
+ \advance\forest@process@left@N-#1\relax
+ \fi
+ \forest@process@right@bottompop\forest@temp@macrobody
+ \expandafter\forest@def@n\expandafter\forest@process@temp@macro\expandafter{\expandafter#1\expandafter}\expandafter{\forest@temp@macrobody}%
+ \expandafter\expandafter\expandafter\forest@process@left@setappend\expandafter\expandafter\expandafter{\expandafter\forest@process@temp@macro\forest@temp@args}%
+ \let\forestmathresulttype\forestmathtype@generic
+}
+\def\forest@def@n#1#2{\csname forest@def@n@#2\endcsname#1}
+\csdef{forest@def@n@1}#1{\def#1##1}
+\csdef{forest@def@n@2}#1{\def#1##1##2}
+\csdef{forest@def@n@3}#1{\def#1##1##2##3}
+\csdef{forest@def@n@4}#1{\def#1##1##2##3##4}
+\csdef{forest@def@n@5}#1{\def#1##1##2##3##4##5}
+\csdef{forest@def@n@6}#1{\def#1##1##2##3##4##5##6}
+\csdef{forest@def@n@7}#1{\def#1##1##2##3##4##5##6##7}
+\csdef{forest@def@n@8}#1{\def#1##1##2##3##4##5##6##7##8}
+\csdef{forest@def@n@9}#1{\def#1##1##2##3##4##5##6##7##8##9}
+\forest@def@processor{s}{1}{}{%
+ \forest@temptrue % delete the originals
+ \expandafter\forest@processor@save\expandafter{%
+ \the\numexpr\forest@process@left@N-\forest@process@n}}
+\forest@def@processor{S}{1}{}{%
+ \forest@tempfalse % keep the originals
+ \expandafter\forest@processor@save\expandafter{%
+ \the\numexpr\forest@process@left@N-\forest@process@n}}
+\def\forest@processor@save#1{%
+ \forest@process@left@checkindex{#1}%
+ \forest@temp@count#1
+ \forest@loop
+ \ifnum\forest@temp@count<\forest@process@left@N\relax
+ \forest@process@left@get@{\the\forest@temp@count}\forest@temp
+ \forest@process@saved@letappend\forest@temp
+ \advance\forest@temp@count+1
+ \forest@repeat
+ \let\forest@process@savedtype\forestmathresulttype
+ \ifforest@temp
+ \forest@process@left@N=#1
+ \fi
+}
+\forest@def@processor{l}{0}{}{%
+ \forest@temptrue
+ \forest@processor@U@@
+}
+\forest@def@processor{L}{0}{}{%
+ \forest@tempfalse
+ \forest@processor@U@@
+}
+
+\def\forest@processor@U@@{%
+ \ifnum\forest@process@n=0
+ \forest@process@n\forest@process@saved@N\relax
+ \fi
+ \expandafter\forest@processor@U@@@\expandafter{%
+ \the\numexpr\forest@process@saved@N-\forest@temp@count}%
}
-\csdef{forest@processargs@ins@r}#1\forest@END#2#3\forest@END{% reverse keylist
- % #1 = rest of ins, #2 = first arg, #3 = rest of args
- \forest@processargs@maybeappend
- \forest@processargs@current{}%
- \pgfqkeys{/forest}{split={#2}{,}{reverse@keylist}}%
- \forest@processargs@appendtrue
- \forest@processargs@getins#1\forest@END#3\forest@END
+\def\forest@processor@U@@@#1{%
+ \forest@temp@count#1
+ \forest@loop
+ \ifnum\forest@temp@count<\forest@process@saved@N\relax
+ \forest@process@saved@get@{\the\forest@temp@count}\forest@temp
+ \forest@process@left@letappend\forest@temp
+ \advance\forest@temp@count1
+ \forest@repeat
+ \let\forestmathresulttype\forest@process@savedtype
+ \ifforest@temp
+ \let\forest@process@savedtype\forest@result@type@any
+ \forest@process@saved@N#1
+ \fi
+}
+\forest@def@processor{&}{2}{}{% and
+ \def\forest@tempa{1}%
+ \forest@repeat@n@times{\forest@process@n}{%
+ \forest@process@left@bottompop\forest@tempb
+ \edef\forest@tempa{\ifnum10<\forest@tempa\forest@tempb\space 1\else0\fi}%
+ }%
+ \forest@process@left@esetappend{\forest@tempa}%
+ \let\forestmathresulttype\forestmathtype@count
+}
+\forest@def@processor{|}{2}{}{% or
+ \def\forest@tempa{0}%
+ \forest@repeat@n@times{\forest@process@n}{%
+ \forest@process@left@bottompop\forest@tempb
+ \edef\forest@tempa{\ifnum0=\forest@tempa\forest@tempb\space 0\else1\fi}%
+ }%
+ \forest@process@left@esetappend{\forest@tempa}%
+ \let\forestmathresulttype\forestmathtype@count
+}
+\forest@def@processor{!}{}{}{% not
+ \forest@process@left@toppop\forest@temp
+ \forest@process@left@esetappend{\ifnum0=\forest@temp\space 1\else0\fi}%
+ \let\forestmathresulttype\forestmathtype@count
+}
+\forest@def@processor{?}{}{}{%
+ \forest@process@left@toppop\forest@temp
+ \forest@process@right@bottompop\forest@tempa
+ \forest@process@right@bottompop\forest@tempb
+ \ifnum\forest@temp=0
+ \forest@process@right@letprepend\forest@tempb
+ \else
+ \forest@process@right@letprepend\forest@tempa
+ \fi
+ \let\forestmathresulttype\forestmathtype@generic
+}
+\forest@def@processor{=}{}{}{%
+ \forest@process@left@toppop\forest@tempa
+ \forest@process@left@toppop\forest@tempb
+ \forest@process@left@esetappend{\ifx\forest@tempa\forest@tempb 1\else0\fi}%
+ \let\forestmathresulttype\forestmathtype@count
+}
+\forest@def@processor{<}{}{}{%
+ \forest@process@left@toppop\forest@tempb
+ \forest@process@left@toppop\forest@tempa
+ \ifx\forestmathresulttype\forestmathtype@generic
+ \forest@cmp@error\forest@tempa\forest@tempb
+ \else
+ \forestmathlt{\forest@tempa}{\forest@tempb}%
+ \forest@process@left@esetappend{\forestmathresult}%
+ \fi
+}
+\forest@def@processor{>}{}{}{%
+ \forest@process@left@toppop\forest@tempb
+ \forest@process@left@toppop\forest@tempa
+ \ifx\forestmathresulttype\forestmathtype@generic
+ \forest@cmp@error\forest@tempa\forest@tempb
+ \else
+ \forestmathgt{\forest@tempa}{\forest@tempb}%
+ \forest@process@left@esetappend{\forestmathresult}%
+ \fi
+}
+\forest@def@processor{r}{}{}{% reverse keylist
+ \forest@process@right@bottompop\forest@temp
+ \expandafter\forest@processor@r@\expandafter{\forest@temp}%
+}
+\def\forest@processor@r@#1{%
+ \forest@temp@toks{}%
+ \def\forest@tempcomma{}%
+ \pgfqkeys{/forest}{split={#1}{,}{process@rk}}%
+ \forest@process@left@esetappend{\the\forest@temp@toks}%
+ \let\forestmathresulttype\forestmathtype@generic
}
\forestset{%
- reverse@keylist/.code={%
- \epretotoks\forest@processargs@current{#1,}%
- },
+ process@rk/.code={%
+ \epretotoks\forest@temp@toks{#1\forest@tempcomma}%
+ \def\forest@tempcomma{,}%
+ }%
}
\def\forest@pgfmathhelper@register@toks#1#2{% #1 is discarded: it is present only for analogy with options
\forestrget{#2}\pgfmathresult
}
\def\forest@pgfmathhelper@register@dimen#1#2{%
\forestrget{#2}\forest@temp
- \pgfmathparse{+\forest@temp}%
+ \edef\pgfmathresult{\expandafter\Pgf@geT\forest@temp}%
}
\def\forest@pgfmathhelper@register@count#1#2{%
- \forestrget{#2}\forest@temp
- \pgfmathtruncatemacro\pgfmathresult{\forest@temp}%
+ \forestrget{#2}\pgfmathresult
}
\def\forest@declareregisterhandler#1#2{%#1=handler for specific type,#2=option name
- \pgfkeyssetvalue{/forest/#2/node@or@reg}{register}%
+ \pgfkeyssetvalue{/forest/#2/node@or@reg}{}% empty = register (node id=node)
\forest@convert@others@to@underscores{#2}\forest@pgfmathoptionname
\edef\forest@marshal{%
\noexpand#1{/forest/#2}{/forest}{#2}{\forest@pgfmathoptionname}%
@@ -2166,6 +3386,7 @@
\pgfkeyssetvalue{#1/option@name}{#3}%
\pgfkeyssetvalue{#1+/option@name}{#3}%
\pgfkeyssetvalue{#2/+#3/option@name}{#3}%
+ \pgfkeyslet{#1/@type}\forestmathtype@generic % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@toks{##1}{#3}}%
}
\def\forest@declareautowrappedtoksregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix
@@ -2190,24 +3411,41 @@
\pgfkeysalso{##3}%
\fi
},
+ #2/if #3</.code n args={3}{%
+ \forestrget{#3}\forest@temp@option@value
+ \ifdim\forest@temp@option@value>##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
+ #2/if #3>/.code n args={3}{%
+ \forestrget{#3}\forest@temp@option@value
+ \ifdim\forest@temp@option@value<##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
}%
+ \pgfkeyslet{#1/@type}\forestmathtype@dimen % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@dimen{##1}{#3}}%
}
\def\forest@declaredimenregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname
\forest@declarereadonlydimenregister@handler{#1}{#2}{#3}{#4}%
\pgfkeysalso{%
#1/.code={%
- \pgfmathsetlengthmacro\forest@temp{##1}%
+ \forestmathsetlengthmacro\forest@temp{##1}%
\forestrlet{#3}\forest@temp
},
#1+/.code={%
- \pgfmathsetlengthmacro\forest@temp{##1}%
+ \forestmathsetlengthmacro\forest@temp{##1}%
\pgfutil@tempdima=\forestrve{#3}
\advance\pgfutil@tempdima\forest@temp\relax
\forestreset{#3}{\the\pgfutil@tempdima}%
},
#1-/.code={%
- \pgfmathsetlengthmacro\forest@temp{##1}%
+ \forestmathsetlengthmacro\forest@temp{##1}%
\pgfutil@tempdima=\forestrve{#3}
\advance\pgfutil@tempdima-\forest@temp\relax
\forestreset{#3}{\the\pgfutil@tempdima}%
@@ -2264,36 +3502,53 @@
\pgfkeysalso{##3}%
\fi
},
+ #2/if #3</.code n args={3}{%
+ \forestrget{#3}\forest@temp@option@value
+ \ifnum\forest@temp@option@value>##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
+ #2/if #3>/.code n args={3}{%
+ \forestrget{#3}\forest@temp@option@value
+ \ifnum\forest@temp@option@value<##1\relax
+ \pgfkeysalso{##3}%
+ \else
+ \pgfkeysalso{##2}%
+ \fi
+ },
}%
+ \pgfkeyslet{#1/@type}\forestmathtype@count % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@count{##1}{#3}}%
}
\def\forest@declarecountregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname
\forest@declarereadonlycountregister@handler{#1}{#2}{#3}{#4}%
\pgfkeysalso{
#1/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\forestrlet{#3}\forest@temp
},
#1+/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestrve{#3}\relax
\advance\c@pgf@counta\forest@temp\relax
\forestreset{#3}{\the\c@pgf@counta}%
},
#1-/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestrve{#3}\relax
\advance\c@pgf@counta-\forest@temp\relax
\forestreset{#3}{\the\c@pgf@counta}%
},
#1*/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestrve{#3}\relax
\multiply\c@pgf@counta\forest@temp\relax
\forestreset{#3}{\the\c@pgf@counta}%
},
#1:/.code={%
- \pgfmathtruncatemacro\forest@temp{##1}%
+ \forestmathtruncatemacro\forest@temp{##1}%
\c@pgf@counta=\forestrve{#3}\relax
\divide\c@pgf@counta\forest@temp\relax
\forestreset{#3}{\the\c@pgf@counta}%
@@ -2337,16 +3592,13 @@
\def\forest@declarebooleanregister@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname
\pgfkeysalso{%
#1/.code={%
- \ifstrequal{##1}{1}{%
- \forestrset{#3}{1}%
+ \ifcsdef{forest@bh@\detokenize{##1}}{%
+ \letcs\forest@temp{forest@bh@\detokenize{##1}}%
}{%
- \ifstrequal{##1}{0}{%
- \forestrset{#3}{0}%
- }{%
- \pgfmathifthenelse{##1}{1}{0}%
- \forestrlet{#3}\pgfmathresult
- }%
+ \forestmathtruncatemacro\forest@temp{##1}%
+ \ifx\forest@temp0\else\def\forest@temp{1}\fi
}%
+ \forestrlet{#3}\forest@temp
},
#1/.default=1,
#2/not #3/.code={\forestrset{#3}{0}},
@@ -2360,6 +3612,7 @@
},
}%
\pgfkeyssetvalue{#1/option@name}{#3}%
+ \pgfkeyslet{#1/@type}\forestmathtype@count % for .process & co
\pgfmathdeclarefunction{#4}{1}{\forest@pgfmathhelper@register@count{##1}{#3}}%
}
\forestset{
@@ -2526,12 +3779,17 @@
preamble'={},
declare autowrapped toks={content}{},
% #1 = which option to split, #2 = separator (one char!), #3 = receiving options
- %%% begin listing region: split_option
- split option/.style n args=3{split/.process args={O}{#1}{#2}{#3}}
- %%% end listing region: split_option
- ,
- split register/.style n args=3{% #1 = which register to split, #2 = separator (one char!), #3 = receiving options
- split/.process args={R}{#1}{#2}{#3},
+ split option/.code n args=3{%
+ \forestRNOget{#1}\forest@temp
+ \edef\forest@marshal{%
+ \noexpand\pgfkeysalso{split={\expandonce{\forest@temp}}\unexpanded{{#2}{#3}}}%
+ }\forest@marshal
+ },
+ split register/.code n args=3{% #1 = which register to split, #2 = separator (one char!), #3 = receiving options
+ \forestrget{#1}\forest@temp
+ \edef\forest@marshal{%
+ \noexpand\pgfkeysalso{split={\expandonce{\forest@temp}}\unexpanded{{#2}{#3}}}%
+ }\forest@marshal
},
TeX={%
\def\forest@split@sourcevalues{}%
@@ -2729,7 +3987,7 @@
get node boundary/.code={%
\forestoget{@boundary}\forest@node@boundary
\def#1{}%
- \forest@extendpath#1\forest@node@boundary{\pgfpoint{\forestove{x}}{\forestove{y}}}%
+ \forest@extendpath#1\forest@node@boundary{\pgfqpoint{\forestove{x}}{\forestove{y}}}%
},
% get min l tree boundary/.code={%
% \forest@get@tree@boundary{negative}{\the\numexpr\forestove{grow}-90\relax}#1},
@@ -2785,7 +4043,7 @@
\def\forest@get@tree@boundary#1#2#3{%#1=pos/neg,#2=grow,#3=receiving cs
\def#3{}%
\forest@node@getedge{#1}{#2}\forest@temp@boundary
- \forest@extendpath#3\forest@temp@boundary{\pgfpoint{\forestove{x}}{\forestove{y}}}%
+ \forest@extendpath#3\forest@temp@boundary{\pgfqpoint{\forestove{x}}{\forestove{y}}}%
}
\def\forest@setter@node{\forest@cn}%
\def\forest@relatednode@option@compat@ignoreinvalidsteps#1{#1}
@@ -2808,33 +4066,31 @@
\forestset{
for tree'/.style 2 args={#1,for children={for tree'={#1}{#2}},#2},
if/.code n args={3}{%
- \pgfmathparse{#1}%
- \ifnum\pgfmathresult=0
+ \forestmathtruncatemacro\forest@temp{#1}%
+ \ifnum\forest@temp=0
\@escapeif{\pgfkeysalso{#3}}%
\else
\@escapeif{\pgfkeysalso{#2}}%
\fi
},
+ %LaTeX if/.code n args={3}{#1{\pgfkeysalso{#2}}{\pgfkeysalso{#3}}},
if nodewalk valid/.code n args={3}{%
- \edef\forest@marshal{%
- \unexpanded{\forest@forthis{%
- \forest@nodewalk{%
- on invalid={fake}{#1},
- TeX={\global\let\forest@global@temp\forest@cn}
- }{}%
- }%
- \def\forest@cn}{\forest@cn}\unexpanded{%
- \ifnum\forest@global@temp=0
- \@escapeif{\pgfkeysalso{#3}}%
- \else
- \@escapeif{\pgfkeysalso{#2}}%
- \fi}%
- }\forest@marshal
+ \forest@forthis{%
+ \forest@configured@nodewalk{independent}{inherited}{fake}{%
+ #1,
+ TeX={\global\let\forest@global@temp\forest@cn}
+ }{}%
+ }%
+ \ifnum\forest@global@temp=0
+ \@escapeif{\pgfkeysalso{#3}}%
+ \else
+ \@escapeif{\pgfkeysalso{#2}}%
+ \fi
},
if nodewalk empty/.code n args={3}{%
\forest@forthis{%
- \forest@nodewalk{%
- on invalid={fake}{#1},
+ \forest@configured@nodewalk{independent}{independent}{fake}{%
+ #1,
TeX={\global\let\forest@global@temp\forest@nodewalk@n},
}{}%
}%
@@ -2844,39 +4100,46 @@
\@escapeif{\pgfkeysalso{#3}}%
\fi
},
+ if current nodewalk empty/.code 2 args={%
+ \ifnum\forest@nodewalk@n=0
+ \@escapeif{\pgfkeysalso{#1}}%
+ \else
+ \@escapeif{\pgfkeysalso{#2}}%
+ \fi
+ },
where/.style n args={3}{for tree={if={#1}{#2}{#3}}},
where nodewalk valid/.style n args={3}{for tree={if nodewalk valid={#1}{#2}{#3}}},
where nodewalk empty/.style n args={3}{for tree={if nodewalk empty={#1}{#2}{#3}}},
repeat/.code 2 args={%
- \pgfmathtruncatemacro\forest@temp{#1}%
+ \forestmathtruncatemacro\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}%
+ \forest@untilkey{\forestmath@if{#1}{\forestloopbreak}{}}{#2}%
}%
},
while/.code 2 args={%
\ifstrempty{#1}{%
\forest@untilkey{\ifnum\forest@cn=0\relax\forestloopbreak\fi}{on invalid={fake}{#2}}%
}{%
- \forest@untilkey{\pgfmathifthenelse{not(#1)}{"\noexpand\forestloopbreak"}{""}\pgfmathresult}{#2}%
+ \forest@untilkey{\forestmath@if{#1}{}{\forestloopbreak}}{#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}%
+ \forest@dountilkey{\forestmath@if{#1}{\forestloopbreak}{}}{#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}%
+ \forest@dountilkey{\forestmath@if{#1}{}{\forestloopbreak}}{#2}%
}%
},
until nodewalk valid/.code 2 args={%
@@ -2981,48 +4244,168 @@
\forest@aggregate@pgfmathpostparse@macro
}
\let\forest@aggregate@pgfmathpostparse\relax
-\pgfkeys{
+\forestset{
/handlers/.aggregate/.code n args=4{%
- % #1 = start value
- % #2 = pgfmath expression for every step
- % #3 = pgfmath expression for after walk
+ % #1 = start value (forestmath)
+ % #2 = forestmath expression that calculates "aggregate result" at each step
+ % #3 = forestmath expression that calculates "aggregate result" at the end of the nodewalk
% #4 = nodewalk
- \edef\forest@marshal{%
- \unexpanded{\forest@aggregate{#1}{#2}{#3}{#4}}{\pgfkeyscurrentpath}%
- }\forest@marshal
+ \forest@aggregate@handler{\forest@aggregate@generic{#1}{#2}{#3}{#4}}%
+ },
+ /handlers/.sum/.code 2 args={% #1=forestmath, #2=nodewalk
+ \forest@aggregate@handler{\forest@aggregate@sum{#1}{#2}}%
+ },
+ /handlers/.count/.code={% #1=nodewalk
+ \forest@aggregate@handler{\forest@aggregate@count{#1}}%
+ },
+ /handlers/.average/.code 2 args={% #1=forestmath, #2=nodewalk
+ \forest@aggregate@handler{\forest@aggregate@average{#1}{#2}}%
},
- /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},
+ /handlers/.product/.code 2 args={% #1=forestmath, #2=nodewalk
+ \forest@aggregate@handler{\forest@aggregate@product{#1}{#2}}%
+ },
+ /handlers/.min/.code 2 args={% #1=forestmath, #2=nodewalk
+ \forest@aggregate@handler{\forest@aggregate@min{#1}{#2}}%
+ },
+ /handlers/.max/.code 2 args={% #1=forestmath, #2=nodewalk
+ \forest@aggregate@handler{\forest@aggregate@max{#1}{#2}}%
+ },
+ declare count register={aggregate n},
+ declare toks register={aggregate value},
+ declare toks register={aggregate result},
+ aggregate result={},
}
-
-\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@aggregate@handler#1{%
+ \edef\forest@marshal{%
+ \unexpanded{%
+ #1%
+ }{%
+ \noexpand\pgfkeysalso{\pgfkeyscurrentpath/.register=aggregate result}%
}%
- \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}%
+ }\forest@marshal
+}
+\def\forest@aggregate@pgfmathfunction@finish{%
+ \forestrget{aggregate result}\pgfmathresult
+}
+\pgfmathdeclarefunction{aggregate}{4}{%
+ \forest@aggregate@generic{#1}{#2}{#3}{#4}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\pgfmathdeclarefunction{aggregate_count}{1}{%
+ \forest@aggregate@sum{#1}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\pgfmathdeclarefunction{aggregate_sum}{2}{%
+ \forest@aggregate@sum{#1}{#2}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\pgfmathdeclarefunction{aggregate_product}{2}{%
+ \forest@aggregate@product{#1}{#2}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\pgfmathdeclarefunction{aggregate_average}{2}{%
+ \forest@aggregate@average{#1}{#2}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\pgfmathdeclarefunction{aggregate_min}{2}{%
+ \forest@aggregate@min{#1}{#2}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\pgfmathdeclarefunction{aggregate_max}{2}{%
+ \forest@aggregate@max{#1}{#2}%
+ \forest@aggregate@pgfmathfunction@finish
+}
+\def\forest@aggregate#1#2#3#4#5#6{% #1...#5=real args,
+ % #6=what to do with |aggregate result| register
+ % #1 = start value (forestmath)
+ % #2 = forestmath expression that calculates "aggregate current" at each step
+ % #3 = forestmath expression that calculates "aggregate result" at each step
+ % #4 = forestmath expression that calculates "aggregate result" at the end of the nodewalk
+ % #5 = nodewalk
+ \forest@saveandrestoreregister{aggregate result}{%
+ \forest@saveandrestoreregister{aggregate n}{%
+ \forest@aggregate@{#1}{#2}{#3}{#4}{#5}%
+ #6%
+ }%
+ }%
+}
+\def\forest@aggregate@generic#1#2#3#4{\forest@aggregate
+ {\forestmathparse{#1}}%
+ {}%
+ {\forestmathparse{#2}}%
+ {\forestmathparse{#3}}%
+ {#4}%
+}
+\def\forest@aggregate@sum#1#2{\forest@aggregate
+ {\forestmath@convert@fromto\forestmathtype@count\forestmathtype@generic{0}}%
+ {\forestmathparse{#1}}%
+ {\forestmathadd{\forestregister{aggregate value}}{\forestregister{aggregate result}}}%
+ {\forestrget{aggregate result}\forestmathresult}%
+ {#2}%
+}
+\def\forest@aggregate@count#1{\forest@aggregate
+ {\def\forestmathresult{1}}%
+ {\def\forestmathresult{1}}%
+ {\edef\forestmathresult{\the\numexpr\forestregister{aggregate result}+1}}%
+ {\forestrget{aggregate result}\forestmathresult}%
+ {#1}%
+}
+\def\forest@aggregate@average#1#2{\forest@aggregate
+ {\forestmath@convert@fromto\forestmathtype@count\forestmathtype@generic{0}}%
+ {\forestmathparse{#1}}%
+ {\forestmathadd{\forestregister{aggregate value}}{\forestregister{aggregate result}}}%
+ {\forestmathdivide@P{\forestregister{aggregate result}}{\forestregister{aggregate n}}}%
+ {#2}%
+}
+\def\forest@aggregate@product#1#2{\forest@aggregate
+ {\forestmath@convert@fromto\forestmathtype@count\forestmathtype@generic{1}}%
+ {\forestmathparse{#1}}%
+ {\forestmathmultiply{\forestregister{aggregate value}}{\forestregister{aggregate result}}}%
+ {\forestrget{aggregate result}\forestmathresult}%
+ {#2}%
+}
+\def\forest@aggregate@min#1#2{\forest@aggregate
+ {\def\forestmathresult{}}%
+ {\forestmathparse{#1}}%
+ {\forestmathmin{\forestregister{aggregate value}}{\forestregister{aggregate result}}}%
+ {\forestrget{aggregate result}\forestmathresult}%
+ {#2}%
+}
+\def\forest@aggregate@max#1#2{\forest@aggregate
+ {\def\forestmathresult{}}%
+ {\forestmathparse{#1}}%
+ {\forestmathmax{\forestregister{aggregate value}}{\forestregister{aggregate result}}}%
+ {\forestrget{aggregate result}\forestmathresult}%
+ {#2}%
+}
+\def\forest@aggregate@#1#2#3#4#5{%
+ % #1 = start value (forestmath)
+ % #2 = forestmath expression that calculates "aggregate current" at each step
+ % #3 = forestmath expression that calculates "aggregate result" at each step
+ % #4 = forestmath expression that calculates "aggregate result" at the end of the nodewalk
+ % #5 = nodewalk
+ #1%
+ \forestrlet{aggregate result}\forestmathresult
+ \forestrset{aggregate value}{}%
+ \forestrset{aggregate n}{0}%
+ \forest@forthis{%
+ \forest@nodewalk{#5}{%
+ TeX={%
+ \forestreset{aggregate n}{\number\numexpr\forestrv{aggregate n}+1}%
+ #2%
+ \forestrlet{aggregate value}\forestmathresult
+ #3%
+ \forestrlet{aggregate result}\forestmathresult
+ }%
+ }{}%
+ }%
+ #4%
+ \let\forest@temp@pgfmathpostparse\pgfmathpostparse
+ \let\pgfmathpostparse\forest@aggregate@pgfmathpostparse
+ \forestmath@convert@to\forestmathtype@dimen{\forestmathresult}
+ \pgfmathqparse{\forestmathresult}%
+ \let\pgfmathpostparse\forest@temp@pgfmathpostparse
+ \forestrlet{aggregate result}\pgfmathresult
}
\pgfmathdeclarefunction{strequal}{2}{%
\ifstrequal{#1}{#2}{\def\pgfmathresult{1}}{\def\pgfmathresult{0}}%
@@ -3038,28 +4421,32 @@
\forest@forthis{%
\forest@nameandgo{#1}%
\forest@compute@minmax@ls{#2}%
- \pgfmathsetmacro\pgfmathresult{\forestove{min@s}}%
+ \edef\forest@temp{\forestove{min@s}}%
+ \edef\pgfmathresult{\expandafter\Pgf@geT\forest@temp}%
}%
}
\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}}%
+ \edef\forest@temp{\forestove{min@l}}%
+ \edef\pgfmathresult{\expandafter\Pgf@geT\forest@temp}%
}%
}
\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}}%
+ \edef\forest@temp{\forestove{max@s}}%
+ \edef\pgfmathresult{\expandafter\Pgf@geT\forest@temp}%
}%
}
\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}}%
+ \edef\forest@temp{\forestove{max@l}}%
+ \edef\pgfmathresult{\expandafter\Pgf@geT\forest@temp}%
}%
}
\def\forest@compute@minmax@ls#1{% #1 = nodewalk; in the context of which node?
@@ -3067,7 +4454,7 @@
\pgftransformreset
\forest@forthis{%
\forest@nameandgo{#1}%
- \pgftransformrotate{-\forestove{grow}}%
+ \forest@pgfqtransformrotate{-\forestove{grow}}%
}%
\forestoget{min x}\forest@temp@minx
\forestoget{min y}\forest@temp@miny
@@ -3116,10 +4503,10 @@
\forest@forthis{%
\forest@nameandgo{#1}%
\ifnum\forest@cn=0
- \def\pgfmathresult{0pt}%
+ \def\pgfmathresult{0}%
\else
\forestoget{#2}\forest@temp
- \pgfmathparse{+\forest@temp}%
+ \edef\pgfmathresult{\expandafter\Pgf@geT\forest@temp}%
\fi
}%
}
@@ -3129,8 +4516,7 @@
\ifnum\forest@cn=0
\def\pgfmathresult{0}%
\else
- \forestoget{#2}\forest@temp
- \pgfmathtruncatemacro\pgfmathresult{\forest@temp}%
+ \forestoget{#2}\pgfmathresult
\fi
}%
}
@@ -3171,21 +4557,30 @@
\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}%
- }%
+ \forest@configured@nodewalk{independent}{independent}{inherited}{#1}{#2}%
}
+\def\forest@configured@nodewalk#1#2#3#4#5{%
+ % #1 = every step method, #2 = history method, #3 = on invalid
+ % #4 = nodewalk, #5 = every step keylist
+ \def\forest@nodewalk@config@everystep@method{#1}%
+ \def\forest@nodewalk@config@history@method{#2}%
+ \def\forest@nodewalk@config@oninvalid{#3}%
+ \forest@Nodewalk{#4}{#5}%
+}
+\def\forest@nodewalk@oninvalid@inherited@text{inherited}
\def\forest@Nodewalk#1#2{% #1 = nodewalk, #2 = every step keylist
+ \ifx\forest@nodewalk@config@oninvalid\forest@nodewalk@oninvalid@inherited@text
+ \edef\forest@nodewalk@config@oninvalid{\forest@nodewalk@oninvalid}%
+ \fi
\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
+ \edef\noexpand\forest@nodewalk@oninvalid{\forest@nodewalk@oninvalid}%
}%
\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
+ \edef\forest@nodewalk@oninvalid{\forest@nodewalk@config@oninvalid}%
\forest@nodewalk@fakefalse
\forest@marshal
}
@@ -3205,25 +4600,27 @@
\def\forest@nodewalk@oninvalid{error}
\def\forest@nodewalk@makestep{%
\ifnum\forest@cn=0
- \csname forest@nodewalk@makestep@oninvalid@\forest@nodewalk@config@oninvalid\endcsname
+ \csname forest@nodewalk@makestep@oninvalid@\forest@nodewalk@oninvalid\endcsname
\else
\forest@nodewalk@makestep@
\fi
}
-\def\forest@nodewalk@makestep@oninvalid@step{\forest@nodewalk@makestep@}
+\csdef{forest@nodewalk@makestep@oninvalid@error if real}{\ifforest@nodewalk@fake\expandafter\forest@nodewalk@makestep@\else\expandafter\forest@nodewalk@makestep@oninvalid@error\fi}
+\csdef{forest@nodewalk@makestep@oninvalid@last valid}{%
+ \forest@nodewalk@tolastvalid
+ \ifforestdebugnodewalks\forest@nodewalk@makestep@invalidtolastvalid@debug\fi}%
\def\forest@nodewalk@makestep@oninvalid@error{\PackageError{forest}{nodewalk stepped to the invalid node\MessageBreak nodewalk 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.}%
+ \forest@deprecated{last step in stack "\forest@nodewalk@currentstepname", which stepped on an invalid node; enabled by "compat=1.0-forstep". 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@{%
+ \ifforestdebugnodewalks\forest@nodewalk@makestep@debug\fi
\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,}%
- \ifforestdebugnodewalks\forest@nodewalk@makestep@debug\fi
\forest@process@keylist@register{every step}%
\fi
}
@@ -3232,6 +4629,11 @@
\noexpand\typeout{\ifforest@nodewalk@fake fake \fi "\forest@nodewalk@currentstepname" step to node id=\forest@cn, content=\forestoption{content}}%
}\forest@marshal
}%
+\def\forest@nodewalk@makestep@invalidtolastvalid@debug{%
+ \edef\forest@marshal{%
+ \noexpand\typeout{\ifforest@nodewalk@fake fake \fi "\forest@nodewalk@currentstepname" step to invalid node, (fake) return to last valid id=\forest@cn, content=\forestoption{content}}%
+ }\forest@marshal
+}%
\def\forest@handlers@savecurrentpath{%
\edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}%
\let\forest@currentkey\pgfkeyscurrentkey
@@ -3336,6 +4738,8 @@
{\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
+ % Uncomment this to collect a list of for-based spatial propagators
+ %\appto\bigbadforlist{[#1]}%
\fi
},
}
@@ -3345,7 +4749,7 @@
}},
}
\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}
+\def\forest@util@nargs#1#2#3{% #1 = prefix (#, ##, ...), #2 = n args, #3=start; returns {#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
@@ -3357,7 +4761,11 @@
\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@compatfake#1{%
+ \forest@deprecated{last step in stack "\forest@nodewalk@currentstepname", which started from an invalid node; enabled by "compat=1.0-forstep". Use "on invalid={fake}{...}" or "for Nodewalk={on invalid=fake}{...}{...}" instead.}%
+}%
+\let\forest@nodewalk@start@oninvalid@errorifreal\forest@nodewalk@start@oninvalid@fake % the step will be to an invalid node anyway
+\let\forest@nodewalk@start@oninvalid@lastvalid\forest@nodewalk@start@oninvalid@fake
\def\forest@nodewalk@start@oninvalid@error#1{\PackageError{forest}{nodewalk step "#1" cannot start at the invalid node}{}}
\forestset{
define long step={current}{autostep}{},
@@ -3403,21 +4811,21 @@
},
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}{%
+ define long step={next on tier}{autostep,n args=1}{%
\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}%
+ \edef\forest@cn{\forest@node@linearnextid}%
\safeloop
- \forestoget{tier}\forest@nodewalk@tier
- \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier
+ \forest@nodewalk@gettier
+ \ifforest@temp
\edef\forest@cn{\forest@node@linearnextid}%
\saferepeat
},
- define long step={previous on tier}{autostep}{%
+ define long step={previous on tier}{autostep,n args=1}{%
\def\forest@temp{#1}%
\ifx\forest@temp\pgfkeysnovalue@text
\forestoget{tier}\forest@nodewalk@giventier
@@ -3426,10 +4834,24 @@
\fi
\safeloop
\edef\forest@cn{\forest@node@linearpreviousid}%
- \forestoget{tier}\forest@nodewalk@tier
- \unless\ifx\forest@nodewalk@tier\forest@nodewalk@giventier
+ \forest@nodewalk@gettier
+ \ifforest@temp
\saferepeat
},
+ TeX={%
+ \def\forest@nodewalk@gettier{%
+ \ifnum\forest@cn=0
+ \forest@tempfalse
+ \else
+ \forestoget{tier}\forest@temp
+ \ifx\forest@temp\forest@nodewalk@giventier
+ \forest@tempfalse
+ \else
+ \forest@temptrue
+ \fi
+ \fi
+ }%
+ },
%
define long step={root}{autostep,must start at valid node=false}{%
\edef\forest@cn{\forest@node@rootid}},
@@ -3439,7 +4861,7 @@
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}%
+ \forestmathtruncatemacro\forest@temp@n{#1}%
\edef\forest@cn{\forest@node@nthchildid{\forest@temp@n}}%
},
define long step={n}{autostep,make for=false,n args=1}{%
@@ -3449,19 +4871,19 @@
\ifx\forest@nodewalk@temp\pgfkeysnovalue@text
\edef\forest@cn{\forestove{@next}}%
\else
- \pgfmathtruncatemacro\forest@temp@n{#1}%
+ \forestmathtruncatemacro\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}%
+ \forestmathtruncatemacro\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
+ \forest@nodewalk@gettier
+ \ifforest@temp
\forestoget{@parent}\forest@cn
\saferepeat
},
@@ -3478,45 +4900,35 @@
\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}%
- }%
+ \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}{}%
- }%
+ define long step={nodewalk'}{n args=1,@bare}{% #1 = nodewalk
+ \forest@configured@nodewalk{inherited}{independent}{inherited}{#1}{}%
},
- % these must be defined explicitely, as prefix "for" normally introduces the every-step keylist
- for nodewalk/.code 2 args={%
+ % these "for ..." keys must be defined explicitely
+ % (and copied into node keyspace manually),
+ % as prefix "for" normally introduces the every-step keylist
+ define long step={for nodewalk}{n args=2,@bare}{% #1 = nodewalk, #2 = every step
\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}{}}%
+ define long step={for nodewalk'}{n args=1,@bare}{% #1 = nodewalk
+ \forest@forthis{%
+ \forest@configured@nodewalk{inherited}{independent}{inherited}{#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}%
+ define long step={for Nodewalk}{n args=3,@bare}{% #1 = config, #2 = nodewalk, #3 = every-step
+ \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@forthis{\forest@Nodewalk{#2}{#3}}%
- }%
+ \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},
+ copy command key={/forest/nodewalk/Nodewalk}{/forest/Nodewalk},
+ copy command key={/forest/nodewalk/for nodewalk}{/forest/for nodewalk},
+ copy command key={/forest/nodewalk/for Nodewalk}{/forest/for Nodewalk},
declare keylist register=every step,
every step'={},
%%% begin nodewalk config
@@ -3536,23 +4948,25 @@
on@invalid/.is choice,
on@invalid/error/.code={},
on@invalid/fake/.code={},
- on@invalid/step/.code={},
+ on@invalid/error if real/.code={},
+ on@invalid/last valid/.code={},
on@invalid/inherited/.code={},
on invalid/.store in=\forest@nodewalk@config@oninvalid,
on invalid/.prefix style={on@invalid=#1},
%%% end nodewalk config
}
+\newtoks\forest@nodewalk@branch@toks
\forestset{
declare toks register=branch@temp@toks,
branch@temp@toks={},
declare keylist register=branched@nodewalk,
branched@nodewalk={},
- define long step={branch}{n args=1,@bare,style}{@branch={#1}{branch@build@realstep,branch@build@fakestep}},
- define long step={branch'}{n args=1,@bare,style}{@branch={#1}{branch@build@realstep}},
+ define long step={branch}{n args=1,@bare,make for,style}{@branch={#1}{branch@build@realstep,branch@build@fakestep}},
+ define long step={branch'}{n args=1,@bare,make for,style}{@branch={#1}{branch@build@realstep}},
@branch/.style 2 args={%
save and restore register={branched@nodewalk}{
branch@temp@toks={},
- split/.process args={r}{#1}{,}{#2},
+ split/.process={r}{#1}{,}{#2},
branch@temp@style/.style/.register=branch@temp@toks,
branch@temp@style,
branch@temp@style/.style/.register=branched@nodewalk,
@@ -3568,7 +4982,7 @@
branch@temp@toks/.expanded={for nodewalk={\unexpanded{#1}}{
\forestregister{branch@temp@toks}}},
},
- define long step={group}{autostep}{\forest@go{#1}},
+ define long step={group}{autostep,n args=1}{\forest@go{#1}},
nodewalk/fake/.code={%
\forest@saveandrestoreifcs{forest@nodewalk@fake}{%
\forest@nodewalk@faketrue
@@ -3583,7 +4997,7 @@
},
declare keylist register=filtered@nodewalk,
filtered@nodewalk={},
- define long step={filter}{n args=2,@bare,style}{% #1 = nodewalk, #2 = condition
+ define long step={filter}{n args=2,@bare,make for,style}{% #1 = nodewalk, #2 = condition
save and restore register={filtered@nodewalk}{
filtered@nodewalk'={},
Nodewalk=%
@@ -3592,12 +5006,13 @@
{if={#2}{filtered@nodewalk+/.expanded={id=\forestoption{id}}}{}},
filtered@nodewalk@style/.style/.register=filtered@nodewalk,
filtered@nodewalk@style
- }
+ },
},
on@invalid/.is choice,
on@invalid/error/.code={},
on@invalid/fake/.code={},
- on@invalid/step/.code={},
+ on@invalid/error if real/.code={},
+ on@invalid/last valid/.code={},
on invalid/.code 2 args={%
\pgfkeysalso{/forest/on@invalid={#1}}%
\forest@saveandrestoremacro\forest@nodewalk@oninvalid{%
@@ -3607,38 +5022,54 @@
},
define long step={strip fake steps}{n args=1,@bare}{%
\forest@nodewalk@stripfakesteps{\pgfkeysalso{#1}}},
+ define long step={unique}{n args=1}{%
+ \begingroup
+ \def\forest@nodewalk@unique@temp{}%
+ \forest@nodewalk{#1}{%
+ TeX={%
+ \forestoget{unique@visited}\forest@temp
+ \ifx\forest@temp\relax
+ \forestoset{unique@visited}{1}%
+ \eappto\forest@nodewalk@unique@temp{,id=\forest@cn}%
+ \fi
+ }%
+ }%
+ \global\let\forest@global@temp\forest@nodewalk@unique@temp
+ \endgroup
+ \pgfkeysalsofrom{\forest@global@temp}%
+ },
define long step={walk back}{n args=1,@bare}{%
- \pgfmathtruncatemacro\forest@temp@n{#1}%
+ \forestmathtruncatemacro\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}%
+ \forestmathtruncatemacro\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}%
+ \forestmathtruncatemacro\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}%
+ \forestmathtruncatemacro\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}%
+ \forestmathtruncatemacro\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}%
+ \forestmathtruncatemacro\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
},
@@ -3691,7 +5122,9 @@
\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,
+ declare keylist register=sort by,
+ copy command key={/forest/sort by'}{/forest/sort by},
+ sort by={},
define long step={save}{n args=2,@bare,make for}{% #1 = name, #2 = nodewalk
\forest@forthis{%
\forest@nodewalk{#2,TeX={%
@@ -3709,6 +5142,21 @@
}\forest@marshal
\csedef{forest@nodewalk@saved@#1}{\forest@nodewalk@walklist@walked}%
},
+ define long step={save append}{style,n args=2,@bare,make for}{% #1 = nodewalk name, #2 = nodewalk
+ save@append@prepend={#1}{#2}{save}{\cseappto}},
+ define long step={save prepend}{style,n args=2,@bare,make for}{% #1 = nodewalk name, #2 = nodewalk
+ save@append@prepend={#1}{#2}{save}{\csepreto}},
+ define long step={walk and save append}{style,n args=2,@bare,make for}{% #1 = nodewalk name, #2 = nodewalk
+ save@append@prepend={#1}{#2}{walk and save}{\cseappto}},
+ define long step={walk and save prepend}{style,n args=2,@bare,make for}{% #1 = nodewalk name, #2 = nodewalk
+ save@append@prepend={#1}{#2}{walk and save}{\csepreto}},
+ nodewalk/save@append@prepend/.code n args=4{%
+ % #1 = nodewalk name, #2 = nodewalk
+ % #3 = "(walk and) save" #4 = \cseappto/\csepreto
+ \pgfkeysalso{#3={@temp}{#2}}%
+ \letcs\forest@temp{forest@nodewalk@saved@@temp}%
+ #4{forest@nodewalk@saved@#1}{\expandonce{\forest@temp}}%
+ },
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}%
@@ -3799,12 +5247,7 @@
\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}{}%
- }%
+ \forest@configured@nodewalk{independent}{inherited}{inherited}{#1}{}%
}
\def\forest@csvlist@getfirst@#1{% assuming that the list is nonempty and finishes with a comma
\forest@csvlist@getfirst@@#1\forest@csvlist@getfirst@@}
@@ -3852,7 +5295,7 @@
\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}%
+ \forestrget{sort by}\forest@nodesort@sortkey
\forest@sort\forest@nodesort@cmpnodes\forest@nodesort@let#2{1}{#1}%
\def\forest@nodewalksort@sorted{}%
\safeloop
@@ -3936,7 +5379,7 @@
% #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}%
+ \forestrget{sort by}\forest@nodesort@sortkey
\edef\forest@nodewalk@minmax@N{\number\numexpr#2}%
\edef\forest@nodewalk@minmax@n{}%
\edef\forest@nodewalk@minmax@list{#1}%
@@ -4146,7 +5589,7 @@
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}%
+ \forestmathtruncatemacro\forest@temp{#1}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst
{\forest@temp}%
@@ -4154,7 +5597,7 @@
}\forest@marshal
},
define long step={level>}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{#1}%
+ \forestmathtruncatemacro\forest@temp{#1}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst
{-1}%
@@ -4162,8 +5605,7 @@
}\forest@marshal
},
define long step={level<}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)-1}%
- \show\forest@temp
+ \forestmathtruncatemacro\forest@temp{(#1)-1}%
\ifnum\forest@temp=-1
% special case, as \forest@node@foreach@breadthfirst uses level<0 as a signal for unlimited max level
\ifnum\forestove{level}=0
@@ -4178,7 +5620,7 @@
\fi
},
define long step={level reversed}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{#1}%
+ \forestmathtruncatemacro\forest@temp{#1}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst@reversed
{\forest@temp}%
@@ -4186,7 +5628,7 @@
}\forest@marshal
},
define long step={level reversed>}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{#1}%
+ \forestmathtruncatemacro\forest@temp{#1}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst@reversed
{-1}%
@@ -4194,7 +5636,7 @@
}\forest@marshal
},
define long step={level reversed<}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)-1}%
+ \forestmathtruncatemacro\forest@temp{(#1)-1}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst@reversed
{\forest@temp}%
@@ -4203,7 +5645,7 @@
},
%
define long step={relative level}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
+ \forestmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst
{\forest@temp}%
@@ -4211,7 +5653,7 @@
}\forest@marshal
},
define long step={relative level>}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
+ \forestmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst
{-1}%
@@ -4219,7 +5661,7 @@
}\forest@marshal
},
define long step={relative level<}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}-1}%
+ \forestmathtruncatemacro\forest@temp{(#1)+\forestove{level}-1}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst
{\forest@temp}%
@@ -4227,7 +5669,7 @@
}\forest@marshal
},
define long step={relative level reversed}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
+ \forestmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst@reversed
{\forest@temp}%
@@ -4235,7 +5677,7 @@
}\forest@marshal
},
define long step={relative level reversed>}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
+ \forestmathtruncatemacro\forest@temp{(#1)+\forestove{level}}%
\edef\forest@marshal{%
\noexpand\forest@node@foreach@breadthfirst@reversed
{-1}%
@@ -4243,13 +5685,26 @@
}\forest@marshal
},
define long step={relative level reversed<}{n args=1}{%
- \pgfmathtruncatemacro\forest@temp{(#1)+\forestove{level}-1}%
+ \forestmathtruncatemacro\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={leaves}{}{%
+ \forest@node@foreach{%
+ \ifnum\forestove{n children}=0
+ \forest@nodewalk@makestep
+ \fi
+ }%
+ },
+ define long step={-level}{n args=1,style}{%
+ unique={branch={leaves,{group={repeat={#1}{parent}}}}}
+ },
+ define long step={-level'}{n args=1,style}{%
+ unique={on invalid={fake}{branch={leaves,{group={repeat={#1}{parent}}}}}}
+ },
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}},
@@ -4327,7 +5782,13 @@
\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}}
+ \ifbool{#1}{\noexpand\setbool{#1}{true}}{\noexpand\setbool{#1}{false}}%
+ }\forest@marshal
+}
+\def\forest@globalsaveandrestoreifcs#1#2{% #1 = the if cs to save before and restore after processing code in #2
+ \edef\forest@marshal{%
+ \unexpanded{#2}%
+ \ifbool{#1}{\global\noexpand\setbool{#1}{true}}{\global\noexpand\setbool{#1}{false}}%
}\forest@marshal
}
\def\forest@saveandrestoretoks#1#2{% #1 = the toks to save before and restore after processing code in #2
@@ -4344,7 +5805,7 @@
}
\forestset{
save and restore register/.code 2 args={%
- \forest@saveandrestoreregister{filter@ed}{%
+ \forest@saveandrestoreregister{#1}{%
\pgfkeysalso{#2}%
}%
},
@@ -4455,21 +5916,16 @@
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}}%
+ \def\noexpand\forest@nodesort@sortkey{\forestrv{sort by}}%
+ \noexpand\forest@nodesort\noexpand\forest@sort@ascending{\forest@cn}
}%
},
sort'/.code={%
\eapptotoks\forest@do@dynamics{%
- \noexpand\forest@nodesort
- \noexpand\forest@sort@descending
- {\forest@cn}%
- {\expandonce{\forest@nodesort@by}}%
+ \def\noexpand\forest@nodesort@sortkey{\forestrv{sort by}}%
+ \noexpand\forest@nodesort\noexpand\forest@sort@descending{\forest@cn}
}%
},
- sort by/.store in=\forest@nodesort@by,
}
\def\forest@replaceby@code#1#2{%#1=node spec,#2=insert after['][']
\ifnum\forestove{@parent}=0
@@ -4485,10 +5941,9 @@
}%
\fi
}
-\def\forest@nodesort#1#2#3{% #1 = direction, #2 = parent node, #3 = sort key
+\def\forest@nodesort#1#2{% #1 = direction, #2 = parent node
\ifforestdebugdynamics\forestdebug@dynamics{before sorting children of #2}\fi
- \def\forest@nodesort@sortkey{#3}%
- \forest@fornode{#2}{\forest@nodesort@#1}%
+ \forest@fornode{#2}{\forest@nodesort@#1}%
\ifforestdebugdynamics\forestdebug@dynamics{after sorting children of #2}\fi
}
\def\forest@nodesort@#1{%
@@ -4516,29 +5971,53 @@
\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
+ \expandafter\forest@nodesort@cmpnodes@\forest@nodesort@sortkey,\forest@END{#1}{#2}%
+}
+\def\forest@nodesort@cmpnodes@#1,#2\forest@END#3#4{%
+ % #1=process ins+arg for this dimension, #2=for next dimensions
+ % #3, #4 = node ids
+ {%
+ \forest@fornode{\csname forest@nodesort@#3\endcsname}{%
+ \forestmathsetmacro\forest@nodesort@resulta{#1}%
+ }%
+ \forest@fornode{\csname forest@nodesort@#4\endcsname}{%
+ \forestmathsetmacro\forest@nodesort@resultb{#1}%
+ }%
+ \ifx\forestmathresulttype\forestmathtype@generic
+ \forest@cmp@error{\forest@nodesort@resulta}{\forest@nodesort@resultb}%
\fi
+ \edef\forest@temp{%
+ \noexpand\forest@nodesort@cmp
+ {\expandonce{\forest@nodesort@resulta}}%
+ {\expandonce{\forest@nodesort@resultb}}%
+ }%
+ \xdef\forest@global@temp{\forest@temp}%
}%
- \forest@nodesort@cmpresult
-}
+ \if=\forest@global@temp
+ \let\forest@next\forest@nodesort@cmpnodes@
+ \else
+ \let\forest@next\forest@nodesort@cmpnodes@finish
+ \fi
+ \ifstrempty{#2}{\let\forest@next\forest@nodesort@cmpnodes@finish}{}%
+ \forest@next#2\forest@END{#3}{#4}%
+}
+\def\forest@nodesort@cmpnodes@finish#1\forest@END#2#3{%
+ \let\forest@sort@cmp@result\forest@global@temp
+}
+\def\forest@nodesort@cmp{\csname fRsT@nsc@\forestmathresulttype\endcsname}
+\def\fRsT@nsc@#1{\csname fRsT@nsc@#1\endcsname}
+\def\fRsT@nsc@n#1#2{\ifnum#1<#2 <\else\ifnum#1=#2 =\else>\fi\fi}
+\def\fRsT@nsc@d#1#2{\ifdim#1<#2 <\else\ifdim#1=#2 =\else>\fi\fi}
+\def\fRsT@nsc@P#1#2{\ifdim#1pt<#2pt <\else\ifdim#1pt=#2pt =\else>\fi\fi}
+\def\fRsT@nsc@t#1#2{\csname fRsT@nsc@\pdfstrcmp{#1}{#2}\endcsname}
+\def\fRsT@nsc@T#1#2{\csname fRsT@nsc@\pdfstrcmp{#2}{#1}\endcsname}
+\csdef{fRsT@nsc@-1}{<}
+\csdef{fRsT@nsc@0}{=}
+\csdef{fRsT@nsc@1}{>}
\def\forest@nodesort@let#1#2{%
\csletcs{forest@nodesort@#1}{forest@nodesort@#2}%
}
@@ -4596,9 +6075,16 @@
declare keylist={before computing xy}{},
declare keylist={before drawing tree}{},
declare keylist={delay}{},
- delay n/.style 2 args={if={#1==0}{#2}{delay@n={#1}{#2}}},
- delay@n/.style 2 args={
- if={#1==1}{delay={#2}}{delay={delay@n/.process args={P}{#1-1}{#2}}}
+ delay n/.code 2 args={%
+ \forestmathsetcount\forest@temp@count{#1}%
+ \pgfkeysalso{delay n'={\forest@temp@count}{#2}}%
+ },
+ delay n'/.code 2 args={
+ \ifnum#1=0
+ \pgfkeysalso{#2}%
+ \else
+ \pgfkeysalso{delay={delay n'/.expand once=\expandafter{\number\numexpr#1-1\relax}{#2}}}%
+ \fi
},
if have delayed/.style 2 args={if have delayed'={processing order}{#1}{#2}},
if have delayed'/.code n args=3{%
@@ -5076,7 +6562,7 @@
\def\forest@pack@pgfpoint@childsposition#1{%
{%
\pgftransformreset
- \pgftransformrotate{\forestove{grow}}%
+ \forest@pgfqtransformrotate{\forestove{grow}}%
\forest@fornode{#1}{%
\pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}%
}%
@@ -5085,7 +6571,7 @@
\def\forest@pack@pgfpoint@positioningrow#1{%
{%
\pgftransformreset
- \pgftransformrotate{#1}%
+ \forest@pgfqtransformrotate{#1}%
\pgfpointtransformed{\pgfqpoint{\forestove{l}}{\forestove{s}}}%
}%
}
@@ -5102,7 +6588,7 @@
{%
\edef\forest@temp@child{\forest@node@nornbarthchildid{\forestove{calign primary child}}}%
\pgftransformreset
- \pgftransformrotate{\forestove{grow}}%
+ \forest@pgfqtransformrotate{\forestove{grow}}%
\pgfpointtransformed{\pgfqpoint{\forestOve{\forest@temp@child}{l}}{\forestOve{\forest@temp@child}{s}}}%
\pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax
\forest@Pointanchor{\forest@temp@child}{child anchor}%
@@ -5111,7 +6597,7 @@
\advance\pgf@xa-\pgf@x\relax\advance\pgf@ya-\pgf@y\relax
\edef\forest@marshal{%
\noexpand\pgftransformreset
- \noexpand\pgftransformrotate{-\forestove{grow}}%
+ \noexpand\forest@pgfqtransformrotate{-\forestove{grow}}%
\noexpand\pgfpointtransformed{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
}\forest@marshal
}%
@@ -5129,7 +6615,7 @@
\edef\forest@temp@firstchild{\forest@node@nornbarthchildid{\forestove{calign primary child}}}%
\edef\forest@temp@secondchild{\forest@node@nornbarthchildid{\forestove{calign secondary child}}}%
\pgftransformreset
- \pgftransformrotate{\forestove{grow}}%
+ \forest@pgfqtransformrotate{\forestove{grow}}%
\pgfpointtransformed{\pgfqpoint{\forestOve{\forest@temp@firstchild}{l}}{\forestOve{\forest@temp@firstchild}{s}}}%
\pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax
\forest@Pointanchor{\forest@temp@firstchild}{child anchor}%
@@ -5145,12 +6631,16 @@
\advance\pgf@xa-\pgf@x\relax\advance\pgf@ya-\pgf@y\relax
\edef\forest@marshal{%
\noexpand\pgftransformreset
- \noexpand\pgftransformrotate{-\forestove{grow}}%
+ \noexpand\forest@pgfqtransformrotate{-\forestove{grow}}%
\noexpand\pgfpointtransformed{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
}\forest@marshal
}%
\forest@calign@s@shift{\the\dimexpr-\the\pgf@y}%
}
+\def\forest@edef@strippt#1#2{%
+ \edef#1{#2}%
+ \edef#1{\expandafter\Pgf@geT#1}%
+}
\csdef{forest@calign@fixed angles}{%
\ifnum\forestove{n children}>1
\edef\forest@ca@first@child{\forest@node@nornbarthchildid{\forestove{calign primary child}}}%
@@ -5161,45 +6651,84 @@
\let\forest@ca@second@child\forest@temp
\fi
\forestOget{\forest@ca@first@child}{l}\forest@ca@first@l
+ \edef\forest@ca@first@l{\expandafter\Pgf@geT\forest@ca@first@l}%
\forestOget{\forest@ca@second@child}{l}\forest@ca@second@l
- \pgfmathsetlengthmacro\forest@ca@desired@s@distance{%
- tan(\forestove{calign secondary angle})*\forest@ca@second@l
- -tan(\forestove{calign primary angle})*\forest@ca@first@l
- }%
+ \edef\forest@ca@second@l{\expandafter\Pgf@geT\forest@ca@second@l}%
+ \pgfmathtan@{\forestove{calign secondary angle}}%
+ \pgfmathmultiply@{\pgfmathresult}{\forest@ca@second@l}%
+ \let\forest@calign@temp\pgfmathresult
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \pgfmathmultiply@{\pgfmathresult}{\forest@ca@first@l}%
+ \edef\forest@ca@desired@s@distance{\the\dimexpr
+ \forest@calign@temp pt-\pgfmathresult pt}%
+ % \pgfmathsetlengthmacro\forest@ca@desired@s@distance{%
+ % tan(\forestove{calign secondary angle})*\forest@ca@second@l
+ % -tan(\forestove{calign primary angle})*\forest@ca@first@l
+ % }%
\forestOget{\forest@ca@first@child}{s}\forest@ca@first@s
\forestOget{\forest@ca@second@child}{s}\forest@ca@second@s
- \pgfmathsetlengthmacro\forest@ca@actual@s@distance{%
+ \edef\forest@ca@actual@s@distance{\the\dimexpr
\forest@ca@second@s-\forest@ca@first@s}%
+ %\pgfmathsetlengthmacro\forest@ca@actual@s@distance{%
+ % \forest@ca@second@s-\forest@ca@first@s}%
\ifdim\forest@ca@desired@s@distance>\forest@ca@actual@s@distance\relax
\ifdim\forest@ca@actual@s@distance=0pt
- \pgfmathsetlength\pgfutil@tempdima{tan(\forestove{calign primary angle})*\forest@ca@second@l}%
- \pgfmathsetlength\pgfutil@tempdimb{\forest@ca@desired@s@distance/(\forestove{n children}-1)}%
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \pgfmathmultiply@{\pgfmathresult}{\forest@ca@second@l}%
+ \pgfutil@tempdima=\pgfmathresult pt
+ % \pgfmathsetlength\pgfutil@tempdima{tan(\forestove{calign primary angle})*\forest@ca@second@l}%
+ \pgfutil@tempdimb=\dimexpr
+ \forest@ca@desired@s@distance/(\forestove{n children}-1)\relax%
+ %\pgfmathsetlength\pgfutil@tempdimb{\forest@ca@desired@s@distance/(\forestove{n children}-1)}%
\forest@node@foreachchild{%
\forestoeset{s}{\the\pgfutil@tempdima}%
\advance\pgfutil@tempdima\pgfutil@tempdimb
}%
\def\forest@calign@anchor{0pt}%
\else
- \pgfmathsetmacro\forest@ca@ratio{%
- \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}%
+ \edef\forest@marshal{\noexpand\pgfmathdivide@
+ {\expandafter\Pgf@geT\forest@ca@desired@s@distance}%
+ {\expandafter\Pgf@geT\forest@ca@actual@s@distance}%
+ }\forest@marshal
+ \let\forest@ca@ratio\pgfmathresult
+ %\pgfmathsetmacro\forest@ca@ratio{%
+ % \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}%
\forest@node@foreachchild{%
- \pgfmathsetlengthmacro\forest@temp{\forest@ca@ratio*\forestove{s}}%
- \forestolet{s}\forest@temp
+ \forest@edef@strippt\forest@temp{\forestove{s}}%
+ \pgfmathmultiply@{\forest@ca@ratio}{\forest@temp}%
+ \forestoeset{s}{\the\dimexpr\pgfmathresult pt}%
+ %\pgfmathsetlengthmacro\forest@temp{\forest@ca@ratio*\forestove{s}}%
+ %\forestolet{s}\forest@temp
}%
- \pgfmathsetlengthmacro\forest@calign@anchor{%
- -tan(\forestove{calign primary angle})*\forest@ca@first@l}%
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \pgfmathmultiply@{\pgfmathresult}{\forest@ca@first@l}%
+ \edef\forest@calign@anchor{\the\dimexpr-\pgfmathresult pt}%
+ %\pgfmathsetlengthmacro\forest@calign@anchor{%
+ % -tan(\forestove{calign primary angle})*\forest@ca@first@l}%
\fi
\else
\ifdim\forest@ca@desired@s@distance<\forest@ca@actual@s@distance\relax
- \pgfmathsetlengthmacro\forest@ca@ratio{%
- \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}%
+ \edef\forest@marshal{\noexpand\pgfmathdivide@
+ {\expandafter\Pgf@geT\forest@ca@actual@s@distance}%
+ {\expandafter\Pgf@geT\forest@ca@desired@s@distance}%
+ }\forest@marshal
+ \let\forest@ca@ratio\pgfmathresult
+ %\pgfmathsetlengthmacro\forest@ca@ratio{%
+ % \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}%
\forest@node@foreachchild{%
- \pgfmathsetlengthmacro\forest@temp{\forest@ca@ratio*\forestove{l}}%
- \forestolet{l}\forest@temp
+ \forest@edef@strippt\forest@temp{\forestove{l}}%
+ \pgfmathmultiply@{\forest@ca@ratio}{\forest@temp}%
+ \forestoeset{l}{\the\dimexpr\pgfmathresult pt}%
+ %\pgfmathsetlengthmacro\forest@temp{\forest@ca@ratio*\forestove{l}}%
+ %\forestolet{l}\forest@temp
}%
\forestOget{\forest@ca@first@child}{l}\forest@ca@first@l
- \pgfmathsetlengthmacro\forest@calign@anchor{%
- -tan(\forestove{calign primary angle})*\forest@ca@first@l}%
+ \edef\forest@ca@first@l{\expandafter\Pgf@geT\forest@ca@first@l}%
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \pgfmathmultiply@{\pgfmathresult}{\forest@ca@first@l}%
+ \edef\forest@calign@anchor{\the\dimexpr-\pgfmathresult pt}%
+ %\pgfmathsetlengthmacro\forest@calign@anchor{%
+ % -tan(\forestove{calign primary angle})*\forest@ca@first@l}%
\fi
\fi
\forest@calign@s@shift{-\forest@calign@anchor}%
@@ -5225,64 +6754,123 @@
\forest@Pointanchor{\forest@ca@second@child}{child anchor}%
\edef\forest@ca@second@child@anchor@s{\the\pgf@x}%
\edef\forest@ca@second@child@anchor@l{\the\pgf@y}%
- \pgfmathsetlengthmacro\forest@ca@desired@second@edge@s{tan(\forestove{calign secondary angle})*%
- (\forest@ca@second@l-\forest@ca@second@child@anchor@l+\forest@ca@parent@anchor@l)}%
- \pgfmathsetlengthmacro\forest@ca@desired@first@edge@s{tan(\forestove{calign primary angle})*%
- (\forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l)}
- \pgfmathsetlengthmacro\forest@ca@desired@s@distance{\forest@ca@desired@second@edge@s-\forest@ca@desired@first@edge@s}%
+ \pgfmathtan@{\forestove{calign secondary angle}}%
+ \edef\forest@temp{\the\dimexpr
+ \forest@ca@second@l-\forest@ca@second@child@anchor@l+\forest@ca@parent@anchor@l}%
+ \pgfmathmultiply@{\pgfmathresult}{\expandafter\Pgf@geT\forest@temp}%
+ \edef\forest@ca@desired@second@edge@s{\the\dimexpr\pgfmathresult pt}%
+ %\pgfmathsetlengthmacro\forest@ca@desired@second@edge@s{%
+ % tan(\forestove{calign secondary angle})*%
+ % (\forest@ca@second@l-\forest@ca@second@child@anchor@l+\forest@ca@parent@anchor@l)}%
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \edef\forest@temp{\the\dimexpr
+ \forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l}%
+ \pgfmathmultiply@{\pgfmathresult}{\expandafter\Pgf@geT\forest@temp}%
+ \edef\forest@ca@desired@first@edge@s{\the\dimexpr\pgfmathresult pt}%
+ %\pgfmathsetlengthmacro\forest@ca@desired@first@edge@s{%
+ % tan(\forestove{calign primary angle})*%
+ % (\forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l)}%
+ \edef\forest@ca@desired@s@distance{\the\dimexpr
+ \forest@ca@desired@second@edge@s-\forest@ca@desired@first@edge@s}%
+ %\pgfmathsetlengthmacro\forest@ca@desired@s@distance{\forest@ca@desired@second@edge@s-\forest@ca@desired@first@edge@s}%
\forestOget{\forest@ca@first@child}{s}\forest@ca@first@s
\forestOget{\forest@ca@second@child}{s}\forest@ca@second@s
- \pgfmathsetlengthmacro\forest@ca@actual@s@distance{%
+ \edef\forest@ca@actual@s@distance{\the\dimexpr
\forest@ca@second@s+\forest@ca@second@child@anchor@s
-\forest@ca@first@s-\forest@ca@first@child@anchor@s}%
+ %\pgfmathsetlengthmacro\forest@ca@actual@s@distance{%
+ % \forest@ca@second@s+\forest@ca@second@child@anchor@s
+ % -\forest@ca@first@s-\forest@ca@first@child@anchor@s}%
\ifdim\forest@ca@desired@s@distance>\forest@ca@actual@s@distance\relax
\ifdim\forest@ca@actual@s@distance=0pt
\forestoget{n children}\forest@temp@n@children
\forest@node@foreachchild{%
\forest@pointanchor{child anchor}%
\edef\forest@temp@child@anchor@s{\the\pgf@x}%
- \pgfmathsetlengthmacro\forest@temp{%
- \forest@ca@desired@first@edge@s+(\forestove{n}-1)*\forest@ca@desired@s@distance/(\forest@temp@n@children-1)+\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}%
- \forestolet{s}\forest@temp
+ \forestoeset{s}{\the\dimexpr
+ \forest@ca@desired@first@edge@s+\forest@ca@desired@s@distance*(\forestove{n}-1)/(\forest@temp@n@children-1)+\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}%
+ %\pgfmathsetlengthmacro\forest@temp{%
+ % \forest@ca@desired@first@edge@s+(\forestove{n}-1)*\forest@ca@desired@s@distance/(\forest@temp@n@children-1)+\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}%
+ %\forestolet{s}\forest@temp
}%
\def\forest@calign@anchor{0pt}%
\else
- \pgfmathsetmacro\forest@ca@ratio{%
- \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}%
+ \edef\forest@marshal{\noexpand\pgfmathdivide@
+ {\expandafter\Pgf@geT\forest@ca@desired@s@distance}%
+ {\expandafter\Pgf@geT\forest@ca@actual@s@distance}%
+ }\forest@marshal
+ \let\forest@ca@ratio\pgfmathresult
+ %\pgfmathsetmacro\forest@ca@ratio{%
+ % \forest@ca@desired@s@distance/\forest@ca@actual@s@distance}%
\forest@node@foreachchild{%
\forest@pointanchor{child anchor}%
\edef\forest@temp@child@anchor@s{\the\pgf@x}%
- \pgfmathsetlengthmacro\forest@temp{%
- \forest@ca@ratio*(%
- \forestove{s}-\forest@ca@first@s
- +\forest@temp@child@anchor@s-\forest@ca@first@child@anchor@s)%
- +\forest@ca@first@s
+ \edef\forest@marshal{\noexpand\pgfmathmultiply@
+ {\forest@ca@ratio}%
+ {\expandafter\Pgf@geT\the\dimexpr
+ \forestove{s}-\forest@ca@first@s+%
+ \forest@temp@child@anchor@s-\forest@ca@first@child@anchor@s}%
+ }\forest@marshal
+ \forestoeset{s}{\the\dimexpr\pgfmathresult pt+\forest@ca@first@s
+\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}%
- \forestolet{s}\forest@temp
- }%
- \pgfmathsetlengthmacro\forest@calign@anchor{%
- -tan(\forestove{calign primary angle})*(\forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l)%
- +\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s
+ % \pgfmathsetlengthmacro\forest@temp{%
+ % \forest@ca@ratio*(%
+ % \forestove{s}-\forest@ca@first@s
+ % +\forest@temp@child@anchor@s-\forest@ca@first@child@anchor@s)%
+ % +\forest@ca@first@s
+ % +\forest@ca@first@child@anchor@s-\forest@temp@child@anchor@s}%
+ % \forestolet{s}\forest@temp
}%
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \edef\forest@marshal{\noexpand\pgfmathmultiply@
+ {\pgfmathresult}%
+ {\expandafter\Pgf@geT\the\dimexpr
+ \forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l}%
+ }\forest@marshal
+ \edef\forest@calign@anchor{\the\dimexpr
+ -\pgfmathresult pt+\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s}%
+ % \pgfmathsetlengthmacro\forest@calign@anchor{%
+ % -tan(\forestove{calign primary angle})*(\forest@ca@first@l-\forest@ca@first@child@anchor@l+\forest@ca@parent@anchor@l)%
+ % +\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s
+ % }%
\fi
\else
\ifdim\forest@ca@desired@s@distance<\forest@ca@actual@s@distance\relax
- \pgfmathsetlengthmacro\forest@ca@ratio{%
- \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}%
+ \edef\forest@marshal{\noexpand\pgfmathdivide@
+ {\expandafter\Pgf@geT\forest@ca@actual@s@distance}%
+ {\expandafter\Pgf@geT\forest@ca@desired@s@distance}%
+ }\forest@marshal
+ \let\forest@ca@ratio\pgfmathresult
+ %\pgfmathsetlengthmacro\forest@ca@ratio{%
+ % \forest@ca@actual@s@distance/\forest@ca@desired@s@distance}%
\forest@node@foreachchild{%
\forest@pointanchor{child anchor}%
\edef\forest@temp@child@anchor@l{\the\pgf@y}%
- \pgfmathsetlengthmacro\forest@temp{%
- \forest@ca@ratio*(%
- \forestove{l}+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l)
- -\forest@ca@parent@anchor@l+\forest@temp@child@anchor@l}%
- \forestolet{l}\forest@temp
+ \edef\forest@marshal{\noexpand\pgfmathmultiply@
+ {\forest@ca@ratio}%
+ {\expandafter\Pgf@geT\the\dimexpr\forestove{l}+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l}%
+ }\forest@marshal
+ \forestoeset{l}{\the\dimexpr
+ \pgfmathresult pt-\forest@ca@parent@anchor@l+\forest@temp@child@anchor@l}%
+ % \pgfmathsetlengthmacro\forest@temp{%
+ % \forest@ca@ratio*(%
+ % \forestove{l}+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l)
+ % -\forest@ca@parent@anchor@l+\forest@temp@child@anchor@l}%
+ % \forestolet{l}\forest@temp
}%
\forestOget{\forest@ca@first@child}{l}\forest@ca@first@l
- \pgfmathsetlengthmacro\forest@calign@anchor{%
- -tan(\forestove{calign primary angle})*(\forest@ca@first@l+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l)%
- +\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s
- }%
+ \pgfmathtan@{\forestove{calign primary angle}}%
+ \edef\forest@marshal{\noexpand\pgfmathmultiply@
+ {\pgfmathresult}%
+ {\expandafter\Pgf@geT\the\dimexpr
+ \forest@ca@first@l+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l}%
+ }\forest@marshal
+ \edef\forest@calign@anchor{\the\dimexpr
+ -\pgfmathresult pt+\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s}%
+ % \pgfmathsetlengthmacro\forest@calign@anchor{%
+ % -tan(\forestove{calign primary angle})*(\forest@ca@first@l+\forest@ca@parent@anchor@l-\forest@temp@child@anchor@l)%
+ % +\forest@ca@first@child@anchor@s-\forest@ca@parent@anchor@s
+ % }%
\fi
\fi
\forest@calign@s@shift{-\forest@calign@anchor}%
@@ -5323,7 +6911,7 @@
\eappto\forest@node@edge{\noexpand\pgfsyssoftpath@movetotoken{\forest@getedge@pa@l}{\forest@getedge@pa@s}}%
\pgfgettransform\forest@temp@transform
\pgftransformreset
- \pgftransformrotate{\forestove{grow}}%
+ \forest@pgfqtransformrotate{\forestove{grow}}%
\def\forest@all@edges{}%
\forest@node@foreachchild{%
\forestoget{#1@edge@#2}\forest@temp@edge
@@ -5897,8 +7485,12 @@
}\forest@marshal
}
\def\forest@node@computeabsolutepositions@#1#2#3{%
- \pgfpointadd{\pgfpoint{#1}{#2}}{%
- \pgfpointadd{\pgfpolar{#3}{\forestove{l}}}{\pgfpolar{90 + #3}{\forestove{s}}}}%
+ \pgfpointadd
+ {\pgfqpoint{#1}{#2}}%
+ {\pgfpointadd
+ {\pgfqpointpolar{#3}{\forestove{l}}}%
+ {\pgfqpointpolar{\numexpr 90+#3\relax}{\forestove{s}}}%
+ }%
\pgfgetlastxy\forest@temp@x\forest@temp@y
\forestolet{x}\forest@temp@x
\forestolet{y}\forest@temp@y
@@ -6052,7 +7644,7 @@
\newdimen\forest@ys
\def\forest@setupgrowline#1{%
\edef\forest@grow{#1}%
- \pgfpointpolar\forest@grow{1pt}%
+ \pgfqpointpolar{\forest@grow}{1pt}%
\forest@xg=\pgf@x
\forest@yg=\pgf@y
\forest@xs=-\pgf@y
@@ -6245,6 +7837,7 @@
\let\forest@previous@px\forest@px
\let\forest@previous@py\forest@py
}
+\patchcmd{\pgfpointintersectionoflines}{\pgfpoint}{\pgfqpoint}{}{}
\def\forest@getnegativetightedgeofpath#1#2{%
\forest@get@onetightedgeofpath#1\forest@sort@ascending#2}
\def\forest@getpositivetightedgeofpath#1#2{%
@@ -6458,7 +8051,11 @@
\pgf@x=0pt
\fi
\fi
- \csname pgfmathatan2\endcsname{\pgf@x}{\pgf@y}%
+ \edef\forest@marshal{%
+ \noexpand\pgfmathatantwo@
+ {\expandafter\Pgf@geT\the\pgf@x}%
+ {\expandafter\Pgf@geT\the\pgf@y}%
+ }\forest@marshal
\let\forest@current@atan\pgfmathresult
\ifx\forest@last@atan\relax
\def\forest@last@x{#1}%
@@ -6501,7 +8098,7 @@
}%
{%
\pgftransformreset
- \pgftransformrotate{\forest@grow}%
+ \forest@pgfqtransformrotate{\forest@grow}%
\forest@pgfpathtransformed\forest@gre@path
}%
\pgfsyssoftpath@getcurrentpath#2%
@@ -6514,7 +8111,7 @@
}%
{%
\pgftransformreset
- \pgftransformrotate{\forest@grow}%
+ \forest@pgfqtransformrotate{\forest@grow}%
\forest@pgfpathtransformed\forest@gre@path
}%
\pgfsyssoftpath@getcurrentpath#2%
@@ -6531,13 +8128,13 @@
}%
{%
\pgftransformreset
- \pgftransformrotate{\forest@grow}%
+ \forest@pgfqtransformrotate{\forest@grow}%
\forest@pgfpathtransformed\forest@gre@negpath
}%
\pgfsyssoftpath@getcurrentpath#2%
{%
\pgftransformreset
- \pgftransformrotate{\forest@grow}%
+ \forest@pgfqtransformrotate{\forest@grow}%
\forest@pgfpathtransformed\forest@gre@pospath
}%
\pgfsyssoftpath@getcurrentpath#3%
@@ -6751,7 +8348,7 @@
\def\forest@path@getboundingrectangle@ls#1#2{%
{%
\pgftransformreset
- \pgftransformrotate{-(#2)}%
+ \forest@pgfqtransformrotate{-#2}%
\forest@pgfpathtransformed#1%
}%
\pgfsyssoftpath@getcurrentpath\forest@gbr@rotatedpath
@@ -6775,6 +8372,17 @@
\ifdim#2<\pgf@ya\relax\pgf@ya=#2 \fi
\ifdim#2>\pgf@yb\relax\pgf@yb=#2 \fi
}
+\let\forest@pgfqtransformrotate\pgftransformrotate
+\let\forest@pgftransformcm\pgftransformcm
+\let\forest@pgf@transformcm\pgf@transformcm
+\patchcmd{\forest@pgfqtransformrotate}{\pgfmathparse{#1}}{\edef\pgfmathresult{\number\numexpr#1}}{}{}
+\patchcmd{\forest@pgfqtransformrotate}{\pgftransformcm}{\forest@pgftransformcm}{}{}
+\patchcmd{\forest@pgftransformcm}{\pgf@transformcm}{\forest@pgf@transformcm}{}{}
+\patchcmd{\forest@pgf@transformcm}{\pgfmathsetlength}{\forest@pgf@transformcm@setlength}{}{} % 4x
+\patchcmd{\forest@pgf@transformcm}{\pgfmathsetlength}{\forest@pgf@transformcm@setlength}{}{} % 4x
+\patchcmd{\forest@pgf@transformcm}{\pgfmathsetlength}{\forest@pgf@transformcm@setlength}{}{} % 4x
+\patchcmd{\forest@pgf@transformcm}{\pgfmathsetlength}{\forest@pgf@transformcm@setlength}{}{} % 4x
+\def\forest@pgf@transformcm@setlength#1#2{#1=#2pt}
\pgfkeys{/forest/external/.cd,
%copy command/.initial={cp "\source" "\target"},
copy command/.initial={},
@@ -6796,10 +8404,11 @@
}%
}{}%
}
+\newread\forest@copy@in
+\newwrite\forest@copy@out
\def\forest@file@copy@#1#2{%
- \newread\forest@copy@in
+ \begingroup
\openin\forest@copy@in=#1
- \newwrite\forest@copy@out
\immediate\openout\forest@copy@out#2
\endlinechar-1
\loop
@@ -6809,6 +8418,7 @@
\repeat
\immediate\closeout\forest@copy@out
\closein\forest@copy@in
+ \endgroup
}
\newif\ifforest@external@optimize@
\forest@external@optimize@true
@@ -6869,11 +8479,15 @@
\forest@next{#3}%
}
\def\forest@config#1{%
- \def\forest@stages{stages}%
+ \forest@defstages{stages}%
\forestset{@config/.cd,#1}%
}
+\def\forest@defstages#1{%
+ \def\forest@stages{#1}%
+}
\forestset{@config/.cd,
- stages/.store in=\forest@stages,
+ %stages/.store in=\forest@stages,
+ stages/.code={\forest@defstages{#1}},
.unknown/.code={\PackageError{forest}{Unknown config option for forest environment/command.}{In Forest v2.0.0 and v2.0.1, this (parenthesized) argument accepted the definition of style stages for the current forest environment/macro. Since v2.0.2, you should write "\string\begin{forest}(stages={...})...\string\end{forest}", or "\string\Forest(stages={...}){...}" instead.}}
}
\def\forest@group@env#1{{\forest@env{#1}}}
@@ -7094,9 +8708,9 @@
\pgfkeysvalueof{/pgf/inner xsep},\pgfkeysvalueof{/pgf/outer xsep}%
}
{
- l sep={\the\ht\strutbox+\pgfkeysvalueof{/pgf/inner ysep}},
+ l sep'/.expanded={\the\dimexpr\the\ht\strutbox+\pgfkeysvalueof{/pgf/inner ysep}},
l={l_sep()+abs(max_y()-min_y())+2*\pgfkeysvalueof{/pgf/outer ysep}},
- s sep={2*\pgfkeysvalueof{/pgf/inner xsep}}
+ s sep'/.expanded={\the\dimexpr \pgfkeysvalueof{/pgf/inner xsep}*2}
}
{l sep,l,s sep}
\pgfqkeys{/forest/@cs}{%
@@ -7111,11 +8725,11 @@
\forest@forestcs@resetxy},
anchor/.code={\forest@forestcs@anchor{#1}},
l/.code={%
- \pgfmathsetlengthmacro\forest@forestcs@l{#1}%
+ \forestmathsetlengthmacro\forest@forestcs@l{#1}%
\forest@forestcs@ls
},
s/.code={%
- \pgfmathsetlengthmacro\forest@forestcs@s{#1}%
+ \forestmathsetlengthmacro\forest@forestcs@s{#1}%
\forest@forestcs@ls
},
.unknown/.code={%
@@ -7130,16 +8744,16 @@
}
\def\forest@forestcs@resetxy{%
\ifnum\forest@cn=0 \forest@cs@invalidnodeerror\fi
- \global\pgf@x\forestove{x}%
- \global\pgf@y\forestove{y}%
+ \global\pgf@x\forestove{x}\relax
+ \global\pgf@y\forestove{y}\relax
}
\def\forest@forestcs@ls{%
\ifdefined\forest@forestcs@l
\ifdefined\forest@forestcs@s
{%
\pgftransformreset
- \pgftransformrotate{\forestove{grow}}%
- \pgfpointtransformed{\pgfpoint{\forest@forestcs@l}{\forest@forestcs@s}}%
+ \forest@pgfqtransformrotate{\forestove{grow}}%
+ \pgfpointtransformed{\pgfqpoint{\forest@forestcs@l}{\forest@forestcs@s}}%
}%
\global\advance\pgf@x\forestove{x}%
\global\advance\pgf@y\forestove{y}%
@@ -7233,10 +8847,18 @@
\forest@anchor@forwardtotikztrue
\forest@anchor@do{#1}{children}{\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{-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}%
@@ -7245,14 +8867,26 @@
\forest@anchor@forwardtotikztrue
\forest@anchor@do{#1}{parent 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}{%
+ \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{-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}%
@@ -7261,14 +8895,26 @@
\forest@anchor@forwardtotikztrue
\forest@anchor@do{#1}{children 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'}{%
+ \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{-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}%
@@ -7277,14 +8923,26 @@
\forest@anchor@forwardtotikztrue
\forest@anchor@do{#1}{parent 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'}{%
+ \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{-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}%
@@ -7293,6 +8951,10 @@
\forest@anchor@forwardtotikztrue
\forest@anchor@do{#1}{children 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}%
@@ -7322,9 +8984,19 @@
\forest@anchor@isbordertrue
\edef\forest@temp@anchor{\number\numexpr\forestove{grow}-\forestove{rotate}}%
}
+\csdef{forest@anchor@@-children'}{%
+ \forest@anchor@isbordertrue
+ \edef\forest@temp@anchor{\number\numexpr 180+\forestove{grow}-\forestove{rotate}}%
+}
\csdef{forest@anchor@@parent'}{%
\forest@anchor@isbordertrue
- \edef\forest@temp@anchor{\number\numexpr\forestove{grow}-\forestove{rotate}+180}%
+ \edef\forest@temp@grow{\ifnum\forestove{@parent}=0 \forestove{grow}\else\forestOve{\forestove{@parent}}{grow}\fi}%
+ \edef\forest@temp@anchor{\number\numexpr\forest@temp@grow-\forestove{rotate}+180}%
+}
+\csdef{forest@anchor@@-parent'}{%
+ \forest@anchor@isbordertrue
+ \edef\forest@temp@grow{\ifnum\forestove{@parent}=0 \forestove{grow}\else\forestOve{\forestove{@parent}}{grow}\fi}%
+ \edef\forest@temp@anchor{\number\numexpr\forest@temp@grow-\forestove{rotate}}%
}
\csdef{forest@anchor@@first'}{%
\forest@anchor@isbordertrue
@@ -7336,14 +9008,34 @@
}
\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}%
+ \edef\forest@temp@grow{\ifnum\forestove{@parent}=0 \forestove{grow}\else\forestOve{\forestove{@parent}}{grow}\fi}%
+ \edef\forest@temp@reversed{\ifnum\forestove{@parent}=0 \forestove{reversed}\else\forestOve{\forestove{@parent}}{reversed}\fi}%
+ \edef\forest@temp@anchor@parent{\number\numexpr\forest@temp@grow-\forestove{rotate}+180}%
+ \edef\forest@temp@anchor@first{\number\numexpr\forest@temp@grow-\forestove{rotate}\ifnum\forest@temp@reversed=0 -\else+\fi90}%
+ \forest@getaverageangle{\forest@temp@anchor@parent}{\forest@temp@anchor@first}\forest@temp@anchor
+}
+\csdef{forest@anchor@@-parent first'}{%
+ \forest@anchor@isbordertrue
+ \edef\forest@temp@grow{\ifnum\forestove{@parent}=0 \forestove{grow}\else\forestOve{\forestove{@parent}}{grow}\fi}%
+ \edef\forest@temp@reversed{\ifnum\forestove{@parent}=0 \forestove{reversed}\else\forestOve{\forestove{@parent}}{reversed}\fi}%
+ \edef\forest@temp@anchor@parent{\number\numexpr\forest@temp@grow-\forestove{rotate}}%
+ \edef\forest@temp@anchor@first{\number\numexpr\forest@temp@grow-\forestove{rotate}\ifnum\forest@temp@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}%
+ \edef\forest@temp@grow{\ifnum\forestove{@parent}=0 \forestove{grow}\else\forestOve{\forestove{@parent}}{grow}\fi}%
+ \edef\forest@temp@reversed{\ifnum\forestove{@parent}=0 \forestove{reversed}\else\forestOve{\forestove{@parent}}{reversed}\fi}%
+ \edef\forest@temp@anchor@parent{\number\numexpr\forest@temp@grow-\forestove{rotate}+180}%
+ \edef\forest@temp@anchor@last{\number\numexpr\forest@temp@grow-\forestove{rotate}\ifnum\forest@temp@reversed=0 +\else-\fi90}%
+ \forest@getaverageangle{\forest@temp@anchor@parent}{\forest@temp@anchor@last}\forest@temp@anchor
+}
+\csdef{forest@anchor@@-parent last'}{%
+ \forest@anchor@isbordertrue
+ \edef\forest@temp@grow{\ifnum\forestove{@parent}=0 \forestove{grow}\else\forestOve{\forestove{@parent}}{grow}\fi}%
+ \edef\forest@temp@reversed{\ifnum\forestove{@parent}=0 \forestove{reversed}\else\forestOve{\forestove{@parent}}{reversed}\fi}%
+ \edef\forest@temp@anchor@parent{\number\numexpr\forest@temp@grow-\forestove{rotate}}%
+ \edef\forest@temp@anchor@last{\number\numexpr\forest@temp@grow-\forestove{rotate}\ifnum\forest@temp@reversed=0 +\else-\fi90}%
\forest@getaverageangle{\forest@temp@anchor@parent}{\forest@temp@anchor@last}\forest@temp@anchor
}
\csdef{forest@anchor@@children first'}{%
@@ -7351,19 +9043,37 @@
\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 first'}{%
+ \forest@anchor@isbordertrue
+ \edef\forest@temp@anchor@first{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 -\else+\fi90}%
+ \forest@getaverageangle{180+\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 last'}{%
+ \forest@anchor@isbordertrue
+ \edef\forest@temp@anchor@last{\number\numexpr\forestove{grow}-\forestove{rotate}\ifnum\forestove{reversed}=0 +\else-\fi90}%
+ \forest@getaverageangle{180+\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@@-children}{%
+ \forest@anchor@snapbordertocompasstrue
+ \csuse{forest@anchor@@-children'}%
+}
\csdef{forest@anchor@@parent}{%
\forest@anchor@snapbordertocompasstrue
\csuse{forest@anchor@@parent'}%
}
+\csdef{forest@anchor@@-parent}{%
+ \forest@anchor@snapbordertocompasstrue
+ \csuse{forest@anchor@@-parent'}%
+}
\csdef{forest@anchor@@first}{%
\forest@anchor@snapbordertocompasstrue
\csuse{forest@anchor@@first'}%
@@ -7376,41 +9086,67 @@
\forest@anchor@snapbordertocompasstrue
\csuse{forest@anchor@@parent first'}%
}
+\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@@-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 first}{%
+ \forest@anchor@snapbordertocompasstrue
+ \csuse{forest@anchor@@-children first'}%
+}
\csdef{forest@anchor@@children last}{%
\forest@anchor@snapbordertocompasstrue
\csuse{forest@anchor@@children last'}%
}
+\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}%
-}
+ \expandafter\pgfmathMod@\expandafter{\forest@temp}{360}%
+ \forest@truncatepgfmathresult
+ \edef\forest@temp{\number\numexpr 360+#2+((\pgfmathresult-180)/2)}%
+ \expandafter\pgfmathMod@\expandafter{\forest@temp}{360}%
+ \forest@truncatepgfmathresult
+ \let#3\pgfmathresult
+}
+\def\forest@truncatepgfmathresult{%
+ \afterassignment\forest@gobbletoEND
+ \forest@temp@count=\pgfmathresult\forest@END
+ \def\pgfmathresult{\the\forest@temp@count}%
+}
+\def\forest@gobbletoEND#1\forest@END{}
\def\forest@anchor@border@to@compass{%
- \ifforest@anchor@isborder
+ \ifforest@anchor@isborder % snap to 45 deg, to range 0-360
\ifforest@anchor@snapbordertocompass
\forest@anchor@snap@border@to@compass
- \else
- \pgfmathMod{\forest@temp@anchor}{360}%
- \pgfmathtruncatemacro\forest@temp@anchor{\pgfmathresult}%
+ \else % to range 0-360
+ \pgfmathMod@{\forest@temp@anchor}{360}%
+ \forest@truncatepgfmathresult
+ \let\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
+ \ifforest@anchor@snapbordertocompass
+ \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
\letcs\forest@temp@anchor{forest@compass@\forest@temp@anchor}%
\fi
\fi
@@ -7426,11 +9162,12 @@
\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}%
+ \pgfmathMod@{\forest@temp@anchor}{360}%
+ \pgfmathdivide@{\pgfmathresult}{45}%
+ \pgfmathround@{\pgfmathresult}%
+ \pgfmathmultiply@{\pgfmathresult}{45}%
+ \forest@truncatepgfmathresult
+ \let\forest@temp@anchor\pgfmathresult
}
\def\forest@anchor@forward#1{% #1 = shape name
\ifdefempty\forest@temp@anchor{%
@@ -7452,34 +9189,32 @@
\if\relax#2\relax#1\fi
}
\expandafter\def\expandafter\forest@referencednodename@stripafter\expandafter#\expandafter1\forest@pgf@notyetpositioned\relax{#1}
+\def\forest@pointanchor#1{% #1 = anchor
+ \forest@Pointanchor{\forest@cn}{#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}%
+ \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}% this is expensive: so that's why caching
+ \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\relax\relax
+ }%
+ \end{pgfpicture}%
}%
\forest@global@marshal
}
-\def\forest@pointanchor#1{% #1 = anchor
- \forest@Pointanchor{\forest@cn}{#1}%
-}
\ifdefempty{\forest@compat}{}{%
\RequirePackage{forest-compat}
}