diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-09 22:36:53 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-09 22:36:53 +0000 |
commit | 375669e355bbc43b4650577c1a3d97ea26da6eb2 (patch) | |
tree | 33a52ca7f3403eb924c142d577848e97d2450cbb /Master/texmf-dist/tex/latex/forest | |
parent | 40f7f8ef844b86336acb970c200f1a3610da13a2 (diff) |
forest (9apr16)
git-svn-id: svn://tug.org/texlive/trunk@40367 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/forest')
-rw-r--r-- | Master/texmf-dist/tex/latex/forest/forest-compat.sty | 30 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/forest/forest-index.sty | 5 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/forest/forest.sty | 495 |
3 files changed, 391 insertions, 139 deletions
diff --git a/Master/texmf-dist/tex/latex/forest/forest-compat.sty b/Master/texmf-dist/tex/latex/forest/forest-compat.sty index 8921cf5405a..4245f103044 100644 --- a/Master/texmf-dist/tex/latex/forest/forest-compat.sty +++ b/Master/texmf-dist/tex/latex/forest/forest-compat.sty @@ -31,20 +31,24 @@ \forestset{@@deprecated/.code={\forest@deprecated{#1}}} \def\forestcompat#1{\pgfqkeys{/forest/@compat}{#1}} \forestcompat{ + silent/.style={\def\forest@deprecated##1{}}, + %%% begin listing region: compat_keys most/.style={1.0-most}, all/.style={1.0-all}, none/.style={}, - silent/.style={\def\forest@deprecated##1{}}, - %%% begin listing region: compat_1.0 1.0-most/.style={ 1.0-triangle,1.0-linear,1.0-nodewalk,1.0-ancestors, 1.0-fittotree,1.0-for,1.0-forall }, 1.0-all/.style={ 1.0-most, - 1.0-ignoreinvalidsteps,1.0-rotate,1.0-stages,1.0-name + 1.0-forstep,1.0-rotate,1.0-stages,1.0-name, + 2.0.2-all, }, - %%% end listing region: compat_1.0 + 2.0.2-all/.style={ + 2.0.2-delayn,2.0.2-wrapnpgfmathargs, + }, + %%% end listing region: compat_keys 1.0-triangle/.style={ /forest/triangle/.style={ @@deprecated={key "triangle" from v1.0.x. Use key "roof" from library "linguistics" instead}, @@ -100,7 +104,7 @@ @@deprecated={Key "for all previous" from v1.0.x. Use key "for preceding siblings" instead.}, for preceding siblings={##1}}, }, - 1.0-ignoreinvalidsteps/.code={% + 1.0-forstep/.code={% \def\forest@forstepwrapper##1##2{% \def\forest@nodewalk@config@everystep@method{independent}% \def\forest@nodewalk@config@history@method{independent}% @@ -166,5 +170,21 @@ }% }% }, + 2.0.2-delayn/.style={ + /forest/delay@n/.style 2 args={ + @@deprecated={propagator "delay n" (it introduces two levels of hash doubling)}, + if={##1==1}{delay={##2}}{delay={delay@n/.wrap pgfmath arg={{####1}{##2}}{##1-1}}} + }, + }, + 2.0.2-wrapnpgfmathargs/.code={ + \def\forest@wrap@pgfmath@args@@@wrapandpasson{% + \forest@deprecated{handler "wrap n pgfmath args" (it introduces two levels of hash doubling)}% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\forest@wrapped + \expandafter\expandafter\expandafter{% + \expandafter\forest@wrap@code\forest@wrap@args}% + \expandafter\pgfkeysalso\expandafter{\expandafter\pgfkeyscurrentpath\expandafter=\expandafter{\forest@wrapped}}% + }% + }, } \expandafter\forestcompat\expandafter{\forest@compat} diff --git a/Master/texmf-dist/tex/latex/forest/forest-index.sty b/Master/texmf-dist/tex/latex/forest/forest-index.sty index 116666290c4..e470d5ffe9e 100644 --- a/Master/texmf-dist/tex/latex/forest/forest-index.sty +++ b/Master/texmf-dist/tex/latex/forest/forest-index.sty @@ -371,12 +371,13 @@ ]>{@unknown} \def\forestindex@filename{\jobname.foridx} \IfFileExists{\forestindex@filename}{% - \input\forestindex@filename + \input\forestindex@filename\relax }{}% \newwrite\forestindex@out -\immediate\openout\forestindex@out=\forestindex@filename +\immediate\openout\forestindex@out=\forestindex@filename.tmp \AtEndDocument{% \immediate\closeout\forestindex@out + \forest@file@copy{\forestindex@filename.tmp}{\forestindex@filename}% } \endinput %% diff --git a/Master/texmf-dist/tex/latex/forest/forest.sty b/Master/texmf-dist/tex/latex/forest/forest.sty index a1746c66751..16c96a52e44 100644 --- a/Master/texmf-dist/tex/latex/forest/forest.sty +++ b/Master/texmf-dist/tex/latex/forest/forest.sty @@ -44,7 +44,7 @@ %% - LICENCE %% To use the package, only the files marked with + need to be installed. %% -\ProvidesPackage{forest}[2016/03/04 v2.0.2 Drawing (linguistic) trees] +\ProvidesPackage{forest}[2016/04/09 v2.0.3 Drawing (linguistic) trees] \RequirePackage{tikz}[2013/12/13] \usetikzlibrary{shapes} @@ -64,13 +64,13 @@ \newif\ifforest@external@ \newif\ifforesttikzcshack \newif\ifforest@install@keys@to@tikz@path@ -\newif\ifforestdebug +\newif\ifforestdebugnodewalks +\newif\ifforestdebugdynamics \def\forest@compat{} \forestset{package@options/.cd, external/.is if=forest@external@, tikzcshack/.is if=foresttikzcshack, tikzinstallkeys/.is if=forest@install@keys@to@tikz@path@, - debug/.is if=forestdebug, compat/.store in=\forest@compat, compat/.default=most, .unknown/.code={% load library @@ -79,6 +79,10 @@ \noexpand\forestapplylibrarydefaults{\pgfkeyscurrentname}% }% }, + debug/.code={\pgfqkeys{/forest/package@options/debug}{#1}}, + debug/.default={nodewalks,dynamics}, + debug/nodewalks/.is if=forestdebugnodewalks, + debug/dynamics/.is if=forestdebugdynamics, } \forest@install@keys@to@tikz@path@true \foresttikzcshacktrue @@ -985,6 +989,7 @@ \advance\forest@node@maxid1 \forest@fornode{\the\forest@node@maxid}{% \forest@node@init + \forestoeset{id}{\forest@cn}% \forest@node@setname{node@\forest@cn}% \forest@initializefromstandardnode \edef#1{\forest@cn}% @@ -996,6 +1001,7 @@ \def\forestoinit##1{\ifstrequal{##1}{name}{\forestoset{name}{node@\forest@cn}}{\forestoletO{##1}{#1}{##1}}}% \forest@fornode{\the\forest@node@maxid}{% \forest@node@init + \forestoeset{id}{\forest@cn}% \forest@node@setname{\forest@copy@name@template{\forestOve{#1}{name}}}% \edef#2{\forest@cn}% }% @@ -1461,7 +1467,6 @@ \forestOve{#1}{@next}% \fi } - \def\forest@node@linearpreviousid{% \ifnum\forestove{@previous}=0 \forestove{@parent}% @@ -1469,20 +1474,87 @@ \forest@node@previousleafid \fi } + \def\forest@ifancestorof#1{% is the current node an ancestor of #1? Yes: #2, no: #3 + \begingroup \expandnumberarg\forest@ifancestorof@{\forestOve{#1}{@parent}}% } -\def\forest@ifancestorof@#1#2#3{% +\def\forest@ifancestorof@#1{% \ifnum#1=0 - \def\forest@ifancestorof@next{\@secondoftwo}% + \def\forest@ifancestorof@next{\expandafter\endgroup\@secondoftwo}% \else \ifnum\forest@cn=#1 - \def\forest@ifancestorof@next{\@firstoftwo}% + \def\forest@ifancestorof@next{\expandafter\endgroup\@firstoftwo}% \else - \def\forest@ifancestorof@next{\expandnumberarg\forest@ifancestorof@{\forestOve{#1}{@parent}}}% + \ifcsdef{forest@circularity@used#1}{% + \def\forest@ifancestorof@next{\expandafter\endgroup\@secondoftwo}% + }{% + \csdef{forest@circularity@used#1}{}% + \def\forest@ifancestorof@next{\expandnumberarg\forest@ifancestorof@{\forestOve{#1}{@parent}}}% + }% \fi \fi - \forest@ifancestorof@next{#2}{#3}% + \forest@ifancestorof@next +} +\NewDocumentCommand\forestdebugtypeouttrees{o}{% + \forestdebug@typeouttrees\forest@temp + \typeout{\IfValueTF{#1}{#1: }{}\forest@temp}% +} +\def\forestdebug@typeouttrees#1{% #1 = cs to store the result + \begingroup + \edef\forest@temp@message{}% + \def\forestdebug@typeouttrees@n{0}% + \loop + \ifnum\forestdebug@typeouttrees@n<\forest@node@maxid + \edef\forestdebug@typeouttrees@n{\number\numexpr\forestdebug@typeouttrees@n+1}% + \ifcsdef{forestdebug@typeouttree@used@\forestdebug@typeouttrees@n}{}{% + \forest@fornode{\forestdebug@typeouttrees@n}{% + \begingroup + \forestdebug@typeouttrees@findroot + \expandafter\endgroup + \expandafter\edef\expandafter\forest@cn\expandafter{\forest@cn}% + \forestdebug@typeouttree@build + \appto\forest@temp@message{\space}% + }% + }% + \repeat + \expandafter\endgroup + \expandafter\edef\expandafter#1\expandafter{\forest@temp@message}% +} +\def\forestdebug@typeouttrees@findroot{% + \let\forestdebug@typeouttrees@next\relax + \edef\forestdebug@typeouttrees@parent{\forestOve{\forest@cn}{@parent}}% + \ifnum\forestdebug@typeouttrees@parent=0 + \else + \ifcsdef{forestdebug@typeouttree@used@\forest@cn}{}{% + \csdef{forestdebug@typeouttree@used@\forest@cn}{}% + \edef\forest@cn{\forestdebug@typeouttrees@parent}% + \let\forestdebug@typeouttrees@next\forestdebug@typeouttrees@findroot + }% + \fi + \forestdebug@typeouttrees@next +} +\def\forestdebug@typeouttree#1#2{% #1=root id, #2=cs to receive result + \begingroup + \edef\forest@temp@message{}% + \forest@fornode{#1}{\forestdebug@typeouttree@build}% + \expandafter\endgroup + \expandafter\edef\expandafter#2\expandafter{\forest@temp@message}% +} +\NewDocumentCommand\forestdebugtypeouttree{o m}{% + \forestdebug@typeouttree{#1}\forest@temp + \typeout{\IfValueTF{#1}{#1: }{}\forest@temp}% +} +\def\forestdebug@typeouttree@build{% + \eappto\forest@temp@message{[\forest@cn%] + \ifcsdef{forestdebug@typeouttree@used@\forest@cn}{*}{}% + }% + \ifcsdef{forestdebug@typeouttree@used@\forest@cn}{}{% + \csdef{forestdebug@typeouttree@used@\forest@cn}{}% + \forest@node@foreachchild{\forestdebug@typeouttree@build}% + }% + \eappto\forest@temp@message{%[ + ]}% } \def\forest@declarehandler#1#2#3{%#1=handler for specific type,#2=option name,#3=default value \pgfkeyssetvalue{/forest/#2}{#3}% @@ -1513,8 +1585,6 @@ \def\forest@declaretoks@handler@A#1#2#3#4#5{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix \pgfkeysalso{% #1/.code={\forestOset{\forest@setter@node}{#3}{##1}}, - #1+/.code={\forestOappto{\forest@setter@node}{#3}{#5##1}}, - #2/+#3/.code={\forestOpreto{\forest@setter@node}{#3}{##1#5}}, #2/if #3/.code n args={3}{% \forestoget{#3}\forest@temp@option@value \edef\forest@temp@compared@value{\unexpanded{##1}}% @@ -1537,6 +1607,31 @@ #2/where #3/.style n args={3}{for tree={#2/if #3={##1}{##2}{##3}}}, #2/where in #3/.style n args={3}{for tree={#2/if in #3={##1}{##2}{##3}}} }% + \ifstrempty{#5}{% + \pgfkeysalso{% + #1+/.code={\forestOappto{\forest@setter@node}{#3}{#5##1}}, + #2/+#3/.code={\forestOpreto{\forest@setter@node}{#3}{##1#5}}, + }% + }{% + \pgfkeysalso{% + #1+/.code={% + \forestOget{\forest@setter@node}{#3}\forest@temp + \ifdefempty{\forest@temp}{% + \forestOset{\forest@setter@node}{#3}{##1}% + }{% + \forestOappto{\forest@setter@node}{#3}{#5##1}% + }% + }, + #2/+#3/.code={% + \forestOget{\forest@setter@node}{#3}\forest@temp + \ifdefempty{\forest@temp}{% + \forestOset{\forest@setter@node}{#3}{##1}% + }{% + \forestOpreto{\forest@setter@node}{#3}{##1#5}% + }% + }% + }% + }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#2/+#3/option@name}{#3}% @@ -1555,6 +1650,11 @@ \pgfkeyssetvalue{#2/+#3'/option@name}{#3}% } \def\forest@declarereadonlydimen@handler#1#2#3#4{% #1=key,#2=path,#3=name,#4=pgfmathname + % this is to have `pt` with the correct category code + \pgfutil@tempdima=\pgfkeysvalueof{/forest/#3}\relax + \edef\forest@marshal{% + \noexpand\pgfkeyssetvalue{/forest/#3}{\the\pgfutil@tempdima}% + }\forest@marshal \pgfkeysalso{% #2/if #3/.code n args={3}{% \forestoget{#3}\forest@temp@option@value @@ -1749,20 +1849,35 @@ declare keylist/.code 2 args={% \forest@declarehandler\forest@declarekeylist@handler{#1}{#2}% }, - declare readonly dimen/.code={% - \forest@declarehandler\forest@declarereadonlydimen@handler{#1}{}% + declare readonly dimen/.code 2 args={% + \pgfmathsetlengthmacro\forest@temp{#2}% + \edef\forest@marshal{% + \unexpanded{\forest@declarehandler\forest@declarereadonlydimen@handler{#1}}{\forest@temp}% + }\forest@marshal }, declare dimen/.code 2 args={% - \forest@declarehandler\forest@declaredimen@handler{#1}{#2}% + \pgfmathsetlengthmacro\forest@temp{#2}% + \edef\forest@marshal{% + \unexpanded{\forest@declarehandler\forest@declaredimen@handler{#1}}{\forest@temp}% + }\forest@marshal }, - declare readonly count/.code={% - \forest@declarehandler\forest@declarereadonlycount@handler{#1}{}% + declare readonly count/.code 2 args={% + \pgfmathtruncatemacro\forest@temp{#2}% + \edef\forest@marshal{% + \unexpanded{\forest@declarehandler\forest@declarereadonlycount@handler{#1}}{\forest@temp}% + }\forest@marshal }, declare count/.code 2 args={% - \forest@declarehandler\forest@declarecount@handler{#1}{#2}% + \pgfmathtruncatemacro\forest@temp{#2}% + \edef\forest@marshal{% + \unexpanded{\forest@declarehandler\forest@declarecount@handler{#1}}{\forest@temp}% + }\forest@marshal }, declare boolean/.code 2 args={% - \forest@declarehandler\forest@declareboolean@handler{#1}{#2}% + \pgfmathtruncatemacro\forest@temp{#2}% + \edef\forest@marshal{% + \unexpanded{\forest@declarehandler\forest@declareboolean@handler{#1}}{\forest@temp}% + }\forest@marshal }, /handlers/.restore default value/.code={% \edef\forest@handlers@currentpath{\pgfkeyscurrentpath}% @@ -1796,16 +1911,16 @@ \pgfmathparse{#2}\let\forest@wrap@arg@i\pgfmathresult \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 \expandafter\expandafter\expandafter\forest@temp@toks\expandafter\expandafter\expandafter{\expandafter\forest@wrap@code\forest@wrap@args}% - \pgfkeysalso{\pgfkeyscurrentpath/.expand once=\the\forest@temp@toks}% + \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 \edef\forest@wrap@args{{\expandonce\forest@wrap@arg@i}{\expandonce\forest@wrap@arg@ii}}% \def\forest@wrap@code##1##2{#1}% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\forest@wrapped\expandafter\expandafter\expandafter{\expandafter\forest@wrap@code\forest@wrap@args}% - \pgfkeysalso{\pgfkeyscurrentpath/.expand once=\forest@wrapped}% + \forest@wrap@pgfmath@args@@@wrapandpasson }, /handlers/.wrap 3 pgfmath args/.code n args={4}{% \forest@wrap@n@pgfmath@args{#2}{#3}{#4}{}{}{}{}{}{3}% @@ -1860,8 +1975,15 @@ \or\def\forest@wrap@code##1##2##3##4##5##6##7{#1}% \or\def\forest@wrap@code##1##2##3##4##5##6##7##8{#1}% \fi - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\forest@wrapped\expandafter\expandafter\expandafter{\expandafter\forest@wrap@code\forest@wrap@args}% - \pgfkeysalso{\pgfkeyscurrentpath/.expand once=\forest@wrapped}% + \forest@wrap@pgfmath@args@@@wrapandpasson +} +\def\forest@wrap@pgfmath@args@@@wrapandpasson{% + \expandafter\expandafter\expandafter\forest@temp@toks + \expandafter\expandafter\expandafter{% + \expandafter\forest@wrap@code\forest@wrap@args}% + \expandafter\pgfkeysalso\expandafter{% + \expandafter\pgfkeyscurrentpath\expandafter=\expandafter{% + \the\forest@temp@toks}}% } \newtoks\forest@processargs@result \newtoks\forest@processargs@current @@ -1996,8 +2118,6 @@ \def\forest@declaretoksregister@handler@A#1#2#3#4#5{% #1=key,#2=path,#3=name,#4=pgfmathname,#5=infix \pgfkeysalso{% #1/.code={\forestrset{#3}{##1}}, - #1+/.code={\forestrappto{#3}{#5##1}}, - #2/+#3/.code={\forestrpreto{#3}{##1#5}}, #2/if #3/.code n args={3}{% \forestrget{#3}\forest@temp@option@value \edef\forest@temp@compared@value{\unexpanded{##1}}% @@ -2018,6 +2138,31 @@ \fi }, }% + \ifstrempty{#5}{% + \pgfkeysalso{% + #1+/.code={\forestrappto{#3}{#5##1}}, + #2/+#3/.code={\forestrpreto{#3}{##1#5}}, + }% + }{% + \pgfkeysalso{% + #1+/.code={% + \forestrget{#3}\forest@temp + \ifdefempty{\forest@temp}{% + \forestrset{#3}{##1}% + }{% + \forestrappto{#3}{#5##1}% + }% + }, + #2/+#3/.code={% + \forestrget{#3}\forest@temp + \ifdefempty{\forest@temp}{% + \forestrset{#3}{##1}% + }{% + \forestrpreto{#3}{##1#5}% + }% + }% + }% + }% \pgfkeyssetvalue{#1/option@name}{#3}% \pgfkeyssetvalue{#1+/option@name}{#3}% \pgfkeyssetvalue{#2/+#3/option@name}{#3}% @@ -2257,9 +2402,17 @@ declare dimen register=tempdimc,tempdimc'={0pt}, declare dimen register=tempdimd,tempdimd'={0pt}, declare dimen register=tempdimx,tempdimx'={0pt}, + declare dimen register=tempdimxa,tempdimxa'={0pt}, + declare dimen register=tempdimxb,tempdimxb'={0pt}, declare dimen register=tempdimy,tempdimy'={0pt}, + declare dimen register=tempdimya,tempdimya'={0pt}, + declare dimen register=tempdimyb,tempdimyb'={0pt}, declare dimen register=tempdiml,tempdiml'={0pt}, + declare dimen register=tempdimla,tempdimla'={0pt}, + declare dimen register=tempdimlb,tempdimlb'={0pt}, declare dimen register=tempdims,tempdims'={0pt}, + declare dimen register=tempdimsa,tempdimsa'={0pt}, + declare dimen register=tempdimsb,tempdimsb'={0pt}, declare count register=tempcounta,tempcounta'={0}, declare count register=tempcountb,tempcountb'={0}, declare count register=tempcountc,tempcountc'={0}, @@ -2309,7 +2462,13 @@ \@escapeif{\forest@node@setnameoralias{#1@\forest@cn}}% \else\@escapeif{% \if y\forest@temp@setname - \@escapeif{\forest@node@setnameoralias@nameclash{#1}}% + \edef\forest@marshal{% + \ifstrequal{\forestove{name}}{#1}% + }\forest@marshal{% + % same name, no problem + }{% + \@escapeif{\forest@node@setnameoralias@nameclash{#1}}% + }% \else\@escapeif{% setting an alias: clashing with alias is not a problem \forestOget{\forest@node@Nametoid{#1}}{name}\forest@temp \expandafter\ifstrequal\expandafter{\forest@temp}{#1}{% @@ -2489,10 +2648,11 @@ declare toks={edge label}{}, declare boolean={phantom}{0}, baseline/.style={alias={forest@baseline@node}}, - declare readonly count={n}, - declare readonly count={n'}, - declare readonly count={n children}, - declare readonly count={level}, + declare readonly count={id}{0}, + declare readonly count={n}{0}, + declare readonly count={n'}{0}, + declare readonly count={n children}{-1}, + declare readonly count={level}{-1}, declare dimen=x{0pt}, declare dimen=y{0pt}, declare dimen={s}{0pt}, @@ -2502,9 +2662,9 @@ declare keylist={node options}{anchor=base}, declare toks={tikz}{}, afterthought/.style={tikz+={#1}}, - label/.style={tikz={\path[late options={% + label/.style={tikz+={\path[late options={% name=\forestoption{name},label={#1}}];}}, - pin/.style={tikz={\path[late options={% + pin/.style={tikz+={\path[late options={% name=\forestoption{name},pin={#1}}];}}, declare toks={content format}{\forestoption{content}}, plain content/.style={content format={\forestoption{content}}}, @@ -2974,22 +3134,12 @@ \fi }% } -\pgfmathdeclarefunction{id}{1}{% +\pgfmathdeclarefunction*{id}{1}{% \forest@forthis{% \forest@nameandgo{#1}% \let\pgfmathresult\forest@cn }% } -\forestset{% - if id/.code n args={3}{% - \ifnum#1=\forest@cn\relax - \pgfkeysalso{#2}% - \else - \pgfkeysalso{#3}% - \fi - }, - where id/.style n args={3}{for tree={if id={#1}{#2}{#3}}} -} \def\forest@nodewalk@n{0} \def\forest@nodewalk@historyback{0,} \def\forest@nodewalk@historyforward{0,} @@ -3061,7 +3211,7 @@ \fi } \def\forest@nodewalk@makestep@oninvalid@step{\forest@nodewalk@makestep@} -\def\forest@nodewalk@makestep@oninvalid@error{\PackageError{forest}{nodewalk stepped to the invalid node; stack: "\forest@nodewalk@currentstepname"}{}}% +\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.}% @@ -3073,7 +3223,7 @@ \edef\forest@nodewalk@n{\number\numexpr\forest@nodewalk@n+1}% \epreto\forest@nodewalk@historyback{\forest@cn,}% \def\forest@nodewalk@historyforward{0,}% - \ifforestdebug\forest@nodewalk@makestep@debug\fi + \ifforestdebugnodewalks\forest@nodewalk@makestep@debug\fi \forest@process@keylist@register{every step}% \fi } @@ -3082,9 +3232,6 @@ \noexpand\typeout{\ifforest@nodewalk@fake fake \fi "\forest@nodewalk@currentstepname" step to node id=\forest@cn, content=\forestoption{content}}% }\forest@marshal }% -\forestset{ - debug/.is if=forestdebug, -} \def\forest@handlers@savecurrentpath{% \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% \let\forest@currentkey\pgfkeyscurrentkey @@ -3150,9 +3297,9 @@ \fi \pretotoks\forest@temp@toks{\appto\forest@nodewalk@currentstepname{,#1}}% \expandafter\forest@temp@toks\expandafter{\expandafter\forest@saveandrestoremacro\expandafter\forest@nodewalk@currentstepname\expandafter{\the\forest@temp@toks}}% - \ifforestdebug - \epretotoks\forest@temp@toks{\noexpand\typeout{Starting step "#1" from id=\forest@cn - \ifnum\forest@nodewalkstephandler@nargs>0 with args ####1\fi + \ifforestdebugnodewalks + \epretotoks\forest@temp@toks{\noexpand\typeout{Starting step "#1" from id=\noexpand\forest@cn + \ifnum\forest@nodewalkstephandler@nargs>0 \space with args ####1\fi \ifnum\forest@nodewalkstephandler@nargs>1 ,####2\fi \ifnum\forest@nodewalkstephandler@nargs>2 ,####3\fi \ifnum\forest@nodewalkstephandler@nargs>3 ,####4\fi @@ -3396,36 +3543,30 @@ %%% end nodewalk config } \forestset{ - define long step={branch}{n args=1,@bare,style}{% - branch@@build/.style={branch@build={##1}{}}, - @branch={#1}, - }, - define long step={branch'}{n args=1,@bare,style}{% - branch@@build/.style/.expanded={branch@build={####1}{\forestregister{every step},}}, - @branch={#1}, - }, - nodewalk/@branch/.style={ - TeX={\forest@temp@toks{}}, - split/.process args={r}{#1}{,}{branch@@build}, - branch@do, - }, - nodewalk/branch@build/.code 2 args={% #1 = nodewalk for this branch, #2 = perhaps every step keylist - \ifstrempty{#1}{}{% - \expandafter\ifstrempty\expandafter{\the\forest@temp@toks}{% - \edef\forest@marshal{% - \noexpand\forest@temp@toks{for nodewalk={\unexpanded{#1}}{\forestregister{every step}}}% - }\forest@marshal - }{% - \edef\forest@marshal{% - \noexpand\forest@temp@toks{for nodewalk={\unexpanded{#1}}{#2\the\forest@temp@toks}}% - }\forest@marshal - }% - }% + 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}}, + @branch/.style 2 args={% + save and restore register={branched@nodewalk}{ + branch@temp@toks={}, + split/.process args={r}{#1}{,}{#2}, + branch@temp@style/.style/.register=branch@temp@toks, + branch@temp@style, + branch@temp@style/.style/.register=branched@nodewalk, + branch@temp@style, + } }, - nodewalk/branch@do/.code={% - \edef\forest@marshal{% - \noexpand\pgfkeysalso{fake={\the\forest@temp@toks}}% - }\forest@marshal + nodewalk/branch@build@realstep/.style={% #1 = nodewalk for this branch + branch@temp@toks/.expanded={for nodewalk={\unexpanded{#1}}{ + branched@nodewalk+/.expanded={id=\noexpand\forestoption{id}}, + \forestregister{branch@temp@toks}}}, + }, + nodewalk/branch@build@fakestep/.style={% #1 = nodewalk for this branch + branch@temp@toks/.expanded={for nodewalk={\unexpanded{#1}}{ + \forestregister{branch@temp@toks}}}, }, define long step={group}{autostep}{\forest@go{#1}}, nodewalk/fake/.code={% @@ -3440,8 +3581,18 @@ \pgfkeysalso{#1}% }% }, + declare keylist register=filtered@nodewalk, + filtered@nodewalk={}, define long step={filter}{n args=2,@bare,style}{% #1 = nodewalk, #2 = condition - nodewalk/.expanded={\unexpanded{#1}}{if={\unexpanded{#2}}{\forestregister{every step}}{}}{} + save and restore register={filtered@nodewalk}{ + filtered@nodewalk'={}, + Nodewalk=% + {history=inherited}% + {#1}% + {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={}, @@ -4012,11 +4163,19 @@ }, define long step={level<}{n args=1}{% \pgfmathtruncatemacro\forest@temp{(#1)-1}% - \edef\forest@marshal{% - \noexpand\forest@node@foreach@breadthfirst - {\forest@temp}% - {\noexpand\forest@nodewalk@makestep}% - }\forest@marshal + \show\forest@temp + \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 + \forest@nodewalk@makestep + \fi + \else + \edef\forest@marshal{% + \noexpand\forest@node@foreach@breadthfirst + {\forest@temp}% + {\noexpand\forest@nodewalk@makestep}% + }\forest@marshal + \fi }, define long step={level reversed}{n args=1}{% \pgfmathtruncatemacro\forest@temp{#1}% @@ -4183,28 +4342,61 @@ \noexpand\forestrset{#1}{\forestregister{#1}}% }\forest@marshal } +\forestset{ + save and restore register/.code 2 args={% + \forest@saveandrestoreregister{filter@ed}{% + \pgfkeysalso{#2}% + }% + }, +} \def\forest@remove@node#1{% + \ifforestdebugdynamics\forestdebug@dynamics{before removing #1}\fi \forest@node@Remove{#1}% } \def\forest@append@node#1#2{% + \ifforestdebugdynamics\forestdebug@dynamics{before appending #2 to #1}\fi + \forest@dynamic@circularitytest{#2}{#1}{append}% \forest@node@Remove{#2}% \forest@node@Append{#1}{#2}% } \def\forest@prepend@node#1#2{% + \ifforestdebugdynamics\forestdebug@dynamics{before prepending #2 to #1}\fi + \forest@dynamic@circularitytest{#2}{#1}{prepend}% \forest@node@Remove{#2}% \forest@node@Prepend{#1}{#2}% } \def\forest@insertafter@node#1#2{% + \ifforestdebugdynamics\forestdebug@dynamics{before inserting #2 after #1}\fi \forest@node@Remove{#2}% \forest@node@Insertafter{\forestOve{#1}{@parent}}{#2}{#1}% } \def\forest@insertbefore@node#1#2{% + \ifforestdebugdynamics\forestdebug@dynamics{before inserting #2 before #1}\fi \forest@node@Remove{#2}% \forest@node@Insertbefore{\forestOve{#1}{@parent}}{#2}{#1}% } \def\forest@set@root#1#2{% + \ifforestdebugdynamics\forestdebug@dynamics{before setting #1 as root}\fi \def\forest@root{#2}% } +\def\forest@dynamic@circularitytest#1#2#3{% + % #1=potenitial ancestor,#2=potential descendant, #3=message prefix + \ifnum#1=#2 + \forest@circularityerror{#1}{#2}{#3}% + \else + \forest@fornode{#1}{% + \forest@ifancestorof{#2}{\forest@circularityerror{#1}{#2}{#3}}{}% + }% + \fi +} +\def\forest@circularityerror#1#2#3{% + \forestdebug@typeouttrees{\forest@temp}% + \PackageError{forest}{#3ing node id=#1 to id=#2 would result in a circular tree\MessageBreak forest of ids: \forest@temp}{}% +}% +\def\forestdebug@dynamics#1{% + \forestdebug@typeouttrees\forest@temp + \typeout{#1: \forest@temp}% +} \def\forest@appto@do@dynamics#1#2{% \forest@nodehandleby@name@nodewalk@or@bracket{#2}% \ifcase\forest@dynamics@copyhow\relax\or @@ -4294,8 +4486,10 @@ \fi } \def\forest@nodesort#1#2#3{% #1 = direction, #2 = parent node, #3 = sort key + \ifforestdebugdynamics\forestdebug@dynamics{before sorting children of #2}\fi \def\forest@nodesort@sortkey{#3}% \forest@fornode{#2}{\forest@nodesort@#1}% + \ifforestdebugdynamics\forestdebug@dynamics{after sorting children of #2}\fi } \def\forest@nodesort@#1{% % prepare the array of child ids @@ -4404,7 +4598,7 @@ declare keylist={delay}{}, delay n/.style 2 args={if={#1==0}{#2}{delay@n={#1}{#2}}}, delay@n/.style 2 args={ - if={#1==1}{delay={#2}}{delay={delay@n/.wrap pgfmath arg={{##1}{#2}}{#1-1}}} + if={#1==1}{delay={#2}}{delay={delay@n/.process args={P}{#1-1}{#2}}} }, if have delayed/.style 2 args={if have delayed'={processing order}{#1}{#2}}, if have delayed'/.code n args=3{% @@ -4468,10 +4662,21 @@ }, %%% end listing region: draw_tree_method draw tree node/.code={\forest@draw@node}, - draw tree edge/.code={\forest@draw@edge}, - draw tree tikz/.code={\forest@draw@tikz}, draw tree node'/.code={\forest@draw@node@}, + if node drawn/.code n args={3}{% + \forest@forthis{% + \forest@configured@nodewalk{independent}{inherited}{fake}{#1}{}% + \ifnum\forest@cn=0 + \forest@tempfalse + \else + \ifcsdef{forest@drawn@\forest@cn}{\forest@temptrue}{\forest@tempfalse}% + \fi + }% + \ifforest@temp\pgfkeysalso{#2}\else\pgfkeysalso{#3}\fi + }, + draw tree edge/.code={\forest@draw@edge}, draw tree edge'/.code={\forest@draw@edge@}, + draw tree tikz/.code={\forest@draw@tikz@}, % always! draw tree tikz'/.code={\forest@draw@tikz@}, processing order/.nodewalk style={tree}, %given options processing order/.style={processing order}, @@ -4598,16 +4803,16 @@ } \forestset{ - declare readonly dimen={min x}, - declare readonly dimen={min y}, - declare readonly dimen={max x}, - declare readonly dimen={max y}, + declare readonly dimen={min x}{0pt}, + declare readonly dimen={min y}{0pt}, + declare readonly dimen={max x}{0pt}, + declare readonly dimen={max y}{0pt}, } \def\forest@patch@enormouscoordinateboxbounds@plus#1{% - \expandafter\ifstrequal\expandafter{#1}{16000.0pt}{\def#1{0.0pt}}{}% + \expandafter\ifstrequal\expandafter{#1}{16000.0pt}{\edef#1{0.0\pgfmath@pt}}{}% } \def\forest@patch@enormouscoordinateboxbounds@minus#1{% - \expandafter\ifstrequal\expandafter{#1}{-16000.0pt}{\def#1{0.0pt}}{}% + \expandafter\ifstrequal\expandafter{#1}{-16000.0pt}{\edef#1{0.0\pgfmath@pt}}{}% } \def\forest@positionnodelater@save{% \global\setbox\forest@box=\box\pgfpositionnodelaterbox @@ -4649,28 +4854,30 @@ \pgfsyssoftpath@setcurrentpath\forest@pack@original@path } \def\forest@@pack{% - \ifnum\forestove{n children}>0 - \ifnum\forestove{uniform growth}>0 + \ifnum\forestove{uniform growth}>0 + \ifnum\forestove{n children}>0 \forest@pack@level@uniform \forest@pack@aligntiers@ofsubtree \forest@pack@sibling@uniform@recursive - \else - \forest@node@foreachchild{\forest@@pack}% - \forest@process@hook@keylist@nodynamics{before packing node}{current}% + \fi + \else + \forest@node@foreachchild{\forest@@pack}% + \forest@process@hook@keylist@nodynamics{before packing node}{current}% + \ifnum\forestove{n children}>0 \forest@pack@level@nonuniform \forest@pack@aligntiers \forest@pack@sibling@uniform@applyreversed \fi + \forestoget{after packing node}\forest@temp@keys + \forest@process@hook@keylist@nodynamics{after packing node}{current}% \fi - \forestoget{after packing node}\forest@temp@keys - \forest@process@hook@keylist@nodynamics{after packing node}{current}% } \def\forest@pack@onlythisnode{% \ifnum\forestove{n children}>0 \forest@pack@computetiers \forest@pack@level@nonuniform \forest@pack@aligntiers - \forest@node@foreachchild{\forestoset{s}{0pt}}% + \forest@node@foreachchild{\forestoset{s}{0\pgfmath@pt}}% \forest@pack@sibling@uniform@applyreversed \fi } @@ -4823,7 +5030,7 @@ \let\forest@previous@positive@edge\pgfutil@empty \forest@extendpath\forest@previous@positive@edge\forest@temp@edge{}% \forestOget{\forest@child}{@#3}\forest@child - \edef\forest@previous@child@s{0pt}% + \edef\forest@previous@child@s{0\pgfmath@pt}% \safeloop \unless\ifnum\forest@child=0 \edef\forest@temp{% @@ -5780,6 +5987,7 @@ } \def\forest@drawtree@root{0} \def\forest@node@drawtree@{% + \def\forest@clear@drawn{}% \forest@forthis{% \forest@saveandrestoremacro\forest@drawtree@root{% \edef\forest@drawtree@root{\forest@cn}% @@ -5787,14 +5995,18 @@ }% }% \forest@node@Ifnamedefined{forest@baseline@node}{% - \edef\forest@temp{% - \noexpand\pgfsetbaselinepointlater{% - \noexpand\pgfpointanchor - {\forestOve{\forest@node@Nametoid{forest@baseline@node}}{name}} - {\forestOve{\forest@node@Nametoid{forest@baseline@node}}{anchor}} - }% - }\forest@temp + \edef\forest@baseline@id{\forest@node@Nametoid{forest@baseline@node}}% + \ifcsdef{forest@drawn@\forest@baseline@id}{% + \edef\forest@marshal{% + \noexpand\pgfsetbaselinepointlater{% + \noexpand\pgfpointanchor + {\forestOve{\forest@baseline@id}{name}}% + {\forestOve{\forest@baseline@id}{anchor}}% + }% + }\forest@marshal + }{}% }{}% + \forest@clear@drawn } \def\forest@draw@node{% \ifnum\forestove{phantom}=0 @@ -5810,15 +6022,18 @@ \ifforest@drawtree@preservenodeboxes@ \pgfnodealias{\forestove{later@name}}{forest@temp}% \fi + \csdef{forest@drawn@\forest@cn}{}% + \eappto\forest@clear@drawn{\noexpand\csundef{forest@drawn@\forest@cn}}% } \def\forest@draw@edge{% - \ifnum\forest@cn=\forest@drawtree@root\relax\else - \ifnum\forestove{phantom}=0 - \ifnum\forestOve{\forestove{@parent}}{phantom}=0 + \ifcsdef{forest@drawn@\forest@cn}{% was the current node drawn? + \ifnum\forestove{@parent}=0 % do we have a parent? + \else + \ifcsdef{forest@drawn@\forestove{@parent}}{% was the parent drawn? \forest@draw@edge@ - \fi + }{}% \fi - \fi + }{}% } \def\forest@draw@edge@{% \edef\forest@temp{\forestove{edge path}}\forest@temp @@ -6561,24 +6776,39 @@ \ifdim#2>\pgf@yb\relax\pgf@yb=#2 \fi } \pgfkeys{/forest/external/.cd, - copy command/.initial={cp "\source" "\target"}, + %copy command/.initial={cp "\source" "\target"}, + copy command/.initial={}, optimize/.is if=forest@external@optimize@, context/.initial={% \forestOve{\csname forest@id@of@standard node\endcsname}{environment@formula}}, depends on macro/.style={context/.append/.expanded={% \expandafter\detokenize\expandafter{#1}}}, } -\def\forest@external@copy#1#2{% - \pgfkeysgetvalue{/forest/external/copy command}\forest@copy@command - \ifx\forest@copy@command\pgfkeysnovalue\else - \IfFileExists{#1}{% - {% - \def\source{#1}% - \def\target{#2}% - \immediate\write18{\forest@copy@command}% - }% - }{}% - \fi +\def\forest@file@copy#1#2{% + \IfFileExists{#1}{% + \pgfkeysgetvalue{/forest/external/copy command}\forest@copy@command + \ifdefempty\forest@copy@command{% + \forest@file@copy@{#1}{#2}% + }{ % copy by external command + \def\source{#1}% + \def\target{#2}% + \immediate\write18{\forest@copy@command}% + }% + }{}% +} +\def\forest@file@copy@#1#2{% + \newread\forest@copy@in + \openin\forest@copy@in=#1 + \newwrite\forest@copy@out + \immediate\openout\forest@copy@out#2 + \endlinechar-1 + \loop + \unless\ifeof\forest@copy@in + \readline\forest@copy@in to\forest@temp + \immediate\write\forest@copy@out{\forest@temp}% + \repeat + \immediate\closeout\forest@copy@out + \closein\forest@copy@in } \newif\ifforest@external@optimize@ \forest@external@optimize@true @@ -6601,13 +6831,13 @@ /pgf/images/aux in dpth=false, }% \tikzifexternalizing{}{% - \forest@external@copy{\jobname.aux}{\jobname.aux.copy}% + \forest@file@copy{\jobname.aux}{\jobname.aux.copy}% }% \AtBeginDocument{% \tikzifexternalizing{% \IfFileExists{\tikzexternalrealjob.aux.copy}{% \makeatletter - \input \tikzexternalrealjob.aux.copy + \input\tikzexternalrealjob.aux.copy\relax \makeatother }{}% }{% @@ -6617,14 +6847,14 @@ \IfFileExists{\tikzexternalrealjob.for}{% {% \makehashother\makeatletter - \input \tikzexternalrealjob.for + \input\tikzexternalrealjob.for\relax }% }{}% }% \AtEndDocument{% \tikzifexternalizing{}{% \immediate\closeout\forest@auxout - \forest@external@copy{\jobname.for.tmp}{\jobname.for}% + \forest@file@copy{\jobname.for.tmp}{\jobname.for}% }% }% \fi @@ -6810,6 +7040,7 @@ \advance\forest@node@maxid1 \forest@fornode{\the\forest@node@maxid}{% \forest@node@init + \forestoeset{id}{\forest@cn}% \forest@node@setname@silent{standard node}% }% } |