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}
  • See tex.stackexchange.com/questions/184497, in comparison to this solutions you need to define two commands. – Zarko Feb 20 at 14:32
  • If you just want to avoid the \newsavebox command, the xsavebox package could be an option. – AlexG Feb 20 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 at 16:13
  • @Zarko I figured out how to do it, so don't worry. – solisoc Feb 21 at 5:33
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.