Is there a way to represent a directory tree in a Github README.md?

GithubMarkdown

Github Problem Overview


In my Githubs repos documentation I want to represent a directory tree structure like this:

enter image description here

Is there a way to do that with Github flavoured markdown, besides just creating it with ascii art?

So basically like this question, but I'm wondering if there is a github specific solution.

Github Solutions


Solution 1 - Github

I got resolver the problem in this way:

  1. Insert command tree in bash. >Example >>enter image description here

  2. Create a README.md in github repository and copy bash result

  3. Insert in .md file within markdown code > Example >> enter image description here

  4. See the output and be happy =) >enter image description here

Solution 2 - Github

I wrote a small script that does the trick:

#!/bin/bash

#File: tree-md

tree=$(tree -tf --noreport -I '*~' --charset ascii $1 |
       sed -e 's/| \+/  /g' -e 's/[|`]-\+/ */g' -e 's:\(* \)\(\(.*/\)\([^/]\+\)\):\1[\4](\2):g')

printf "# Project tree\n\n${tree}"

Example:

Original tree command:
$ tree
.
├── dir1
│   ├── file11.ext
│   └── file12.ext
├── dir2
│   ├── file21.ext
│   ├── file22.ext
│   └── file23.ext
├── dir3
├── file_in_root.ext
└── README.md

3 directories, 7 files
Markdown tree command:
$ ./tree-md .
# Project tree

.
 * [tree-md](./tree-md)
 * [dir2](./dir2)
   * [file21.ext](./dir2/file21.ext)
   * [file22.ext](./dir2/file22.ext)
   * [file23.ext](./dir2/file23.ext)
 * [dir1](./dir1)
   * [file11.ext](./dir1/file11.ext)
   * [file12.ext](./dir1/file12.ext)
 * [file_in_root.ext](./file_in_root.ext)
 * [README.md](./README.md)
 * [dir3](./dir3)
Rendered result:

(Links are not visible in Stackoverflow...)

Project tree

Solution 3 - Github

Not directly, no. You'd have to hand create it and put it in yourself. Assuming you are using a *nix box locally and are using utf, then tree will generate it nicely (I believe that is what generated the example you used above).

Assuming you mean the readme.md as the documentation target, then I think the only way you could automate it would be a git pre-commit hook that ran tree and embedded it into your readme file. You'd want to do a diff to make sure you only updated the readme if the output changed.

Otoh if you are maintaining seperate docs via github pages, then what you could do, is switch to using jekyll (or another generator) locally and pushing the static pages yourself. Then you could potentially implement the changes you want either as a plugin / shell script* / manual changes (if they won't vary much), or use the same method as above.

*If you integrate it into a commit hook, you can avoid adding any extra steps to changing your pages.

Solution 4 - Github

I made a node module to automate this task: mddir

Usage

node mddir "../relative/path/"

To install: npm install mddir -g

To generate markdown for current directory: mddir

To generate for any absolute path: mddir /absolute/path

To generate for a relative path: mddir ~/Documents/whatever.

The md file gets generated in your working directory.

Currently ignores node_modules, and .git folders.

Troubleshooting

If you receive the error 'node\r: No such file or directory', the issue is that your operating system uses different line endings and mddir can't parse them without you explicitly setting the line ending style to Unix. This usually affects Windows, but also some versions of Linux. Setting line endings to Unix style has to be performed within the mddir npm global bin folder.

Line endings fix

Get npm bin folder path with:

npm config get prefix

Cd into that folder

brew install dos2unix

dos2unix lib/node_modules/mddir/src/mddir.js

This converts line endings to Unix instead of Dos

Then run as normal with: node mddir "../relative/path/".

Example generated markdown file structure 'directoryList.md'
    |-- .bowerrc
    |-- .jshintrc
    |-- .jshintrc2
    |-- Gruntfile.js
    |-- README.md
    |-- bower.json
    |-- karma.conf.js
    |-- package.json
    |-- app
        |-- app.js
        |-- db.js
        |-- directoryList.md
        |-- index.html
        |-- mddir.js
        |-- routing.js
        |-- server.js
        |-- _api
            |-- api.groups.js
            |-- api.posts.js
            |-- api.users.js
            |-- api.widgets.js
        |-- _components
            |-- directives
                |-- directives.module.js
                |-- vendor
                    |-- directive.draganddrop.js
            |-- helpers
                |-- helpers.module.js
                |-- proprietary
                    |-- factory.actionDispatcher.js
            |-- services
                |-- services.cardTemplates.js
                |-- services.cards.js
                |-- services.groups.js
                |-- services.posts.js
                |-- services.users.js
                |-- services.widgets.js
        |-- _mocks
            |-- mocks.groups.js
            |-- mocks.posts.js
            |-- mocks.users.js
            |-- mocks.widgets.js

Solution 5 - Github

Here is a useful git alias that works for me.

git config --global alias.tree '! git ls-tree --full-name --name-only -t -r HEAD | sed -e "s/[^-][^\/]*\//   |/g" -e "s/|\([^ ]\)/|-- \1/"'

Here is the output of git tree

jonavon@XPS13:~/projects/roman-numerals$ git tree
.gitignore
pom.xml
src
   |-- main
   |   |-- java
   |   |   |-- com
   |   |   |   |-- foxguardsolutions
   |   |   |   |   |-- jonavon
   |   |   |   |   |   |-- AbstractFile.java
   |   |   |   |   |   |-- roman
   |   |   |   |   |   |   |-- Main.java
   |   |   |   |   |   |   |-- Numeral.java
   |   |   |   |   |   |   |-- RomanNumberInputFile.java
   |   |   |   |   |   |   |-- RomanNumeralToDecimalEvaluator.java
   |-- test
   |   |-- java
   |   |   |-- com
   |   |   |   |-- foxguardsolutions
   |   |   |   |   |-- jonavon
   |   |   |   |   |   |-- roman
   |   |   |   |   |   |   |-- InterpretSteps.java
   |   |   |   |   |   |   |-- RunCukesTest.java
   |   |-- resources
   |   |   |-- com
   |   |   |   |-- foxguardsolutions
   |   |   |   |   |-- jonavon
   |   |   |   |   |   |-- roman
   |   |   |   |   |   |   |-- Interpret.feature
   |   |   |-- sample-input.txt

The comparable tree command

jonavon@XPS13:~/projects/roman-numerals$ tree -n
.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   │       └── com
│   │           └── foxguardsolutions
│   │               └── jonavon
│   │                   ├── AbstractFile.java
│   │                   └── roman
│   │                       ├── Main.java
│   │                       ├── Numeral.java
│   │                       ├── RomanNumberInputFile.java
│   │                       └── RomanNumeralToDecimalEvaluator.java
│   └── test
│       ├── java
│       │   └── com
│       │       └── foxguardsolutions
│       │           └── jonavon
│       │               └── roman
│       │                   ├── InterpretSteps.java
│       │                   └── RunCukesTest.java
│       └── resources
│           ├── com
│           │   └── foxguardsolutions
│           │       └── jonavon
│           │           └── roman
│           │               └── Interpret.feature
│           └── sample-input.txt
└── target
    ├── classes
    │   └── com
    │       └── foxguardsolutions
    │           └── jonavon
    │               ├── AbstractFile.class
    │               └── roman
    │                   ├── Main.class
    │                   ├── Numeral.class
    │                   ├── RomanNumberInputFile.class
    │                   └── RomanNumeralToDecimalEvaluator.class
    ├── generated-sources
    │   └── annotations
    └── maven-status
        └── maven-compiler-plugin
            └── compile
                └── default-compile
                    ├── createdFiles.lst
                    └── inputFiles.lst

30 directories, 17 files

Clearly tree has better output, but I like this way because it only shows the relevant source files and not the .git directory and compiled binaries.

Solution 6 - Github

The best way to do this is to surround your tree in the triple backticks to denote a code block. For more info, see the markdown docs: http://daringfireball.net/projects/markdown/syntax#code

Solution 7 - Github

None of the above solution worked for me completely on my mac.

The best solution I found this is to use the utility created here.

https://github.com/michalbe/md-file-tree

Once you have installed the utility npm install md-file-tree -g then you can simply run to get all files tree

md-file-tree . > README.md

Solution 8 - Github

Yes there is a way, In your readme.md file just copy & paste the tree you have generated in between three of back quotes like as if you are writing a code in markdown, it will work. Please see the below attachment. ``` your tree ```

enter image description here

Solution 9 - Github

In Linux the tree command can be used to list all the files/dir under the directory

if someone just wants to list directories & not files

$ tree -d

data
├── cats_vs_dogs
│   ├── test_cat_dog
│   ├── testing
│   │   ├── cats
│   │   └── dogs
│   └── training
│       ├── cats
│       └── dogs
└── PetImages
    ├── Cat
    └── Dog

copy the output & wrap it 3 backticks ``` in the markdown file.

Solution 10 - Github

You can also check this tree-extended package. It can be used as a command line app by using node >= 6.x.

It is very similar to tree but also has the option of configuring the max deep in the tree, that is one of the awful things of it. Also you can filter by using .gitignore file.

enter image description here

Solution 11 - Github

You can use <pre> tags as I did in one of my projects.

Solution 12 - Github

Simple tree command will do the job. For example: tree -o readme.md will print the tree structure of your current working directory and write it to readme.md. Then open readme.md file in one of text editor like Sublime and wrap its content within a pair of triple backticks (```).

FYI: you might have to brew install tree in OSX if it's not already installed. In Linux and Windows it should just work fine. Also in windows you might have to replace hyphen with forward slash.

I hope this helps.

Solution 13 - Github

> Insert command tree in bash.

Also, there is a DOS comnand "tree". You can displays directory paths and files in each subdirectory with command:

tree /F

https://web.csulb.edu/~murdock/tree.html

Solution 14 - Github

For those who want a quick solution:

There is a way to get a output to the console similar to the output from tree, by typing the following command into your terminal:

ls -R YOURFOLDER | grep ':$' | sed -e 's/:$//' -e 's/[^\/]*\//|  /g' -e 's/|  \([^|]\)/|–– \1/g' 

This alternative is mentioned in this documentation: https://wiki.ubuntuusers.de/tree/

Then the output can be copied and encapsuled inside a .md file with code block back tics, like mentioned in Jonathas B.C.'s answer.

But be aware that it also outputs all node modules folders in a node project. And in tree you can do something like

tree -I node_modules

to exlude the node modules folder.

Solution 15 - Github

I just like to generate it with UTF-8 and link it to every file and folder to navigate really easily. Please take a look at the example here.

The denerated markdown file

Solution 16 - Github

If you are working on windows write tree /f inside the directory you want to achieve that in command prompt. This should do your job. you can copy and paste the output on markdown surrounded my triple back ticks i.e. '''{tree structure here}'''

Solution 17 - Github

This python module (I am the author) generates directory-trees dynamically based on a specific tag added to the project's files.

For example, inserting in a file a comment line like the following:

# [treesource] the file description

Will generate an entry for this file in the generate tree. The tree, by default, shows only the files that have been tagged.

A generated tree looks like this:

$ python -m treesource
.
├── example_folder\
│   ├── first_subfolder\ (a documented folder)
│   │   ├── sub-sub1\
│   │   │   └── file3.sh (this is file 3)
│   │   ├── sub-sub2\
│   │   │   └── file4.cpp (this is file 4)
│   │   └── random_file.rdm (a documented file)
│   ├── second_subfolder\ (a documented folder with no documented files)
│   ├── a_text_file.txt (a text file)
│   ├── my_javascript.js (this is file 1)
│   └── test.py (a python script)
└── README.md (The main readme)

and can directly be exported in makdown format:

.
├── example_folder\
│ ├── first_subfolder\ a documented folder
│ │ ├── sub-sub1\
│ │ │ └── file3.sh this is file 3
│ │ ├── sub-sub2\
│ │ │ └── file4.cpp this is file 4
│ │ └── random_file.rdm a documented file
│ ├── second_subfolder\ a documented folder with no documented files
│ ├── a_text_file.txt a text file
│ ├── my_javascript.js this is file 1
│ └── test.py a python script
└── README.md The main readme\

Solution 18 - Github

it works in my MAC.


➜  examle-web git:(develop) ✗ tree src -d -L 1
src
├── api
├── assets
├── biz
├── constants
├── hooks
├── layout
├── queries
├── routes
├── store
├── themes
├── types
├── ui-component
├── utils
├── views
└── zustands

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1694077View Question on Stackoverflow
Solution 1 - Githubjonathasborges1View Answer on Stackoverflow
Solution 2 - GithubSimonView Answer on Stackoverflow
Solution 3 - GithubOliver MatthewsView Answer on Stackoverflow
Solution 4 - GithubJohn ByrneView Answer on Stackoverflow
Solution 5 - GithubjonavonView Answer on Stackoverflow
Solution 6 - Githubjoe sepiView Answer on Stackoverflow
Solution 7 - Githubnagendra547View Answer on Stackoverflow
Solution 8 - GithubManojView Answer on Stackoverflow
Solution 9 - GithubAmit DubeView Answer on Stackoverflow
Solution 10 - GithubRaúl OtañoView Answer on Stackoverflow
Solution 11 - GithubborngeekView Answer on Stackoverflow
Solution 12 - GithubGyanView Answer on Stackoverflow
Solution 13 - GithubBorisVView Answer on Stackoverflow
Solution 14 - GithubvindomView Answer on Stackoverflow
Solution 15 - GithubДеян ДобромировView Answer on Stackoverflow
Solution 16 - GithubParikshit SinghView Answer on Stackoverflow
Solution 17 - GithubMarcoPView Answer on Stackoverflow
Solution 18 - GithubkeatingView Answer on Stackoverflow