public
Last active

Vim: Preview a Markdown document in the default browser on Windows or Mac OS X

  • Download Gist
markdown.vim
VimL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
"
" While editing a Markdown document in Vim, preview it in the
" default browser.
"
" Author: Nate Silva
"
" To install: Place markdown.vim in ~/.vim/ftplugin or
" %USERPROFILE%\vimfiles\ftplugin.
"
" To use: While editing a Markdown file, press ',p' (comma p)
"
" Tested on Windows and Mac OS X. Should work on Linux if you set
" BROWSER_COMMAND properly.
"
" Requires the `markdown` command to be on the system path. If you
" do not have the `markdown` command, install one of the following:
"
" http://www.pell.portland.or.us/~orc/Code/discount/
" http://www.freewisdom.org/projects/python-markdown/
"
function!PreviewMarkdown()
" **************************************************************
" Configurable settings
 
let MARKDOWN_COMMAND = 'markdown'
 
if has('win32')
" note important extra pair of double-quotes
let BROWSER_COMMAND = 'cmd.exe /c start ""'
else
let BROWSER_COMMAND = 'open'
endif
 
" End of configurable settings
" **************************************************************
 
silent update
let output_name = tempname() . '.html'
 
" Some Markdown implementations, especially the Python one,
" work best with UTF-8. If our buffer is not in UTF-8, convert
" it before running Markdown, then convert it back.
let original_encoding = &fileencoding
let original_bomb = &bomb
if original_encoding != 'utf-8' || original_bomb == 1
set nobomb
set fileencoding=utf-8
silent update
endif
 
" Write the HTML header. Do a CSS reset, followed by setting up
" some basic styles from YUI, so the output looks nice.
let file_header = ['<html>', '<head>',
\ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">',
\ '<title>Markdown Preview</title>',
\ '<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.3.0/build/cssreset/reset-min.css">',
\ '<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.3.0/build/cssbase/base-min.css">',
\ '<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.3.0/build/cssfonts/fonts-min.css">',
\ '<style>body{padding:20px;}div#container{background-color:#F2F2F2;padding:0 20px;margin:0px;border:solid #D0D0D0 1px;}</style>',
\ '</head>', '<body>', '<div id="container">']
call writefile(file_header, output_name)
 
let md_command = '!' . MARKDOWN_COMMAND . ' "' . expand('%:p') . '" >> "' .
\ output_name . '"'
silent exec md_command
 
if has('win32')
let footer_name = tempname()
call writefile(['</div></body></html>'], footer_name)
silent exec '!type "' . footer_name . '" >> "' . output_name . '"'
exec delete(footer_name)
else
silent exec '!echo "</div></body></html>" >> "' .
\ output_name . '"'
endif
 
" If we changed the encoding, change it back.
if original_encoding != 'utf-8' || original_bomb == 1
if original_bomb == 1
set bomb
endif
silent exec 'set fileencoding=' . original_encoding
silent update
endif
 
silent exec '!' . BROWSER_COMMAND . ' "' . output_name . '"'
 
exec input('Press ENTER to continue...')
echo
exec delete(output_name)
endfunction
 
" Map this feature to the key sequence ',p' (comma lowercase-p)
map ,p :call PreviewMarkdown()<CR>

Beautiful!
I love how simple this is :)

Great script!

Tested on Linux:

  1. I don't know whether Linux has an 'open' command, but 'xdg-open' generally works.

  2. Some terminals won't redraw after the script exits. I don't know whose problem it is. But add a 'redraw!' command in the end fix it.

xdg-open doesn't work for me.

I added this function:

    function! OpenDocument(document)
        if has("win32") || has("win64")
            " It's often recommended to use the build-in 'start' command of the cmd
            " shell, but that didn't seem to work on my Windows 7 machine. Invoking
            " Explorer opens the document correctly
            call system("explorer \"" . a:document . "\"")
        elseif has("unix")
            " OS X or Linux? Note that we can't rely on has("mac") here as this
            " isn't set for the console Vim shipping with OS X
            let s:uname = system("uname")
            if s:uname == "Darwin\n"
                " Use 'open' command on OS X
                call system("open '" . a:document . "'")
            else
                " Assume we're on Linux, use 'xdg-open'
                call system("xdg-open '" . a:document . "'")
            endif
        endif
    endfunc

And changed this:

    silent exec '!' . BROWSER_COMMAND . ' "' . output_name . '"'

for this:

    call OpenDocument(output_name)

Hi, thanks for contributing. It works just great.

By the way, have you considered making a pull request to https://github.com/tpope/vim-markdown ?

Best regards :)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.