cetz-package / cetz

CeTZ: ein Typst Zeichenpaket - A library for drawing stuff with Typst.
https://cetz-package.github.io
GNU Lesser General Public License v3.0
755 stars 34 forks source link

Improved tree algorithm / better tree customization #225

Open RubixDev opened 10 months ago

RubixDev commented 10 months ago

From Discord here. The tree function positions the Lt node to the right of the left subtree, even though there would be enough space for centering it below its parent. Either the placement algorithm should be improved or it should be made possible to manually tweak the placement of nodes.

image

#import "@preview/cetz:0.1.1"
#figure(
  cetz.canvas({
    let encircle(num) = {
      box(baseline: 2pt, circle(inset: (x: 1pt, y: -.5pt), stroke: .5pt)[#num])
    }
    cetz.tree.tree((
      [Expression #encircle(5)],
      (
        [Expression #encircle(3)],
        ([Expression #encircle(1)], [`Int(1)`]),
        [`Plus`],
        ([Expression #encircle(2)], [`Int(2)`]),
      ),
      [`Lt`],
      ([Expression #encircle(4)], [`Int(4)`]),
    ), spread: 1.7, content: (padding: .1))
  }),
  caption: [Abstract syntax tree for '`1 + 2 < 4`']
)

Below is a picture of the same tree using LaTeX with TikZ.

image

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{trees}
\newcommand{\encircle}[1]{\raisebox{.5pt}{\textcircled{\raisebox{-.8pt} {\footnotesize#1}}}}
\begin{document}
  \begin{tikzpicture}[level distance=1cm, sibling distance=2.2cm]
    \node {Expression \encircle{5}}
      child {node {Expression \encircle{3}}
        child {node {Expression \encircle{1}}
          child {node {\texttt{Int(1)}}}}
        child {node {\texttt{Plus}}}
        child {node {Expression \encircle{2}}
          child {node {\texttt{Int(2)}}}}}
      child {node {\texttt{Lt}}}
      child {node {Expression \encircle{4}}
        child {node {\texttt{Int(4)}}}};
  \end{tikzpicture}
\end{document}
RubixDev commented 10 months ago

Actually I think TikZ doesn't even try to calculate the needed space itself and just relies on the user to set the node distance accordingly.

johannes-wolf commented 9 months ago

Actually I think TikZ doesn't even try to calculate the needed space itself and just relies on the user to set the node distance accordingly.

Yes, TikZ does not measure the tree nodes, I have tested this before, when I was trying to implement a more TikZ like layout.

I will take a look at this. I think it can only be done by layouting in multiple passes by “correcting” subtrees after the first layout.