1

I am able to generate the following tree using the MWE below. It creates tikzpictures using a \drawtape command and puts them into saveboxes, which in turn can be straightforwardly used as the content of nodes in a forest environment.

A simple computation tree

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning}

\newcommand{\drawtape}[3]{
\begin{tikzpicture}[cell/.style={minimum size=0.5cm,outer sep=0pt,draw,rectangle,node distance=0pt,text height=1.5ex}]
\foreach \x [count=\xi] in {#1} {
    \ifnum \xi=1
        \node[cell] (\xi) {$\x$};
    \else
        \pgfmathtruncatemacro{\xil}{\xi - 1}
        \node[cell] (\xi) [right=of \xil] {$\x$};
    \fi
}
\node[font=\footnotesize] [below=0cm of #2, xshift=0.03em] {$#3$};
\end{tikzpicture}
}

\newsavebox{\treeroot}
\newsavebox{\treeone}
\newsavebox{\treetwo}

\usepackage{forest}

\begin{document}

\savebox{\treeroot}{\drawtape{1, 1, 1}{1}{1}}
\savebox{\treeone}{\drawtape{0, 1, 1, 1}{1}{2}}
\savebox{\treetwo}{\drawtape{1, 1, 1}{2}{1}}

\begin{forest}
    [\usebox{\treeroot}
        [\usebox{\treeone}]
        [\usebox{\treetwo}]
    ]
\end{forest}

\end{document}

This works okay for small trees like the one pictured, but if I want to create a larger tree then the number of saveboxes I have to manually create quickly becomes incredibly cumbersome. Ideally, I would like to be able to write a forest environment like the one below instead. Is there any way to achieve this?

\begin{forest}
    [\drawtape{1, 1, 1}{1}{1}
        [\drawtape{0, 1, 1, 1}{1}{2}]
        [\drawtape{1, 1, 1}{2}{1}]
    ]
\end{forest}
4
  • See tex.stackexchange.com/questions/184497, in comparison to this solutions you need to define two commands.
    – Zarko
    Feb 20, 2020 at 14:32
  • If you just want to avoid the \newsavebox command, the xsavebox package could be an option.
    – AlexG
    Feb 20, 2020 at 16:08
  • @Zarko Your diagram at tex.stackexchange.com/questions/184497 looks very good, but I can't figure out how to adapt it to this question. Can you please elaborate?
    – solisoc
    Feb 20, 2020 at 16:13
  • @Zarko I figured out how to do it, so don't worry.
    – solisoc
    Feb 21, 2020 at 5:33

2 Answers 2

2

If you are willing to consider to use a slightly different syntax, you can use simple tabulars along with append after command.

\documentclass{article}
\usepackage{array}
\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}
\usepackage{forest}
\tikzset{drawtape/.style n args={3}{node contents={
\begin{tabular}{|*{10}{@{}C{5mm}@{}|}}
\hline
#1
\hline
\end{tabular}},append after command={
([xshift=#2*5mm-1mm]\tikzlastnode.south west) 
node[anchor=north,inner sep=0pt,font=\footnotesize]{#3}}}}

\begin{document}

\begin{forest}
for tree={l sep+=2ex,edge={shorten <=2.5ex}}
    [,drawtape={1& 1& 1\\}{1}{1}
        [,drawtape={0 & 1 & 1& 1\\}{1}{2}]
        [,drawtape={1& 1& 1\\}{3}{1}]
    ]
\end{forest}
\end{document}

enter image description here

2

Thanks to Zarko pointing me towards the use of multipart nodes, I arrived at the following solution:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart, positioning}

\usepackage{xinttools}

\usepackage{forest}

\def\numname#1{%
    \ifcase#1 \or one\or two\or three\or four\or five\or six\or seven\or eight\or nine\or ten\or eleven \or twelve\or thirteen\or fourteen\or fifteen\or sixteen\or seventeen\or eighteen\or nineteen\or twenty\fi%
}

\newcounter{cellnum}
\newcommand{\tape}[1]{%
    \setcounter{cellnum}{1}
    \xintFor* ##1 in {#1} \do {%
        \nodepart[text width=1.5ex, align=center]{\numname{\value{cellnum}}} $##1$%
        \stepcounter{cellnum}%
    }
    \addtocounter{cellnum}{-1}%
}

\begin{document}

\begin{forest}
    for tree={
        delay={
            content={\tape{#1}}
        },
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=\value{cellnum},
        rectangle split part align=base,
        draw,
        l sep=6ex,
        s sep=2em,
        anchor=parent,
        edge path={
            \noexpand\path[draw] 
            ([yshift=-2.5ex]!u.children) -- ([yshift=1ex].parent);
        },
        head/.style n args=2{
            tikz={\node[below=0cm of .\numname{#1} south, font=\scriptsize]{$#2$};}
        }
    }
    [111, head={1}{1}
        [0111, head={1}{2}]
        [111, head={2}{1}]
    ]
\end{forest}

\end{document}

Unfortunately there is an issue with edge paths being of unequal lengths. I will inquire after a solution and update this answer when I find one. EDIT: Using anchor=parent in for tree solves this.

A simple computation tree

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .