kis9a / vimsidian

Vim plugin for PKM like obsidian.md
Do What The F*ck You Want To Public License
54 stars 0 forks source link

Export to PDF functionality #15

Open dlitvakb opened 3 months ago

dlitvakb commented 3 months ago

Here's a snippet to Export a Vimsidian (or any Obsidian-like) Markdown file to PDF.

It uses markdown-pdf to convert the current file into a PDF and save it to the /Exports folder under your Vimsidian Path.

It also requires a CSS stylesheet, but you can choose whichever. CSS File name is hardcoded, but could be easily extracted.

let $VIMSIDIAN_EXPORTS_PATH = g:vimsidian_path . '/Exports/'
let $VIMSIDIAN_MEDIA_PATH = g:vimsidian_path . '/Media/'
let $VIMSIDIAN_PDF_TEMPLATE_THEME = $VIMSIDIAN_EXPORTS_PATH . 'pdf_theme.min.css'

function! ToCleanMarkdown()
  " remove all comments
  silent execute '%s/<!--\(\(-->\)\@!\(.\|\n\)\)*-->//ge'

  " remove all trailing whitespace
  silent execute '%s/\s\+$//ge'

  " merge empty lines
  silent execute '%g/^$/,/./-j'

  " replace Obsidian links with aliases to the alias
  silent execute '%s/\[\[[^|]*[|]\+\([^\]]*\)\]\]/[[\1]]/ge'

  " remove all Obsidian links
  silent execute '%s/\[\[\([^\]]*\)\]\]/\1/ge'
endfunction

function! ExpandVimsidianMediaPath()
  silent execute '%s#!\[\([^\]]\+\)\](\([^)]\+\))#![\1](' . $VIMSIDIAN_MEDIA_PATH . '\2)#ge'
endfunction

function! GeneratePDFFromMarkdown()
  " prevent nerdtree sync from stopping process
  let nerdtree_toggled = 0
  if exists('g:NERDTree') && g:NERDTree.IsOpen()
    let nerdtree_toggled = 1
    silent execute 'NERDTreeToggle'
  endif

  " Set file names
  let current_file = expand('%:p')
  let output_file = $VIMSIDIAN_EXPORTS_PATH . expand('%:t:r') . '.pdf'
  let temp_file = current_file . '.tmp'

  " Copy current file into a temporary one
  silent execute '!cp "' . current_file . '" "' . temp_file . '"'

  " Create a buffer for the tempfile
  let current_buffer = bufnr('')
  let g:to_pdf = bufnr(temp_file, 1)

  " Switch to tempfile buffer
  silent execute g:to_pdf . 'buffer'

  call ToCleanMarkdown()
  call ExpandVimsidianMediaPath()

  " Add styling class and closing tag
  silent call append(line('^'), '<div class="fs-pdf">')
  silent call append(line('$'), '</div>')

  " clear search term
  silent noh

  " save temp file
  silent execute 'write'

  " go back to original buffer
  silent execute current_buffer . 'buffer'

  " Create markdown
  silent execute '!markdown-pdf -f A4 -m "{\"html\": true}" -s "' . $VIMSIDIAN_PDF_TEMPLATE_THEME . '" "' . temp_file . '" -o "' . output_file . '"'

  " clear no longer relevant buffer
  silent execute g:to_pdf . 'bwipeout'

  " remove file
  silent execute '!rm "' . temp_file . '"'

  " Open file in Preview
  silent execute '!open "' . output_file . '"'

  " update UI
  redraw!

  echo 'PDF Created at: ' . output_file

  " reopen NERDTree if closed
  if (nerdtree_toggled)
    silent execute 'NERDTreeToggle'
  endif
endfunction

augroup vimsidian_commands
  au!
  " other stuff here ...
    au BufNewFile,BufReadPost $VIMSIDIAN_PATH_PATTERN nn <silent> <Leader>P :call GeneratePDFFromMarkdown()<CR>
augroup END

Feel free to consider this and modify it to your liking

Cheers