sasozivanovic / forest

a PGF/TikZ-based LaTeX package for drawing (linguistic) trees
LaTeX Project Public License v1.3c
64 stars 4 forks source link

Circle nodes need "minimum size" #4

Open nignasi opened 3 years ago

nignasi commented 3 years ago

Following code shows a forest-tree where nodes has to be circles instead of rectangles. The code fails with error "Dimension too large". As soon as a minimum size is fixed for nodes, the code works.

\documentclass{article}
\usepackage{forest}

\begin{document}
\begin{forest}
  [7, for tree={circle, draw}%, minimum size=2em}
    [6 [5] [4]]
    [5]
    ]
\end{forest}
\end{document}

I don't know if it's a know topic, but I've not seen any minimum size reference for circle nodes examples in forest-doc.

Thank you,

Ignasi

cfr42 commented 5 months ago

I don't know if this is a bug or just what TikZ does since this kind of error happens pretty regularly regardless of application. However, for whatever it is worth the first error occurs on line 6449 of forest.sty

\forest@node@getedge{negative}{\forest@plu@grow}{\forest@plnu@negativechildedge}%

If you force packing per node, it happens after all the nodes in the sub-tree are packed i.e. between before packing node and after packing node for the root.

What I don't quite understand is that it seems to perform exactly the same action with precisely the same values one and only complains the second time. So it almost seems as if the problem is that there's a zero difference between the two? Does PGF not like moving 0pt? But probably I'm just misunderstanding what's going on.

\forest@node@marshal ->\bix \show \ri 
\show \forest@plu@grow \show \forest@p...
l.1233 \end{forest}

? 
> \forest@plu@grow=macro:
->270.
\forest@node@marshal ...ri \show \forest@plu@grow 
\show \forest@plnu@negativ...
l.1233 \end{forest}

? 
> \forest@plnu@negativechildedge=macro:
->\pgfsyssoftpath@movetotoken {0.0pt}{-5.76367pt}\pgfsyssoftpath@linetotoken {-
6.35397pt}{-3.13176pt}\pgfsyssoftpath@linetotoken {-8.98589pt}{3.22221pt}\pgfsy
ssoftpath@linetotoken {-6.35397pt}{9.57619pt}\pgfsyssoftpath@linetotoken {0.0pt
}{12.2081pt}.
\forest@node@marshal ...st@plnu@negativechildedge 
\forest@node@getedge {nega...
l.1233 \end{forest}

? 
! Undefined control sequence.
\forest@node@marshal ...u@negativechildedge }\bix 
\forest@node@getedge {posi...
l.1233 \end{forest}

? 
node@3
node@6
5
node@6
node@2
7
> \oi=undefined.
<argument> \show \oi 

l.1233 \end{forest}

? 
> \ghi=undefined.
<argument> \show \ghi 
\def \bix {\show \hi }
l.1233 \end{forest}

? 
> \hi=undefined.
\bix ->\show \hi 

l.1233 \end{forest}

? 
> \ri=undefined.
\forest@node@marshal ->\bix \show \ri 
\show \forest@plu@grow \show \forest@p...
l.1233 \end{forest}

? 
> \forest@plu@grow=macro:
->270.
\forest@node@marshal ...ri \show \forest@plu@grow 
\show \forest@plnu@negativ...
l.1233 \end{forest}

? 
> \forest@plnu@negativechildedge=macro:
->\pgfsyssoftpath@movetotoken {0.0pt}{-5.76367pt}\pgfsyssoftpath@linetotoken {-
6.35397pt}{-3.13176pt}\pgfsyssoftpath@linetotoken {-8.98589pt}{3.22221pt}\pgfsy
ssoftpath@linetotoken {-6.35397pt}{9.57619pt}\pgfsyssoftpath@linetotoken {0.0pt
}{12.2081pt}.
\forest@node@marshal ...st@plnu@negativechildedge
\forest@node@getedge {nega...
l.1233 \end{forest}

?
! Dimension too large.
<recently read> \pgf@x

Code probably isn't much more informative, but it features Bagpuss, so why not?

\documentclass{article}
\usepackage{forest}
\makeatletter
\def\forest@pack{%
  \forestmath@if{bagpuss}{}{}%
  \pgfsyssoftpath@getcurrentpath\forest@pack@original@path
  \forest@pack@computetiers
  \forest@pack@computegrowthuniformity
  \forestmath@if{bagpuss}{}{}%
  \forest@@pack
  \forestmath@if{bagpuss}{}{}%
  \pgfsyssoftpath@setcurrentpath\forest@pack@original@path
}
\def\forest@@pack{%
  \ifnum\forestove{uniform growth}>0
    \ifnum\forestove{n children}>0
      \forest@pack@level@uniform
      \forest@pack@aligntiers@ofsubtree
      \forest@pack@sibling@uniform@recursive
    \fi
    \else
      \forest@node@foreachchild{\forest@@pack}%
      \forest@process@hook@keylist@nodynamics{before packing node}{current}%
      \ifnum\forestove{n children}>0
        \forestmath@if{bagpuss}{\show\oi}{}%
        \forest@pack@level@nonuniform
        \forestmath@if{bagpuss}{\show\vi}{}%
        \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
}
\def\forest@pack@onlythisnode{%
  \ifnum\forestove{n children}>0
    \forest@pack@computetiers
    \forest@pack@level@nonuniform
    \forest@pack@aligntiers
    \forest@node@foreachchild{\forestoset{s}{0\pgfmath@pt}}%
    \forest@pack@sibling@uniform@applyreversed
  \fi
}
\def\forest@pack@computegrowthuniformity{%
  \forest@node@foreachchild{\forest@pack@computegrowthuniformity}%
  \edef\forest@pack@cgu@uniformity{%
    \ifnum\forestove{n children}=0
      2\else 1\fi
  }%
  \forestoget{grow}\forest@pack@cgu@parentgrow
  \forest@node@foreachchild{%
    \ifnum\forestove{uniform growth}=0
      \def\forest@pack@cgu@uniformity{0}%
    \else
      \ifnum\forestove{uniform growth}=1
        \ifnum\forestove{grow}=\forest@pack@cgu@parentgrow\relax\else
          \def\forest@pack@cgu@uniformity{0}%
        \fi
      \fi
    \fi
  }%
  \forestoget{before packing node}\forest@temp@a
  \forestoget{after packing node}\forest@temp@b
  \expandafter\expandafter\expandafter\ifstrempty\expandafter\expandafter\expandafter{\expandafter\forest@temp@a\forest@temp@b}{%
    \forestolet{uniform growth}\forest@pack@cgu@uniformity
  }{%
    \forestoset{uniform growth}{0}%
  }%
}
\def\forest@pack@level@nonuniform{%
  \let\forest@plu@minchildl\relax
  \forestoget{grow}\forest@plu@grow
  \forestmath@if{bagpuss}{\show\ghi\def\bix{\show\hi}}{}%
  \forest@node@foreachchild{%
    \bix
    \show\ri
    \show\forest@plu@grow
    \show\forest@plnu@negativechildedge
    \forest@node@getedge{negative}{\forest@plu@grow}{\forest@plnu@negativechildedge}%
    \bix
    \forest@node@getedge{positive}{\forest@plu@grow}{\forest@plnu@positivechildedge}%
    \def\forest@plnu@childedge{\forest@plnu@negativechildedge\forest@plnu@positivechildedge}%
    \forest@path@getboundingrectangle@ls\forest@plnu@childedge{\forest@plu@grow}%
    \advance\pgf@xa\forestove{l}\relax
    \ifx\forest@plu@minchildl\relax
      \edef\forest@plu@minchildl{\the\pgf@xa}%
    \else
      \ifdim\pgf@xa<\forest@plu@minchildl\relax
        \edef\forest@plu@minchildl{\the\pgf@xa}%
      \fi
    \fi
  }%
  \let\bix\relax
  \forest@node@getboundingrectangle@ls{\forest@plu@grow}%
  \pgfutil@tempdima=\pgf@xb\relax
  \advance\pgfutil@tempdima -\forest@plu@minchildl\relax
  \advance\pgfutil@tempdima \forestove{l sep}\relax
  \ifdim\pgfutil@tempdima>0pt
    \forest@node@foreachchild{%
      \forestoeset{l}{\the\dimexpr\the\pgfutil@tempdima+\forestove{l}}%
    }%
  \fi
}
\makeatother
\forestset{%
  declare boolean={bagpuss}{false},
}
\begin{document}
\begin{forest} 
  for tree={%
    circle,
    draw,
    before packing node={%
      typeout/.option=name,
      typeout/.option=content,
    },
    after packing node={%
      typeout/.option=name,
    },
  }%, minimum size=2em}
  [7,bagpuss
    [6 [5] [4]]
    [5]
  ]
\end{forest}
\end{document}

[I do realise Bagpuss is a culturally parochial reference - not to mention a temporally specific one, but he's easy to find in code. ]