Skip to content

Instantly share code, notes, and snippets.

@lelandbatey
Created May 23, 2019 17:41
Show Gist options
  • Save lelandbatey/b0d7bd5ae5817f0487b5827d20bc5529 to your computer and use it in GitHub Desktop.
Save lelandbatey/b0d7bd5ae5817f0487b5827d20bc5529 to your computer and use it in GitHub Desktop.
Turn an indented block of text into a 'tree' view with unicode lines
#!/usr/bin/env python3
'''
Treeify takes a file (on stdin or passed as the first argument) and converts
it's indentation into a 'tree' representation. As an example:
what
is
this
thing
that's
happening
becomes the following "tree" structure:
└ what
├ is
├ this
│ └ thing
├ that's
└ happening
Note that treeify requires all indentation to be done using spaces and only
accepts four spaces as one 'indentation level'.
'''
import fileinput
def count_indent(line):
for idx, c in enumerate(line):
if not c.isspace():
return idx // 4
return 0
def get_tree(lines, depth):
level = list()
while True:
if len(lines) < 1:
return level
if not lines[0].strip():
lines.pop(0)
continue
curdepth = count_indent(lines[0])
if curdepth > depth:
level.append(get_tree(lines, curdepth))
elif curdepth == depth:
level.append(lines.pop(0).strip())
elif curdepth < depth:
return level
def non_lists_exist(collection):
for x in collection:
if not isinstance(x, list):
return True
return False
def print_level(level, prefix=''):
PARENT_CONTINUATION_PREFIX = '│ '
NOPARENT_PREFIX = ' '
ITEM_MARK = '├ '
END_LEVEL = '└ '
while True:
if len(level) < 1:
return
cur = level[0]
nxt = None
if len(level) > 1:
nxt = level[1]
if isinstance(cur, list):
if len(level) > 1:
print_level(cur, '{}{}'.format(prefix,
PARENT_CONTINUATION_PREFIX))
else:
print_level(cur, '{}{}'.format(prefix, NOPARENT_PREFIX))
elif nxt is None:
print('{}{}{}'.format(prefix, END_LEVEL, cur))
return
else:
# Handle the case where there aren't any more strings at this level
cur_prefix = END_LEVEL
if non_lists_exist(level[1:]):
cur_prefix = ITEM_MARK
print('{}{}{}'.format(prefix, cur_prefix, cur))
level.pop(0)
def main():
docs_structure_lines = list()
docs_structure_lines = [x for x in fileinput.input()]
tree = get_tree(docs_structure_lines, 0)
print_level(tree)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment