DEV Community

Cover image for Vim to the rescue: Tree to Markdown
Angad Sharma
Angad Sharma

Posted on

Vim to the rescue: Tree to Markdown

The What

Recently, I was working on my competitive-coding skills to land a job. But like a developer I was pushing each and every program that I made to GitHub. I wanted a way to list down all the files I made in my README.md file in a readable format.

The tree command is a very useful utility to list out the hierarchy inside a project. My aim was to convert this hierarchial structure into a markdown list:

Before:

.
├── arrays
│   ├── k-smallest-fastest.cpp
│   ├── k-smallest-using-set.cpp
│   └── rotate.cpp
Enter fullscreen mode Exit fullscreen mode

After:

* arrays
   * k-smallest-fastest.cpp
   * k-smallest-using-set.cpp
   * rotate.cpp
Enter fullscreen mode Exit fullscreen mode

To see what we are going to make in detail, check this video out:


The How

Working with the hierarchy that we have, we need to perform a series of find and replace operations to get our output. The only challenge is that our symbols | |-- -- are not utf-8 encoded. Which means that we cannot type them using our standard keyboard. So to search for these tags, we need to copy paste them.

Flow


Removing the left-most pipe

Now let us perform our first operation:

:%s/│//
Enter fullscreen mode Exit fullscreen mode

This will search for all (which are in the left side of the hierarchy) and delete them. Now to type this command, you can copy paste the character from your file, or you can directly go into the vim command line with in your cursor and press Ctrl + r + " to paste it there, which is a more intuitive way of approaching the problem. We get this as our output:

.
|── arrays
   ├── k-smallest-fastest.cpp
   ├── k-smallest-using-set.cpp
   └── rotate.cpp
Enter fullscreen mode Exit fullscreen mode

Replacing the sub-element pipe with a star

To convert our hierarchy to a list, every sub-element needs to remain in the same position and have a * next to it. This can be achieved by replacing the ├── character by a *:

:%s/├──/*/
Enter fullscreen mode Exit fullscreen mode

Our output now look like this:

.
* arrays
   * k-smallest-fastest.cpp
   * k-smallest-using-set.cpp
   └── rotate.cpp
Enter fullscreen mode Exit fullscreen mode

Replacing the last sub-element pipe with a star

Notice that the last sub-element still has the pipe character in front of it. It can be replaced by the following and subsequent output is given below:

:%s/└──/*/
Enter fullscreen mode Exit fullscreen mode
.
* arrays
   * k-smallest-fastest.cpp
   * k-smallest-using-set.cpp
   * rotate.cpp
Enter fullscreen mode Exit fullscreen mode

Are we done? Not quite. If you look at the produced output in a markdown previewer, you will notice that it does not render properly. Why?

That is because there are hidden unicode characters in this file which we need to replace by a space character. To show all whitespaces, you can run the following commands:

:set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<,space::set list

" to see unicode characters in the statusline
:set statusline=%b\ %B
Enter fullscreen mode Exit fullscreen mode

This will yield the following output:

Alt Text

Notice that in the statusline we can view the invisible character as A0. We need to replace it by space, which can be easily done by:

:%s/\%u00a0/ /g
Enter fullscreen mode Exit fullscreen mode

And voila, we have our output!


Combining everything

In vim, the pipe (|) character can be used to pipe multiple find and replace commands. So everything we did here can be condensed to the following command:

:%s/│//|%s/├──/*/|%s/└──/*/|%s/\%u00a0/ /g
Enter fullscreen mode Exit fullscreen mode

What lies ahead

I have made a plugin called treemd which maps some very easy keybindings for converting your tree buffer to a markdown list. There is a bonus keybinding for running the tree command with a specified depth, in the current directory and using it as a markdown list:

GitHub logo L04DB4L4NC3R / treemd.vim

A simple vim plugin to convert the output of tree command to a markdown list

treemd.vim

A simple vim plugin to convert the output of tree command to a markdown list

Installation

If using pathogen, simply run the following command:

git clone https://github.com/L04DB4L4NC3R/treemd.vim.git ~/.vim/bundle/treemd.vim
Enter fullscreen mode Exit fullscreen mode

demo

Keybindings

Mode Mapping Action
Normal tmd Convert to markdown
Normal [num]tmt Run tree command with depth = num, in the current dir and convert to markdown

Top comments (1)

Collapse
 
drepram profile image
Andre Christoga Pramaditya

This post was really helpful and concise, thanks Angad!