Search code examples
regexvimmarkdownoutlining

How to convert from VimOutliner to Markdown?


How could I convert a VimOutliner file to Markdown? In other words, I how to turn tab-indeted outlines like this...

Heading 1
    Heading 2
            Heading 3
            : Body text is separated by colons.
            : Another line of body text.
    Heading 4

...into hash-style headings separated by an empty line like this:

# Heading 1

## Heading 2

### Heading 3

Body text.

## Heading 4

I have tried defining a macro but I'm fairly new to Vim (and not a coder) so I've been unsuccessful so far. Thanks for any help!

(PS -- As for Markdown, I do know about the awesome VOoM plugin but I still prefer doing initial outlines for documents with no hash-characters in sight. Plus, I also like the way VimOutliner highlights different levels of headings.)


Solution

  • Place this functions in your vimrc and just use :call VO2MD() or :call MD2VO() as needed.

    function! VO2MD()
      let lines = []
      let was_body = 0
      for line in getline(1,'$')
        if line =~ '^\t*[^:\t]'
          let indent_level = len(matchstr(line, '^\t*'))
          if was_body " <= remove this line to have body lines separated
            call add(lines, '')
          endif " <= remove this line to have body lines separated
          call add(lines, substitute(line, '^\(\t*\)\([^:\t].*\)', '\=repeat("#", indent_level + 1)." ".submatch(2)', ''))
          call add(lines, '')
          let was_body = 0
        else
          call add(lines, substitute(line, '^\t*: ', '', ''))
          let was_body = 1
        endif
      endfor
      silent %d _
      call setline(1, lines)
    endfunction
    
    function! MD2VO()
      let lines = []
      for line in getline(1,'$')
        if line =~ '^\s*$'
          continue
        endif
        if line =~ '^#\+'
          let indent_level = len(matchstr(line, '^#\+')) - 1
          call add(lines, substitute(line, '^#\(#*\) ', repeat("\<Tab>", indent_level), ''))
        else
          call add(lines, substitute(line, '^', repeat("\<Tab>", indent_level) . ': ', ''))
        endif
      endfor
      silent %d _
      call setline(1, lines)
    endfunction