24

How to draw the directory tree image shown below, indicating folders and files?

enter image description here

To draw the folder tree I used the code from Making a (simple) directory tree, but there is no obvious option to include files, and I therefore edited the image in Inkscape, as indicated in red.

The replicated code from Gonzalo Medina post (Making a (simple) directory tree) is shown below

    \documentclass[border=5pt]{standalone}
    \usepackage{forest}

    \definecolor{folderbg}{RGB}{124,166,198}
    \definecolor{folderborder}{RGB}{110,144,169}

    \def\Size{4pt}
    \tikzset{
      folder/.pic={
        \filldraw[draw=folderborder,top color=folderbg!50,bottom color=folderbg]
          (-1.05*\Size,0.2\Size+5pt) rectangle ++(.75*\Size,-0.2\Size-5pt);  
        \filldraw[draw=folderborder,top color=folderbg!50,bottom color=folderbg]
          (-1.15*\Size,-\Size) rectangle (1.15*\Size,\Size);
      }
    }

    \begin{document}

    \begin{forest}
      for tree={
        font=\ttfamily,
        grow'=0,
        child anchor=west,
        parent anchor=south,
        anchor=west,
        calign=first,
        inner xsep=7pt,
        edge path={
          \noexpand\path [draw, \forestoption{edge}]
          (!u.south west) +(7.5pt,0) |- (.child anchor) pic {folder} \forestoption{edge label};
        },
        before typesetting nodes={
          if n=1
            {insert before={[,phantom]}}
            {}
        },
        fit=band,
        before computing xy={l=15pt},
      }  
    [system
      [config
      ]
      [lib
        [Access
        ]
        [Plugin
        ]
      ]
      [templates
      ]
      [tests
      ]
    ]
    \end{forest}

    \end{document}
22

You can create a style for your file node like this

file/.style={edge path={\noexpand\path [draw, \forestoption{edge}]
          (!u.south west) +(7.5pt,0) |- (.child anchor) \forestoption{edge label};},
         inner xsep=2pt,font=\small\ttfamily
            }

Code

\documentclass[border=5pt]{standalone}
\usepackage{forest}

\definecolor{folderbg}{RGB}{124,166,198}
\definecolor{folderborder}{RGB}{110,144,169}

\def\Size{4pt}
\tikzset{
      folder/.pic={
        \filldraw[draw=folderborder,top color=folderbg!50,bottom color=folderbg]
          (-1.05*\Size,0.2\Size+5pt) rectangle ++(.75*\Size,-0.2\Size-5pt);  
        \filldraw[draw=folderborder,top color=folderbg!50,bottom color=folderbg]
          (-1.15*\Size,-\Size) rectangle (1.15*\Size,\Size);
      }
    }


 \begin{document}

 \begin{forest}
      for tree={
        font=\ttfamily,
        grow'=0,
        child anchor=west,
        parent anchor=south,
        anchor=west,
        calign=first,
        inner xsep=7pt,
        edge path={
          \noexpand\path [draw, \forestoption{edge}]
          (!u.south west) +(7.5pt,0) |- (.child anchor) pic {folder} \forestoption{edge label};
        },
        % style for your file node 
        file/.style={edge path={\noexpand\path [draw, \forestoption{edge}]
          (!u.south west) +(7.5pt,0) |- (.child anchor) \forestoption{edge label};},
          inner xsep=2pt,font=\small\ttfamily
                     },
        before typesetting nodes={
          if n=1
            {insert before={[,phantom]}}
            {}
        },
        fit=band,
        before computing xy={l=15pt},
      }  
    [system
      [config
      ]
      [lib
        [Access
        ]
        [Plugin
        ]
        [file.txt,file
        ]
      ]
      [templates
      ]
      [tests
      ]
    ]
 \end{forest}

 \end{document}

enter image description here

13

This answer has 2 primary purposes.

  1. Simplify the existing code by updating it to make use of the facilities offered by current Forest, especially those offered by the edges library which provides the folder option.

  2. Create a file pic to match the existing folder one, and to enable styles to easily switch between them.

In addition, it has a secondary purpose.

  1. Provide an extensible interface for the addition of further pic icons, should these be desired.

When Gonzalo Medina posted that code, Forest offered no easy out-of-the-box solution supporting this kind of structure. This was why I wrote styles such as dir tree and the answer cited by Gonzalo Medina in response to requests for this kind of diagram.

Since then, we have an extensively updated and expanded Forest with the beginnings of an expansion system via libraries. One of those already on offer is edges which, perhaps surprisingly, supports just this kind of tree.

I would not recommend using the old method unless you are stuck with Forest 1 and cannot update. The support for this kind of tree provided by updated Forest is more flexible, simpler and more robust.


First, we add a pic for the file icon.

  file/.pic={%
    \filldraw [draw=folderborder, top color=folderbg!5, bottom color=folderbg!10] (-\Size,.4*\Size+5pt) coordinate (a) |- (\Size,-1.2*\Size) coordinate (b) -- ++(0,1.6*\Size) coordinate (c) -- ++(-5pt,5pt) coordinate (d) -- cycle (d) |- (c) ;
  },

This picks up the base folder colours. Obviously, you could change this to use different colours if desired.

Now for some Forest configuration.

\forestset{%
  declare autowrapped toks={pic me}{},

This is an option to hold the value desired for each node. Eventually, this will take values such as pic {file}. By default, it is empty.

We define a style for trees of this kind, pic dir tree.

  pic dir tree/.style={%
    for tree={%
      folder,
      font=\ttfamily,
      grow'=0,
    },

Defaults for the tree: folder has nothing to do with the pic. Rather, it is the name of the style which the Forest edges library provides for directory-style trees.

We'll collect the pic me settings on parsing the tree. We'll then add them to the edge path by appending the option to the value of edge label.

    before typesetting nodes={%
      for tree={%
        edge label+/.option={pic me},
      },
    },
  },

This saves messing around with the path which we've already set to a non-default by using the folder style for the tree.

Now for a convenience wrapper. pic me set takes 2 arguments. The first is the name of a Forest style to-be-created. The second is the name of a pic such as folder (in the icon sense) or file.

  pic me set/.code n args=2{%
    \forestset{%
      #1/.style={%
        inner xsep=2\Size,
        pic me={pic {#2}},
      }
    }
  },

Each style so defined will do 2 things. First, it will set a node's inner xsep to a value which is not here hard-coded, but dependent on \Size. Second, it will set the node's pic me option to the relevant value.

We just create 2 such styles for now.

  pic me set={directory}{folder},

The first, is directory. This add the folder icon. (We use directory rather than folder to avoid still further confusion.)

  pic me set={file}{file},

The second is file. No complications here, so we can use the name of the file icon.

Further styles can be created in the same way, provided a suitable pic is available.

}

Now to typeset a tree of this kind, we can use the following in the tree's preamble.

\begin{forest}
  pic dir tree,

This sets up the tree with the options described above.

  where level=0{}{% folder icons by default; override using file for file icons
    directory,
  },

In our case, we'll set all non-root nodes to use the directory style by default, since most of them need folder icons.

We can then write

      [file.txt, file
      ]

to override the style and use a file icon for the single exception.

folders and files in current Forest

Complete code:

\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage[edges]{forest}
\definecolor{folderbg}{RGB}{124,166,198}
\definecolor{folderborder}{RGB}{110,144,169}
\newlength\Size
\setlength\Size{4pt}
\tikzset{%
  folder/.pic={%
    \filldraw [draw=folderborder, top color=folderbg!50, bottom color=folderbg] (-1.05*\Size,0.2\Size+5pt) rectangle ++(.75*\Size,-0.2\Size-5pt);
    \filldraw [draw=folderborder, top color=folderbg!50, bottom color=folderbg] (-1.15*\Size,-\Size) rectangle (1.15*\Size,\Size);
  },
  file/.pic={%
    \filldraw [draw=folderborder, top color=folderbg!5, bottom color=folderbg!10] (-\Size,.4*\Size+5pt) coordinate (a) |- (\Size,-1.2*\Size) coordinate (b) -- ++(0,1.6*\Size) coordinate (c) -- ++(-5pt,5pt) coordinate (d) -- cycle (d) |- (c) ;
  },
}
\forestset{%
  declare autowrapped toks={pic me}{},
  pic dir tree/.style={%
    for tree={%
      folder,
      font=\ttfamily,
      grow'=0,
    },
    before typesetting nodes={%
      for tree={%
        edge label+/.option={pic me},
      },
    },
  },
  pic me set/.code n args=2{%
    \forestset{%
      #1/.style={%
        inner xsep=2\Size,
        pic me={pic {#2}},
      }
    }
  },
  pic me set={directory}{folder},
  pic me set={file}{file},
}
\begin{document}

\begin{forest}
  pic dir tree,
  where level=0{}{% folder icons by default; override using file for file icons
    directory,
  },
  [system
    [config
    ]
    [lib
      [Access
      ]
      [Plugin
      ]
      [file.txt, file
      ]
    ]
    [templates
    ]
    [tests
    ]
  ]
\end{forest}
\end{document}

See https://tex.stackexchange.com/a/405253/ if you want a folder icon for the root node.

  • unfortunately, the code won't compile, but throw the following errors instead: ! Package pgfkeys Error: I do not know the key '/forest/package@options/edges' and I am going to ignore it. Perhaps you misspelled it., Package pgfkeys Error: I do not know the key '/forest/edge label+/.option', td it. \end{forest}, Package pgfkeys Error: I do not know the key '/tikz/folder' and I am going to ignore it. Perhaps you misspelled it. \end{forest} – Bastian Sep 28 '16 at 14:40
  • @Bastian You have an old version of Forest. Update your installation of TeX and it should work fine. The error says that you are using v1 of Forest whereas the code requires v2. – cfr Sep 28 '16 at 22:13
  • @Bastian As I explain in the question, this answer relies on features of current Forest which were not available when the earlier answer was posted. If you cannot update, just stick with the method in that earlier answer. However, things are much easier and more flexible if you can update and use the approach in my answer. – cfr Sep 28 '16 at 22:16

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.