...
1treeprint [](https://godoc.org/github.com/xlab/treeprint) 
2=========
3
4Package `treeprint` provides a simple ASCII tree composing tool.
5
6<a href="https://upload.wikimedia.org/wikipedia/commons/5/58/ENC_SYSTEME_FIGURE.jpeg"><img alt="SYSTEME FIGURE" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/58/ENC_SYSTEME_FIGURE.jpeg/896px-ENC_SYSTEME_FIGURE.jpeg" align="left" width="300"></a>
7
8If you are familiar with the [tree](http://mama.indstate.edu/users/ice/tree/) utility that is a recursive directory listing command that produces a depth indented listing of files, then you have the idea of what it would look like.
9
10On my system the command yields the following
11
12```
13 $ tree
14.
15├── LICENSE
16├── README.md
17├── treeprint.go
18└── treeprint_test.go
19
200 directories, 4 files
21```
22
23and I'd like to have the same format for my Go data structures when I print them.
24
25## Installation
26
27```
28$ go get github.com/xlab/treeprint
29```
30
31## Concept of work
32
33The general idea is that you initialise a new tree with `treeprint.New()` and then add nodes and
34branches into it. Use `AddNode()` when you want add a node on the same level as the target or
35use `AddBranch()` when you want to go a level deeper. So `tree.AddBranch().AddNode().AddNode()` would
36create a new level with two distinct nodes on it. So `tree.AddNode().AddNode()` is a flat thing and
37`tree.AddBranch().AddBranch().AddBranch()` is a high thing. Use `String()` or `Bytes()` on a branch
38to render a subtree, or use it on the root to print the whole tree.
39
40The utility will yield Unicode-friendly trees. The output is predictable and there is no platform-dependent exceptions, so if you have issues with displaying the tree in the console, all platform-related transformations can be done after the tree has been rendered: [an example](https://github.com/xlab/treeprint/issues/2#issuecomment-324944141) for Asian locales.
41
42## Use cases
43
44### When you want to render a complex data structure:
45
46```go
47func main() {
48 // to add a custom root name use `treeprint.NewWithRoot()` instead
49 tree := treeprint.New()
50
51 // create a new branch in the root
52 one := tree.AddBranch("one")
53
54 // add some nodes
55 one.AddNode("subnode1").AddNode("subnode2")
56
57 // create a new sub-branch
58 one.AddBranch("two").
59 AddNode("subnode1").AddNode("subnode2"). // add some nodes
60 AddBranch("three"). // add a new sub-branch
61 AddNode("subnode1").AddNode("subnode2") // add some nodes too
62
63 // add one more node that should surround the inner branch
64 one.AddNode("subnode3")
65
66 // add a new node to the root
67 tree.AddNode("outernode")
68
69 fmt.Println(tree.String())
70}
71```
72
73Will give you:
74
75```
76.
77├── one
78│ ├── subnode1
79│ ├── subnode2
80│ ├── two
81│ │ ├── subnode1
82│ │ ├── subnode2
83│ │ └── three
84│ │ ├── subnode1
85│ │ └── subnode2
86│ └── subnode3
87└── outernode
88```
89
90### Another case, when you have to make a tree where any leaf may have some meta-data (as `tree` is capable of it):
91
92```go
93func main {
94 // to add a custom root name use `treeprint.NewWithRoot()` instead
95 tree := treeprint.New()
96
97 tree.AddNode("Dockerfile")
98 tree.AddNode("Makefile")
99 tree.AddNode("aws.sh")
100 tree.AddMetaBranch(" 204", "bin").
101 AddNode("dbmaker").AddNode("someserver").AddNode("testtool")
102 tree.AddMetaBranch(" 374", "deploy").
103 AddNode("Makefile").AddNode("bootstrap.sh")
104 tree.AddMetaNode("122K", "testtool.a")
105
106 fmt.Println(tree.String())
107}
108```
109
110Output:
111
112```
113.
114├── Dockerfile
115├── Makefile
116├── aws.sh
117├── [ 204] bin
118│ ├── dbmaker
119│ ├── someserver
120│ └── testtool
121├── [ 374] deploy
122│ ├── Makefile
123│ └── bootstrap.sh
124└── [122K] testtool.a
125```
126
127### Iterating over the tree nodes
128
129```go
130tree := New()
131
132one := tree.AddBranch("one")
133one.AddNode("one-subnode1").AddNode("one-subnode2")
134one.AddBranch("two").AddNode("two-subnode1").AddNode("two-subnode2").
135 AddBranch("three").AddNode("three-subnode1").AddNode("three-subnode2")
136tree.AddNode("outernode")
137
138// if you need to iterate over the whole tree
139// call `VisitAll` from your top root node.
140tree.VisitAll(func(item *node) {
141 if len(item.Nodes) > 0 {
142 // branch nodes
143 fmt.Println(item.Value) // will output one, two, three
144 } else {
145 // leaf nodes
146 fmt.Println(item.Value) // will output one-*, two-*, three-* and outernode
147 }
148})
149
150```
151Yay! So it works.
152
153## License
154MIT
View as plain text