Skip to content
VIM plugin for markup editing with live preview
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.dot
autoload
plugin
static
README.md

README.md

VimPreviewPandoc

Introduction

VimPreviewPandoc is VIM plugin that helps you with editing MarkDown-like documents.

Edit your MarkDown documents in VIM and see a nice HTML-based output in qutebrowser. The web browser always shows changed area so you don't need to scroll manually.

Features

  • Preview your MarkDown documents with qutebrowser

    • Scroll browser's view to show changed area automatically
    • Generate dot graphs with graphviz
    • Generate blockdiag, seqdiag, actdiag, nwdiag, packetdiag, rackdiag graphs
    • Generate R graphs
    • Generate PlantUML graphs
    • Generate ascii art based images with ditaa
  • Show structural diff of specified file between specified git revisions

    • :call vimpreviewpandoc#VimPreviewPandocGitDiff(expand("%"), "HEAD~5", "HEAD")

    • :Unite giti/log, press a (action), select diff_pandoc_preview

      Please see [Unite.vim integration] for required configuration.

  • Generate output document in specified output format

    • :call vimpreviewpandoc#VimPreviewPandocConvertTo("docx,html")

TODO

  • Decouple pandoc plugins to a separate project

Examples

Supports links

```
[Link to generated image from R](#whatever)
```

DOT Graph

This DOT code is shown as the following picture in the preview window:

```dot
graph {
A -- B
C -- B
C -- D
}
```

Blockdiag Graph

This DOT code is shown as the following picture in the preview window:

```blockdiag
blockdiag {
A -> B -> C
}
```

Seqdiag Graph

This Seqdiag code is shown as the following picture in the preview window:

```seqdiag
seqdiag {
  browser  -> webserver [label = "GET /index.html"];
  browser <-- webserver;
  browser  -> webserver [label = "POST /blog/comment"];
              webserver  -> database [label = "INSERT comment"];
              webserver <-- database;
  browser <-- webserver;
}
```

Actdiag Graph

This Actdiag code is shown as the following picture in the preview window:

```actdiag
actdiag {
  write -> convert -> image

  lane user {
     label = "User"
     write [label = "Writing reST"];
     image [label = "Get diagram IMAGE"];
  }
  lane actdiag {
     convert [label = "Convert reST to Image"];
  }
}
```

Nwdiag Graph

This Nwdiag code is shown as the following picture in the preview window:

```nwdiag
nwdiag {
  network dmz {
      address = "210.x.x.x/24"

      web01 [address = "210.x.x.1"];
      web02 [address = "210.x.x.2"];
  }
  network internal {
      address = "172.x.x.x/24";

      web01 [address = "172.x.x.1"];
      web02 [address = "172.x.x.2"];
      db01;
      db02;
  }
}
```

Packetdiag Graph

This Packetdiag code is shown as the following picture in the preview window:

```packetdiag
{
  colwidth = 32
  node_height = 72

  0-15: Source Port
  16-31: Destination Port
  32-63: Sequence Number
  64-95: Acknowledgment Number
  96-99: Data Offset
  100-105: Reserved
  106: URG [rotate = 270]
  107: ACK [rotate = 270]
  108: PSH [rotate = 270]
  109: RST [rotate = 270]
  110: SYN [rotate = 270]
  111: FIN [rotate = 270]
  112-127: Window
  128-143: Checksum
  144-159: Urgent Pointer
  160-191: (Options and Padding)
  192-223: data [colheight = 3]
}
```

Rackdiag Graph

This Rackdiag code is shown as the following picture in the preview window:

```rackdiag

rackdiag {
  // define height of rack
  16U;

  // define rack items
  1: UPS [2U];
  3: DB Server
  4: Web Server
  5: Web Server
  6: Web Server
  7: Load Balancer
  8: L3 Switch
}
```

R Graph

This R code is shown as the following picture in the preview window:

```{.r #whatever width=9 height=6 caption="R generated output"}
                              
y <- c(1,4,9,13,10)     
x <- c(1,2,3,4, 5 )
xx <- seq(1, 5, length.out=250)
       
plot(x, y)

fit <- lm(y~x)
label1 <- bquote(italic(R)^2 == .(format(summary(fit)$adj.r.squared, digits=4)))
lines(xx, predict(fit, data.frame(x=xx)))
fnc1 <- bquote(y == .(coef(fit)[[2]]) * x + .(coef(fit)[[1]]))

         
fit <- lm(y~poly(x,3, raw = TRUE))
label2 <- bquote(italic(R)^2 == .(format(summary(fit)$adj.r.squared, digits=4)))
lines(xx, predict(fit, data.frame(x=xx)))
fnc2 <- bquote(y == .(coef(fit)[[4]]) * x^3 + .(coef(fit)[[3]]) * x^2 + .(coef(fit)[[2]]) * x + .  (coef(fit)[[1]]))

labels <- c(label1, fnc1, label2, fnc2)
legend("topleft", bty="n", legend=as.expression(labels))
```

PlantUML

This PlantUML code as the following picture in the preview window:

```plantuml
@startuml
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml
```

Ditaa

This Ditaa code is shown as the following picture in the preview window:

```ditaa
+--------+   +-------+    +-------+
|        | --+ ditaa +--> |       | 
|  Text  |   +-------+    |diagram|
|Document|   |!magic!|    |       |
|     {d}|   |       |    |       |
+---+----+   +-------+    +-------+
    :                         ^
    |       Lots of work      |
    +-------------------------+
```

Installation

Install this plugin either manually or using any plugin manager (Vundle, NeoBundle, Plug...).

Make sure that python scripts in plugin sub folder (pre.py, blockdiag.py, ...) needs to have executable bit set. This is required by pandoc to read its shebang and execute it with python version as specified with the shebang.

Those plugins are required:

I also recommend you to install the following plugins to extend pandoc support:

Place your VIM on one side of your screen and when qutebrowser appears, move it to the other side to get productive environment. qutebrowser shows automatically correct preview.

Dependencies

  • VIM with python3 support
  • pandoc 1.12.3.3 and newer
  • python3 pandocfilters

Structural diff support

Dot graph support

Diag-family graphs support

R graph support

PlantUML

Ditaa

Qutebrowser

Unite.vim integration

Add the following code to your .vimrc to add diff_pandoc_preview action to vim-unite-giti's giti-log.

    if neobundle#tap("unite.vim")
                \ && neobundle#tap("vim-unite-giti")
                \ && neobundle#tap("vimpreviewpandoc")

        function! s:is_graph_only_line(candidate)
            return has_key(a:candidate.action__data, 'hash') ? 0 : 1
        endfunction

    let s:pandoc_diff_action = {
        \ 'description' : 'pandoc diff with vimpreviewpandoc',
        \ 'is_selectable' : 1,
        \ 'is_quit' : 1,
        \ 'is_invalidate_cache' : 0,
        \ }
    function! s:pandoc_diff_action.func(candidates)
        if s:is_graph_only_line(a:candidates[0])
                    \ || len(a:candidates) > 1 && s:is_graph_only_line(a:candidates[1])
            call giti#print('graph only line')
            return
        endif

        let file  = len(a:candidates[0].action__file) > 0
                    \               ? a:candidates[0].action__file
                    \               : expand('%:p')
        let relative_path = giti#to_relative_path(file)
        if len(a:candidates) == 1
            let from = a:candidates[0].action__data.hash
            call vimpreviewpandoc#VimPreviewPandocGitDiff(relative_path, from)
        elseif len(a:candidates) == 2
            let to   = a:candidates[0].action__data.hash
            let from = a:candidates[1].action__data.hash
            call vimpreviewpandoc#VimPreviewPandocGitDiff(relative_path, from, to)
        else
            call unite#print_error('select up to two commits')
            return
        endif
    endfunction

    call unite#custom#action('giti/log', 'diff_pandoc_preview', s:pandoc_diff_action)
    unlet s:pandoc_diff_action

endif

Theory of operation

BufwinEnter, CursorHold,CusrsorHildI events execute the following:

  • pandoc to convert MarkDown document to HTML

    • custom filter to create a graphviz graphs from dot code blocks

    • custom filter to create a blockdiag, seqdiag, actdiag, nwdiag, packetdiag, rackdiag graphs from blockdiag, seqdiag, actdiag, nwdiag, packetdiag, rackdiag blocks

    • custom filter to create a R generated graphs from R code blocks

    • custom filter to create a plantuml generated graphics from planuml code blocks

    • custom filter to create a ditaa generated graphics from ditaa code blocks

    • custom filter to fix block code view in qutebrowser

    • custom filter to replace relative paths to images to absolute paths

    • qutebrowser

      • qutebrowser uses a socket to talk to already running instance
      • this allows to execute JavaScript on loaded page
  • index.html is empty page with setCursor(word, count) and setOutput(html) functions

    • setCursor(word, count) finds the encoded position and scrolls window to it
    • setOutput(html) replaces the content of the div with a new one
You can’t perform that action at this time.