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 Pramaditya •

This post was really helpful and concise, thanks Angad!