2012/02/09

Recent entries from same category

  1. VimConf 2023 Tiny に参加しました
  2. Vim で Go 言語を書くために行った引越し作業 2020年度版
  3. Vim をモダンな IDE に変える LSP の設定
  4. ぼくがかんがえたさいきょうの Vim のこうせい 2019年 年末版
  5. VimConf 2019 を終えて

Vimが良くも悪くも「エディタだ」と言われる要因として「画像や異なるグリフのフォントを同時に出せない」ことを上げられます。つまりVimはHTMLやマークダウン等のプレビューを確認する為にいちいちブラウザを起動して確認し、ファイルを更新した際には読み込み直すという面倒な手間が掛かる事を意味しています。
まぁ専用ブラウザを作ればいいんだけど面倒で腰が重かったんだけど、ちょいと作ってみました。

mattn/mkdpreview-vim - GitHub

MkdPreview Markdown previewer for vimmer

https://github.com/mattn/mkdpreview-vim
ファイルタイプがmarkdownなバッファで :MkdPreview!
と実行するとプレビューワが起動します。
mkdpreview-vim
プレビューワが一度起動している状態なら、以後は他のVimからでも :MkdPreview
でプレビューが表示される様になっています。MkdPreview!を実行したVimに関してはBufWritePostに 対してプレビュー更新が行われる様になっているので:wで自動更新されます。この辺は使い勝手で変えていくかも知れない。
仕組みはpythonスクリプトで書かれたウェブサーバ兼Qt4を使ったプレビューワになっていて POSTを受けたらそれをmarkdown-jsを使ってQtWebkitに反映させています。 複数起動とかうっとおしいだろうなと思ったので、ポートは固定にしています。 起動に必要な物としては
  • python (2.7 or later) http://python.org/
  • PyQt4 http://www.riverbankcomputing.co.uk/software/pyqt/download
  • curl command http://curl.haxx.se/libcurl/
  • webapi-vim http://github.com/mattn/webapi-vim
  • markdown-js https://github.com/evilstreak/markdown-js
となります。pythonスクリプトは短いのでコードを貼り付けておきます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import json
import cgi
from threading import Thread
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtNetwork import *
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

os.chdir(os.path.dirname(__file__))

port = int(os.getenv("mkdpreview_port"or "8081")

QNetworkProxyFactory.setUseSystemConfiguration(True)
app = QApplication(sys.argv)
webview = QWebView()
webview.setWindowTitle('Markdown Previewer')
webview.load(QUrl("http://localhost:8081"))
def do_eval(js):
  webview.page().mainFrame().evaluateJavaScript(
      "preview(%s)" % json.dumps(unicode(js, 'utf-8')))
QObject.connect(webview, SIGNAL("preview(QString)"), do_eval)
webview.show()

class PreviewHandler(SimpleHTTPRequestHandler):
  def do_POST(self):
    s = self.rfile.read(int(self.headers.getheader('content-length')))
    p = cgi.parse_qs(s)
    webview.emit(SIGNAL("preview(QString)"), p["data"][0])
    self.wfile.write("")

class WebServer(QThread):
  def __init__(self):
    QThread.__init__(self)
    self.server = HTTPServer(("", port), PreviewHandler)

  def run(self):
    self.server.serve_forever()

server = WebServer()
server.start()

sys.exit(app.exec_())

# vim:set et sw=2 ts=2:
良かったら使ってみて下さい。 なお、ベースとなるHTMLはstaticフォルダにあるのでスタイル等をカスタマイズしたい人はじゃんじゃんやっちゃって下さい。 こうすればもっと使い勝手が良くなるよなどあればpull requestお願いします。

追記
Windowsじゃない人はstatic/mkdpreview.pyに実行権限与えて下さい。
markdown-jsじゃなくpython側でparseする様にしました。
Posted at by | Edit