6

I want to print a tree structure and started using the package dirtree (v0.32, see Making a (simple) directory tree). Following calls work smooth:

\dirtree{.1 root. .2 child1. .2 child2. .3 childofchild2. }

\def\mytree{{.1 root. .2 child1. .2 child2. .3 childofchild2. }}
\expandafter\dirtree\mytree{}

\dirtree will draw a tree representation like

root
 |-- child1
 |-- child2
      |-- child of child2

But a problem arises if the generation of the tree data is using some more complex macro.

\documentclass{article}
\usepackage{dirtree}
% edited to remove the use of counters
%\newcounter{qtreedepth}
%\def\nodeC#1{\addtocounter{qtreedepth}{1}#1\addtocounter{qtreedepth}{-1}}
%\renewcommand{\item}[1]{.\arabic{qtreedepth} #1. }
\def\nodeC#1{{#1}}
\newcommand{\myitem}[1]{.1 #1. }

\begin{document}
\nodeC{\myitem{root}\nodeC{\myitem{child}}}

\expandafter\dirtree{\nodeC{\myitem{root}\nodeC{\myitem{child}}}}
\end{document}

The error message:

! Use of \next doesn't match its definition.
<argument> \myitem 
                   {root}\nodeC {\myitem {child}}
l.11 ...nodeC{\myitem{root}\nodeC{\myitem{child}}}

Is there something wrong with the expansion? Is the usage of \expandafter correct? Any idea what is wrong?

(Meanwhile I discovered the page on tree drawing in TikZ, Drawing a directory listing a la the tree command in TikZ. Worth trying, but on the other I'd like to know the reason why above does not work...)

e-birk
  • 4,373
  • Welcome to TeX.sx! It's not a good idea to redefine \item, to begin with. Can you give a graphical (approximate) representation of what you want to do? – egreg Jan 15 '13 at 21:26
  • A quick read of the dirtree docs makes me suspect that \dirtree requires a fully-expanded argument. So \dirtree{.1 root.} is fine (that's what your \expandafter will generate), but something with \stepcounter can never work as it's not expandable. – Joseph Wright Jan 15 '13 at 21:38
  • @egreg The \item is a leftover because I want to use lists, thus, the redefinition. Reading that environments are not expandable I avoided lists for \dirtree.

    The graphical output should have a structure like

    root |- child1 |- child of child1

    The input structure should use environments.

    \begin{nodeC} \item{root} \begin{nodeC} \item{child1} \begin{nodeC}\item{child of child1}\end{nodeC} \end{nodeC} \end{nodeC}

    The closest solution would be to change to TikZ package and modify the code of link of Tom Bombadil.

    – e-birk Jan 16 '13 at 01:58
  • @Joseph Wright Though I am not that familiar with Tex programming yet, I had the same impression that \dirtree just wants "plain text" (fully expanded macros).

    Now I removed all the counter stuff but I get still the same error... Am I doing anything wrong?

    – e-birk Jan 16 '13 at 02:18

1 Answers1

4

This seems to implement the syntax you prefer:

\documentclass{article}
\usepackage{dirtree}

\newcounter{nodeCdepth}
\newenvironment{nodeC}
  {\ifnum\value{nodeCdepth}=0
     \gdef\listfordirtree{}%
     \let\item\nodeCitem
    \fi
    \stepcounter{nodeCdepth}}
  {\addtocounter{nodeCdepth}{-1}%
   \ifnum\value{nodeCdepth}=0
     \expandafter\dirtree\expandafter{\listfordirtree}%
   \fi}
\newcommand{\nodeCitem}[1]{%
  \xdef\listfordirtree{%
    \unexpanded\expandafter{\listfordirtree}%
    .\thenodeCdepth\space\unexpanded{#1}. }%
}

\begin{document}

\begin{nodeC}
  \item{root}
  \begin{nodeC}
    \item{bin}
    \begin{nodeC}
      \item{home}
    \end{nodeC}
    \item{xu}
  \end{nodeC}
\end{nodeC}

\dirtree{.1 root.  .2 bin.  .3 home.  .2 xu. }
\end{document}

Just for comparison I've added the usual dirtree syntax.

enter image description here

I maintain the depth in the nodeCdepth counter; when it's zero, either we are starting (at \begin{nodeC}) and a container macro is initialized to empty or we are ending (at \end{nodeC}) and the container macro is delivered to \dirtree for processing the list of nodes. When the counter has a value greater than zero, \item will add its argument to the container macro, surrounded by the tokens required by the syntax of \dirtree.

egreg
  • 1,121,712
  • Many thks! - So the creation of a container (\listfordirtree) to store the argument avoids the problem with non-expandable counter manipulations (\stepcounter etc.). I found that \item without braces would be easier to use (e.g. \item root instead of \item{root}). But probably this goes far beyond the scope of this question and I will ask a separate question. Anyway, this solution works fine! – e-birk Jan 17 '13 at 01:57