From 57d833d68da94cb5a1cc5e675f9e21f1681e59d0 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 4 Feb 2017 00:23:35 +0000 Subject: forest (3feb17) git-svn-id: svn://tug.org/texlive/trunk@43129 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/forest/README | 2 +- Master/texmf-dist/doc/latex/forest/forest-doc.pdf | Bin 1314346 -> 1212416 bytes Master/texmf-dist/doc/latex/forest/forest-doc.tex | 18 +++ Master/texmf-dist/doc/latex/forest/forest.pdf | Bin 496508 -> 498559 bytes Master/texmf-dist/source/latex/forest/forest.dtx | 169 +++++++++++----------- Master/texmf-dist/tex/latex/forest/forest.sty | 113 +++++++++------ 6 files changed, 168 insertions(+), 134 deletions(-) (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/forest/README b/Master/texmf-dist/doc/latex/forest/README index fbe9a4aee3c..df173068679 100644 --- a/Master/texmf-dist/doc/latex/forest/README +++ b/Master/texmf-dist/doc/latex/forest/README @@ -1,4 +1,4 @@ -LaTeX package: forest [2017/01/27 v2.1.3 Drawing (linguistic) trees] +LaTeX package: forest [2017/02/02 v2.1.4 Drawing (linguistic) trees] Copyright (c) 2012-2017 Saso Zivanovic (Sa\v{s}o \v{Z}ivanovi\'{c}) diff --git a/Master/texmf-dist/doc/latex/forest/forest-doc.pdf b/Master/texmf-dist/doc/latex/forest/forest-doc.pdf index 78e647869a9..53f21b9e28b 100644 Binary files a/Master/texmf-dist/doc/latex/forest/forest-doc.pdf and b/Master/texmf-dist/doc/latex/forest/forest-doc.pdf differ diff --git a/Master/texmf-dist/doc/latex/forest/forest-doc.tex b/Master/texmf-dist/doc/latex/forest/forest-doc.tex index 579f0a9a433..a4c73212316 100644 --- a/Master/texmf-dist/doc/latex/forest/forest-doc.tex +++ b/Master/texmf-dist/doc/latex/forest/forest-doc.tex @@ -6409,7 +6409,25 @@ in |-all| styles. \subsubsection{v2.1} \begin{description} +\item[v2.1.4 (2017/02/02)] \mbox{} + + Performance: + \begin{itemize} + \item Reimplement some internals of the packing algorithm to avoid consuming the string pool in + documents with many trees. (We're about 10\% slower now, but (depending on the document) the + memory usage can drop up to five times!) + \end{itemize} + + Bugfixes: + \begin{itemize} + \item Fix aggregate function \index{aggregate>count}. + \item Provide a workaround for a PGF bug: for coordinate-shaped nodes, |\positionnodelater| + provides dimensions with |pt| in a wrong catcode, so \index{max y} and friends did not work for + such nodes. + \end{itemize} + \item[v2.1.3 (2017/01/27)] \mbox{} + Bugfixes: \begin{itemize} \item Update \index{nice empty nodes} to use \index{for step=\index{current and siblings}}. diff --git a/Master/texmf-dist/doc/latex/forest/forest.pdf b/Master/texmf-dist/doc/latex/forest/forest.pdf index 0bd16e0ba26..d8d7cacbf42 100644 Binary files a/Master/texmf-dist/doc/latex/forest/forest.pdf and b/Master/texmf-dist/doc/latex/forest/forest.pdf differ diff --git a/Master/texmf-dist/source/latex/forest/forest.dtx b/Master/texmf-dist/source/latex/forest/forest.dtx index 01ae642c752..6f0f6bfae1a 100644 --- a/Master/texmf-dist/source/latex/forest/forest.dtx +++ b/Master/texmf-dist/source/latex/forest/forest.dtx @@ -1,4 +1,4 @@ -% \CheckSum{16610} +% \CheckSum{16623} % \iffalse meta-comment % forest.dtx %% `forest' is a `pgf/tikz'-based package for drawing (linguistic) trees. @@ -83,7 +83,7 @@ % % \section{Identification} % \begin{macrocode} -\ProvidesPackage{forest}[2017/01/27 v2.1.3 Drawing (linguistic) trees] +\ProvidesPackage{forest}[2017/02/02 v2.1.4 Drawing (linguistic) trees] \RequirePackage{tikz}[2013/12/13] \usetikzlibrary{shapes} @@ -2988,8 +2988,8 @@ \expandafter\endgroup \expandafter\edef\expandafter#2\expandafter{\forest@temp@message}% } -\NewDocumentCommand\forestdebugtypeouttree{o m}{% - \forestdebug@typeouttree{#1}\forest@temp +\NewDocumentCommand\forestdebugtypeouttree{d() O{\forest@cn}}{% + \forestdebug@typeouttree{#2}\forest@temp \typeout{\IfValueTF{#1}{#1: }{}\forest@temp}% } % \end{macrocode} @@ -5117,10 +5117,10 @@ {#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}% + {\def\forestmathresult{0}\let\forestmathresulttype\forestmathtype@count}% + {\def\forestmathresult{1}\let\forestmathresulttype\forestmathtype@count}% + {\edef\forestmathresult{\the\numexpr\forestregister{aggregate result}+1}\let\forestmathresulttype\forestmathtype@count}% + {\forestrget{aggregate result}\forestmathresult\let\forestmathresulttype\forestmathtype@count}% {#1}% } \def\forest@aggregate@average#1#2{\forest@aggregate @@ -7139,10 +7139,17 @@ \forest@patch@enormouscoordinateboxbounds@minus\pgfpositionnodelatermaxx \forest@patch@enormouscoordinateboxbounds@minus\pgfpositionnodelatermaxy % end of patch - \xappto\forest@smuggle{\noexpand\forestoset{min x}{\pgfpositionnodelaterminx}}% - \xappto\forest@smuggle{\noexpand\forestoset{min y}{\pgfpositionnodelaterminy}}% - \xappto\forest@smuggle{\noexpand\forestoset{max x}{\pgfpositionnodelatermaxx}}% - \xappto\forest@smuggle{\noexpand\forestoset{max y}{\pgfpositionnodelatermaxy}}% + % when shape=coordinate, pgf returns \pgfpositionnodelater... with wrong catcode of pt + \forest@pnn@addtosmuggle{min x}\pgfpositionnodelaterminx + \forest@pnn@addtosmuggle{max x}\pgfpositionnodelatermaxx + \forest@pnn@addtosmuggle{min y}\pgfpositionnodelaterminy + \forest@pnn@addtosmuggle{max y}\pgfpositionnodelatermaxy +} +\def\forest@pnn@addtosmuggle#1#2{% + {% + \pgfutil@tempdima=#2\relax + \xappto\forest@smuggle{\noexpand\forestoset{#1}{\the\pgfutil@tempdima}}% + }% } \def\forest@node@forest@positionnodelater@restore{% \ifforest@drawtree@preservenodeboxes@ @@ -8819,7 +8826,7 @@ % original point; |d| is its distance to the grow line. The inner % array is not sorted. % \end{itemize} -% \item A dictionary |#2|: keys are the coordinates |(x,y)| of +% \item A ``dictionary'' |#3|: keys are the coordinates |(x,y)| of % the original points; a value is the index of the original point's % projection in array |#2|.\footnote{At first sight, this % information could be cached ``at the source'': by @@ -8827,10 +8834,12 @@ % intersecting (in breakpath), we cheat and merge very adjacent % projection points, expecting that the points to project to the % merged projection point. All this depends on the given path, so a -% generic cache is not feasible.} +% generic cache is not feasible.} In v2.1.4, the ``dictionary'' was +% reimplemented using a toks register, to prevent using up the string +% pool; that's when |#3| was introduced. % \end{itemize} % \begin{macrocode} -\def\forest@processprojectioninfo#1#2{% +\def\forest@processprojectioninfo#1#2#3{% \edef\forest@ppi@inputprefix{#1}% % \end{macrocode} % Loop (counter |\c@pgf@counta|) through the sorted array of raw data. @@ -8867,7 +8876,7 @@ \csdef{#2\the\c@pgf@countb @n}{0}% \fi % \end{macrocode} -% If the projection is actually a projection of one a point in our path: +% If the projection is actually a projection of one point in our path (it will not be when this macro is called from |\forest@distance@between@edge@paths|): % \begin{macrocode} % todo: this is ugly! \ifdefined\forest@xo\ifx\forest@xo\relax\else @@ -8883,12 +8892,13 @@ % Put a new item in the dictionary: key = the original point, value = % the projection index. % \begin{macrocode} - \csedef{#2(\forest@xo,\forest@yo)}{\the\c@pgf@countb}% + \eapptotoks#3{(\forest@xo,\forest@yo){\the\c@pgf@countb}}% \fi\fi \fi\fi % \end{macrocode} % Clean-up the raw array item. % \begin{macrocode} + % todo: is this really necessary? (yes: see the "ugly" thing above) \cslet{#1\the\c@pgf@counta xo}\relax \cslet{#1\the\c@pgf@counta yo}\relax \cslet{#1\the\c@pgf@counta xp}\relax @@ -8898,6 +8908,7 @@ % \end{macrocode} % Clean up the raw array length. % \begin{macrocode} + % todo: is this really necessary? \cslet{#1n}\relax % \end{macrocode} % Store the length of the outer result array. @@ -8907,7 +8918,7 @@ } % \end{macrocode} % -% Item-exchange macro for quicksorting the raw projection data. (|#1| +% Item-exchange macro for sorting the raw projection data. (|#1| % is copied into |#2|.) % \begin{macrocode} \def\forest@ppiraw@let#1#2{% @@ -8917,7 +8928,7 @@ \csletcs{\forest@ppi@inputprefix#1yp}{\forest@ppi@inputprefix#2yp}% } % \end{macrocode} -% Item comparision macro for quicksorting the raw projection data. +% Item comparision macro for sorting the raw projection data. % \begin{macrocode} \def\forest@ppiraw@cmp#1#2{% \forest@sort@cmptwodimcs @@ -8943,7 +8954,7 @@ % \subsection{Break path} % % The following macro computes from the given path (|#1|) a ``broken'' -% path (|#3|) that contains the same points of the plane, but has +% path (|#4|) that contains the same points of the plane, but has % potentially more segments, so that, for every point from a given set % of points on the grow line, a line through this point perpendicular % to the grow line intersects the broken path only at its edge @@ -8952,24 +8963,26 @@ % The macro works only for \emph{simple} paths, i.e.\ paths built % using only move-to and line-to operations. Furthermore, % |\forest@processprojectioninfo| must be called before calling -% |\forest@breakpath|: we expect information with prefix |#2|. The -% macro updates the information compiled by -% |\forest@processprojectioninfo| with information about points added -% by path-breaking. +% |\forest@breakpath|: we expect information in an array with prefix +% |#2| (projections and (an inner array of) their original points) +% and toks register |#3| (a ``dictionary'': for each original points, +% the index of its projection in |#2|). The macro updates array |#2|. +% (No need to update |#3|, as it is not used anymore.) % \begin{macrocode} -\def\forest@breakpath#1#2#3{% +\def\forest@breakpath#1#2#3#4{% % \end{macrocode} % Store the current path in a macro and empty it, then process the % stored path. The processing creates a new current path. % \begin{macrocode} \edef\forest@bp@prefix{#2}% + \let\forest@breakpath@toks#3% \forest@save@pgfsyssoftpath@tokendefs \let\pgfsyssoftpath@movetotoken\forest@breakpath@processfirstpoint \let\pgfsyssoftpath@linetotoken\forest@breakpath@processfirstpoint %\pgfusepath{}% empty the current path. ok? #1% \forest@restore@pgfsyssoftpath@tokendefs - \pgfsyssoftpath@getcurrentpath#3% + \pgfsyssoftpath@getcurrentpath#4% } % \end{macrocode} % The original and the broken path start in the same way. (This code @@ -8991,13 +9004,18 @@ \pgfsyssoftpath@moveto{#1}{#2}% \def\forest@previous@x{#1}% \def\forest@previous@y{#2}% - \expandafter\let\expandafter\forest@previous@i - \csname\forest@bp@prefix(#1,#2)\endcsname + \forest@breakpath@getfromtoks\forest@breakpath@toks\forest@previous@i{#1}{#2}% \expandafter\let\expandafter\forest@previous@px \csname\forest@bp@prefix\forest@previous@i x\endcsname \expandafter\let\expandafter\forest@previous@py \csname\forest@bp@prefix\forest@previous@i y\endcsname } +\def\forest@breakpath@getfromtoks#1#2#3#4{% + % #1=cache toks register, #2=receiving cs, (#3,#4)=point; + % we rely on the fact that the point we're looking up should always be present + \def\forest@breakpath@getfromtoks@##1(#3,#4)##2##3\forest@END{##2}% + \edef#2{\expandafter\forest@breakpath@getfromtoks@\the#1\forest@END}% +} % \end{macrocode} % % This is the heart of the path-breaking procedure. @@ -9012,8 +9030,7 @@ % Get the index of the current point's projection and the projection % itself. (The point dictionary is used here.) % \begin{macrocode} - \expandafter\let\expandafter\forest@i - \csname\forest@bp@prefix(#1,#2)\endcsname + \forest@breakpath@getfromtoks\forest@breakpath@toks\forest@i{#1}{#2}% \expandafter\let\expandafter\forest@px \csname\forest@bp@prefix\forest@i x\endcsname \expandafter\let\expandafter\forest@py @@ -9084,10 +9101,6 @@ \forest@append@point@to@inner@array \forest@last@x\forest@last@y {\forest@bp@prefix\the\forest@temp@count @}% -% \end{macrocode} -% Cache the projection of the new segment edge. -% \begin{macrocode} - \csedef{\forest@bp@prefix(\the\pgf@x,\the\pgf@y)}{\the\forest@temp@count}% \saferepeat \fi % \end{macrocode} @@ -9118,7 +9131,7 @@ % % Imagine an infinitely long light source parallel to the grow line, % on the grow line's negative/positive side.\footnote{For the -% definition of negative/positive side, see forest@distancetogrowline +% definition of negative/positive side, see {\tt\string\forest@distancetogrowline} % in \S\ref{imp:projections}} Furthermore imagine that the path is % opaque. Then the negative/positive tight edge of the path is the % part of the path that is illuminated. @@ -9144,22 +9157,24 @@ }% \let#3\forest@gep@global@edge } +\newtoks\forest@pi@toks +\newtoks\forest@segment@toks \def\forest@get@one@tightedgeofpath#1#2#3{% % \end{macrocode} % Project the path to the grow line and compile some useful information. % \begin{macrocode} \forest@projectpathtogrowline#1{forest@pp@}% \forest@sortprojections{forest@pp@}% - \forest@processprojectioninfo{forest@pp@}{forest@pi@}% + \forest@processprojectioninfo{forest@pp@}{forest@pi@}\forest@pi@toks % \end{macrocode} % Break the path. % \begin{macrocode} - \forest@breakpath#1{forest@pi@}\forest@brokenpath + \forest@breakpath#1{forest@pi@}\forest@pi@toks\forest@brokenpath % \end{macrocode} % Compile some more useful information. % \begin{macrocode} \forest@sort@inner@arrays{forest@pi@}#2% - \forest@pathtodict\forest@brokenpath{forest@pi@}% + \forest@pathtodict\forest@brokenpath\forest@segment@toks % \end{macrocode} % The auxiliary data is set up: do the work! % \begin{macrocode} @@ -9253,16 +9268,13 @@ % \end{macrocode} % % Put path segments into a ``segment dictionary'': for each segment of -% the path from $(x_1,y_1)$ to $(x_2,y_2)$ let -% |\forest@(x1,y1)--(x2,y2)| be |\forest@inpath| (which can be -% anything but |\relax|). -% \begin{macrocode} -\let\forest@inpath\advance -% \end{macrocode} -% This macro is just a wrapper to process the path. +% the pgf path (given in |#1|) from $(x_1,y_1)$ to $(x_2,y_2)$ we put +% |(x1,y1)--(x2,y2)| into toks |#2|. (The ``dictionary'' was +% reimplemented in v2.1.4. It's based on a toks register now, we search using +% |\pgfutil@in@|.) % \begin{macrocode} \def\forest@pathtodict#1#2{% - \edef\forest@pathtodict@prefix{#2}% + \let\forest@pathtodict@toks#2% \forest@save@pgfsyssoftpath@tokendefs \let\pgfsyssoftpath@movetotoken\forest@pathtodict@movetoop \let\pgfsyssoftpath@linetotoken\forest@pathtodict@linetoop @@ -9274,34 +9286,13 @@ % When a move-to operation is encountered: % \begin{macrocode} \def\forest@pathtodict@movetoop#1#2{% -% \end{macrocode} -% If a subpath had just started, it was a degenerate one (a point). No -% need to store that (i.e.\ no code would use this information). So, -% just remember that a new subpath has started. -% \begin{macrocode} - \def\forest@pathtodict@subpathstart{(#1,#2)-}% + \apptotoks\forest@pathtodict@toks{(#1,#2)}% } % \end{macrocode} % When a line-to operation is encountered: % \begin{macrocode} \def\forest@pathtodict@linetoop#1#2{% -% \end{macrocode} -% If the subpath has just started, its start is also the start of the -% current segment. -% \begin{macrocode} -\if\relax\forest@pathtodict@subpathstart\relax\else - \let\forest@pathtodict@from\forest@pathtodict@subpathstart - \fi -% \end{macrocode} -% Mark the segment as existing. -% \begin{macrocode} - \expandafter\let\csname\forest@pathtodict@prefix\forest@pathtodict@from-(#1,#2)\endcsname\forest@inpath -% \end{macrocode} -% Set the start of the next segment to the current point, and mark -% that we are in the middle of a subpath. -% \begin{macrocode} - \def\forest@pathtodict@from{(#1,#2)-}% - \def\forest@pathtodict@subpathstart{}% + \apptotoks\forest@pathtodict@toks{--(#1,#2)}% } % \end{macrocode} % @@ -9395,25 +9386,28 @@ % write a macro computing its boundary, make sure that the computed % boundary path is non-self-intersecting! % \begin{macrocode} - \forest@tempfalse - \expandafter\ifx\csname forest@pi@(% - \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% + \edef\forest@temp{% + (\csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb y\endcsname)--(% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname)% - \endcsname\forest@inpath - \forest@temptrue + }% + \expandafter\expandafter\expandafter\pgfutil@in@\expandafter\expandafter\expandafter + {\expandafter\forest@temp\expandafter}\expandafter + {\the\forest@segment@toks}% + \ifpgfutil@in@ \else - \expandafter\ifx\csname forest@pi@(% - \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% + \edef\forest@temp{% + (\csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname)--(% \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb y\endcsname)% - \endcsname\forest@inpath - \forest@temptrue - \fi + }% + \expandafter\expandafter\expandafter\pgfutil@in@\expandafter\expandafter\expandafter + {\expandafter\forest@temp\expandafter}\expandafter + {\the\forest@segment@toks}% \fi - \ifforest@temp + \ifpgfutil@in@ % \end{macrocode} % We have found the segment with the minimal/maximal distance to the % grow line. So let's add it to the edge path. @@ -9647,7 +9641,10 @@ % Another crucial part of the package. % % \begin{macrocode} +\newtoks\forest@PIi@toks +\newtoks\forest@PIii@toks \def\forest@distance@between@edge@paths#1#2#3{% + \begingroup % #1, #2 = (edge) paths % % project paths @@ -9659,11 +9656,11 @@ {forest@p1@}{forest@p2@}% {forest@P1@}{forest@P2@}% % process projections - \forest@processprojectioninfo{forest@P1@}{forest@PI1@}% - \forest@processprojectioninfo{forest@P2@}{forest@PI2@}% + \forest@processprojectioninfo{forest@P1@}{forest@PI1@}\forest@PIi@toks + \forest@processprojectioninfo{forest@P2@}{forest@PI2@}\forest@PIii@toks % break paths - \forest@breakpath#1{forest@PI1@}\forest@broken@one - \forest@breakpath#2{forest@PI2@}\forest@broken@two + \forest@breakpath#1{forest@PI1@}\forest@PIi@toks\forest@broken@one + \forest@breakpath#2{forest@PI2@}\forest@PIii@toks\forest@broken@two % sort inner arrays ---optimize: it's enough to find max and min \forest@sort@inner@arrays{forest@PI1@}\forest@sort@descending \forest@sort@inner@arrays{forest@PI2@}\forest@sort@ascending @@ -9687,7 +9684,9 @@ \fi \advance\c@pgf@countc 1 \forest@repeat - \let#3\forest@distance + \global\let\forest@global@temp\forest@distance + \endgroup + \let#3\forest@global@temp } % merge projections: we need two projection arrays, both containing % projection points from both paths, but each with the original diff --git a/Master/texmf-dist/tex/latex/forest/forest.sty b/Master/texmf-dist/tex/latex/forest/forest.sty index 47a19b90cd2..0c6c43ba005 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}[2017/01/27 v2.1.3 Drawing (linguistic) trees] +\ProvidesPackage{forest}[2017/02/02 v2.1.4 Drawing (linguistic) trees] \RequirePackage{tikz}[2013/12/13] \usetikzlibrary{shapes} @@ -2342,8 +2342,8 @@ \expandafter\endgroup \expandafter\edef\expandafter#2\expandafter{\forest@temp@message}% } -\NewDocumentCommand\forestdebugtypeouttree{o m}{% - \forestdebug@typeouttree{#1}\forest@temp +\NewDocumentCommand\forestdebugtypeouttree{d() O{\forest@cn}}{% + \forestdebug@typeouttree{#2}\forest@temp \typeout{\IfValueTF{#1}{#1: }{}\forest@temp}% } \def\forestdebug@typeouttree@build{% @@ -4361,10 +4361,10 @@ {#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}% + {\def\forestmathresult{0}\let\forestmathresulttype\forestmathtype@count}% + {\def\forestmathresult{1}\let\forestmathresulttype\forestmathtype@count}% + {\edef\forestmathresult{\the\numexpr\forestregister{aggregate result}+1}\let\forestmathresulttype\forestmathtype@count}% + {\forestrget{aggregate result}\forestmathresult\let\forestmathresulttype\forestmathtype@count}% {#1}% } \def\forest@aggregate@average#1#2{\forest@aggregate @@ -6320,10 +6320,17 @@ \forest@patch@enormouscoordinateboxbounds@minus\pgfpositionnodelatermaxx \forest@patch@enormouscoordinateboxbounds@minus\pgfpositionnodelatermaxy % end of patch - \xappto\forest@smuggle{\noexpand\forestoset{min x}{\pgfpositionnodelaterminx}}% - \xappto\forest@smuggle{\noexpand\forestoset{min y}{\pgfpositionnodelaterminy}}% - \xappto\forest@smuggle{\noexpand\forestoset{max x}{\pgfpositionnodelatermaxx}}% - \xappto\forest@smuggle{\noexpand\forestoset{max y}{\pgfpositionnodelatermaxy}}% + % when shape=coordinate, pgf returns \pgfpositionnodelater... with wrong catcode of pt + \forest@pnn@addtosmuggle{min x}\pgfpositionnodelaterminx + \forest@pnn@addtosmuggle{max x}\pgfpositionnodelatermaxx + \forest@pnn@addtosmuggle{min y}\pgfpositionnodelaterminy + \forest@pnn@addtosmuggle{max y}\pgfpositionnodelatermaxy +} +\def\forest@pnn@addtosmuggle#1#2{% + {% + \pgfutil@tempdima=#2\relax + \xappto\forest@smuggle{\noexpand\forestoset{#1}{\the\pgfutil@tempdima}}% + }% } \def\forest@node@forest@positionnodelater@restore{% \ifforest@drawtree@preservenodeboxes@ @@ -7703,7 +7710,7 @@ \advance\c@pgf@counta -1 \forest@sort\forest@ppiraw@cmp\forest@ppiraw@let\forest@sort@ascending{0}{\the\c@pgf@counta}% } -\def\forest@processprojectioninfo#1#2{% +\def\forest@processprojectioninfo#1#2#3{% \edef\forest@ppi@inputprefix{#1}% \c@pgf@counta=0 \c@pgf@countb=-1 @@ -7735,15 +7742,17 @@ \forest@append@point@to@inner@array \forest@xo\forest@yo {#2\the\c@pgf@countb @}% - \csedef{#2(\forest@xo,\forest@yo)}{\the\c@pgf@countb}% + \eapptotoks#3{(\forest@xo,\forest@yo){\the\c@pgf@countb}}% \fi\fi \fi\fi + % todo: is this really necessary? (yes: see the "ugly" thing above) \cslet{#1\the\c@pgf@counta xo}\relax \cslet{#1\the\c@pgf@counta yo}\relax \cslet{#1\the\c@pgf@counta xp}\relax \cslet{#1\the\c@pgf@counta yp}\relax \advance\c@pgf@counta 1 \saferepeat + % todo: is this really necessary? \cslet{#1n}\relax \advance\c@pgf@countb 1 \csedef{#2n}{\the\c@pgf@countb}% @@ -7768,15 +7777,16 @@ \advance\c@pgf@countc 1 \csedef{#3n}{\the\c@pgf@countc}% } -\def\forest@breakpath#1#2#3{% +\def\forest@breakpath#1#2#3#4{% \edef\forest@bp@prefix{#2}% + \let\forest@breakpath@toks#3% \forest@save@pgfsyssoftpath@tokendefs \let\pgfsyssoftpath@movetotoken\forest@breakpath@processfirstpoint \let\pgfsyssoftpath@linetotoken\forest@breakpath@processfirstpoint %\pgfusepath{}% empty the current path. ok? #1% \forest@restore@pgfsyssoftpath@tokendefs - \pgfsyssoftpath@getcurrentpath#3% + \pgfsyssoftpath@getcurrentpath#4% } \def\forest@breakpath@processfirstpoint#1#2{% \forest@breakpath@processmoveto{#1}{#2}% @@ -7787,17 +7797,21 @@ \pgfsyssoftpath@moveto{#1}{#2}% \def\forest@previous@x{#1}% \def\forest@previous@y{#2}% - \expandafter\let\expandafter\forest@previous@i - \csname\forest@bp@prefix(#1,#2)\endcsname + \forest@breakpath@getfromtoks\forest@breakpath@toks\forest@previous@i{#1}{#2}% \expandafter\let\expandafter\forest@previous@px \csname\forest@bp@prefix\forest@previous@i x\endcsname \expandafter\let\expandafter\forest@previous@py \csname\forest@bp@prefix\forest@previous@i y\endcsname } +\def\forest@breakpath@getfromtoks#1#2#3#4{% + % #1=cache toks register, #2=receiving cs, (#3,#4)=point; + % we rely on the fact that the point we're looking up should always be present + \def\forest@breakpath@getfromtoks@##1(#3,#4)##2##3\forest@END{##2}% + \edef#2{\expandafter\forest@breakpath@getfromtoks@\the#1\forest@END}% +} \def\forest@breakpath@processlineto#1#2{% \let\forest@breakpath@op\pgfsyssoftpath@lineto - \expandafter\let\expandafter\forest@i - \csname\forest@bp@prefix(#1,#2)\endcsname + \forest@breakpath@getfromtoks\forest@breakpath@toks\forest@i{#1}{#2}% \expandafter\let\expandafter\forest@px \csname\forest@bp@prefix\forest@i x\endcsname \expandafter\let\expandafter\forest@py @@ -7838,7 +7852,6 @@ \forest@append@point@to@inner@array \forest@last@x\forest@last@y {\forest@bp@prefix\the\forest@temp@count @}% - \csedef{\forest@bp@prefix(\the\pgf@x,\the\pgf@y)}{\the\forest@temp@count}% \saferepeat \fi \forest@breakpath@op{#1}{#2}% @@ -7860,13 +7873,15 @@ }% \let#3\forest@gep@global@edge } +\newtoks\forest@pi@toks +\newtoks\forest@segment@toks \def\forest@get@one@tightedgeofpath#1#2#3{% \forest@projectpathtogrowline#1{forest@pp@}% \forest@sortprojections{forest@pp@}% - \forest@processprojectioninfo{forest@pp@}{forest@pi@}% - \forest@breakpath#1{forest@pi@}\forest@brokenpath + \forest@processprojectioninfo{forest@pp@}{forest@pi@}\forest@pi@toks + \forest@breakpath#1{forest@pi@}\forest@pi@toks\forest@brokenpath \forest@sort@inner@arrays{forest@pi@}#2% - \forest@pathtodict\forest@brokenpath{forest@pi@}% + \forest@pathtodict\forest@brokenpath\forest@segment@toks \forest@gettightedgeofpath@getedge\forest@edge \forest@simplifypath\forest@edge#3% } @@ -7916,9 +7931,8 @@ \noexpand\forest@sort@cmpdimcs{#1##1d}{#1##2d}% }% } -\let\forest@inpath\advance \def\forest@pathtodict#1#2{% - \edef\forest@pathtodict@prefix{#2}% + \let\forest@pathtodict@toks#2% \forest@save@pgfsyssoftpath@tokendefs \let\pgfsyssoftpath@movetotoken\forest@pathtodict@movetoop \let\pgfsyssoftpath@linetotoken\forest@pathtodict@linetoop @@ -7927,15 +7941,10 @@ \forest@restore@pgfsyssoftpath@tokendefs } \def\forest@pathtodict@movetoop#1#2{% - \def\forest@pathtodict@subpathstart{(#1,#2)-}% + \apptotoks\forest@pathtodict@toks{(#1,#2)}% } \def\forest@pathtodict@linetoop#1#2{% -\if\relax\forest@pathtodict@subpathstart\relax\else - \let\forest@pathtodict@from\forest@pathtodict@subpathstart - \fi - \expandafter\let\csname\forest@pathtodict@prefix\forest@pathtodict@from-(#1,#2)\endcsname\forest@inpath - \def\forest@pathtodict@from{(#1,#2)-}% - \def\forest@pathtodict@subpathstart{}% + \apptotoks\forest@pathtodict@toks{--(#1,#2)}% } \def\forest@gettightedgeofpath@getedge#1{% cs to store the edge into \pgfsyssoftpath@setcurrentpath\pgfutil@empty @@ -7975,25 +7984,28 @@ \advance\c@pgf@counta -1 \safeloop \ifnum\c@pgf@countc<\csname forest@pi@\forest@aplusone @n\endcsname\relax - \forest@tempfalse - \expandafter\ifx\csname forest@pi@(% - \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% + \edef\forest@temp{% + (\csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb y\endcsname)--(% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname)% - \endcsname\forest@inpath - \forest@temptrue + }% + \expandafter\expandafter\expandafter\pgfutil@in@\expandafter\expandafter\expandafter + {\expandafter\forest@temp\expandafter}\expandafter + {\the\forest@segment@toks}% + \ifpgfutil@in@ \else - \expandafter\ifx\csname forest@pi@(% - \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% + \edef\forest@temp{% + (\csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname,% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc y\endcsname)--(% \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb x\endcsname,% \csname forest@pi@\the\c@pgf@counta @\the\c@pgf@countb y\endcsname)% - \endcsname\forest@inpath - \forest@temptrue - \fi + }% + \expandafter\expandafter\expandafter\pgfutil@in@\expandafter\expandafter\expandafter + {\expandafter\forest@temp\expandafter}\expandafter + {\the\forest@segment@toks}% \fi - \ifforest@temp + \ifpgfutil@in@ \forest@gettightedgeofpath@maybemoveto{\the\c@pgf@counta}{\the\c@pgf@countb}% \edef\forest@last@x{% \csname forest@pi@\forest@aplusone @\the\c@pgf@countc x\endcsname}% @@ -8150,7 +8162,10 @@ }% \pgfsyssoftpath@getcurrentpath#3% } +\newtoks\forest@PIi@toks +\newtoks\forest@PIii@toks \def\forest@distance@between@edge@paths#1#2#3{% + \begingroup % #1, #2 = (edge) paths % % project paths @@ -8162,11 +8177,11 @@ {forest@p1@}{forest@p2@}% {forest@P1@}{forest@P2@}% % process projections - \forest@processprojectioninfo{forest@P1@}{forest@PI1@}% - \forest@processprojectioninfo{forest@P2@}{forest@PI2@}% + \forest@processprojectioninfo{forest@P1@}{forest@PI1@}\forest@PIi@toks + \forest@processprojectioninfo{forest@P2@}{forest@PI2@}\forest@PIii@toks % break paths - \forest@breakpath#1{forest@PI1@}\forest@broken@one - \forest@breakpath#2{forest@PI2@}\forest@broken@two + \forest@breakpath#1{forest@PI1@}\forest@PIi@toks\forest@broken@one + \forest@breakpath#2{forest@PI2@}\forest@PIii@toks\forest@broken@two % sort inner arrays ---optimize: it's enough to find max and min \forest@sort@inner@arrays{forest@PI1@}\forest@sort@descending \forest@sort@inner@arrays{forest@PI2@}\forest@sort@ascending @@ -8190,7 +8205,9 @@ \fi \advance\c@pgf@countc 1 \forest@repeat - \let#3\forest@distance + \global\let\forest@global@temp\forest@distance + \endgroup + \let#3\forest@global@temp } % merge projections: we need two projection arrays, both containing % projection points from both paths, but each with the original -- cgit v1.2.3