EmacsでHaml保存時に自動でHTMLを出力する

福山です。Haml習得によって、HTMLを効率的に書くことができるかも。ということで手を伸ばしてみました。

使ったものとバージョン

  • Mac OSX Lion 10.7.3
  • Cocoa Emacs 23.4
  • haml 3.1.4
  • haml-mode 3.0.15

Emacs上で M-! haml 対象ファイル 変換後ファイル
とすることも可能ですが、面倒なので .haml拡張子のファイル保存されたと同時に.htmlファイルを出力します。

まず、Emacsにhaml-modeをインストールします。

nex3 / haml-mode

ターミナルを開き、以下を入力しマッス。
sudo gem install haml
準備完了!

セーブ時オートコンパイル設定

init.el(emacs.el)に以下を書き込みます。


;; Emacsにhamlコマンドのあるフォルダを教える
(setenv "PATH" (concat "/Users/-略-/haml-3.1.4/bin" ":" (getenv "PATH")))
;; haml
(require 'haml-mode)
;; hamlからhtmlへコンパイル
(defun haml-compile ()
  (interactive)
  (let ((from buffer-file-name)
        (to (replace-regexp-in-string "\.haml$" ".html" buffer-file-name)))
    (shell-command-to-string
     (concat "haml" " --double-quote-attributes --format html5 " from " " to))))
;; 保存時に自動でhamlからhtmlへコンパイル
(add-hook 'haml-mode-hook
          '(lambda ()
            (add-hook 'after-save-hook 'haml-compile)))

elisp は詳しくないですが、とりあえず保存時にhtmlを自動で吐き出してくれるようなコードです。
--double-quote-attributesでシングルクオートをダブルクオートにしてHTMLへ出力する設定にしています。--style ugly とするとインデントなしのhtmlが出来上がります。ほかのオプションを使いたい場合はターミナルで haml --help と入力すると一覧が見れます。

Haml学習用設定

Hamlの出力結果がどうなるのかリアルタイム(html変換,隣のバッファリロード)に確認できるようにしてみました。縦でも横でもいいですが、上の画像のようにEmacsウィンドウを2分割します。
どちらかにhaml、もう一方に出力後のhtmlを開きます。


;; Emacsにhamlコマンドのあるフォルダを教える
(setenv "PATH" (concat "/Users/-略-/haml-3.1.4/bin" ":" (getenv "PATH")))
;; haml
(require 'haml-mode)
;; hamlからhtmlへコンパイル
(defun haml-compile ()
  (interactive)
  (let ((from buffer-file-name)
        (to (replace-regexp-in-string "\.haml$" ".html" buffer-file-name)))
    (shell-command-to-string
     (concat "haml" " --double-quote-attributes --format html5 " from " " to))
    ;;拡張子以外同名のhtmlバッファをリロードする
    (with-current-buffer (replace-regexp-in-string ".+\/\(.+\)" "\1" to)
      (revert-buffer nil t))))
;; 保存時に自動でhamlからhtmlへコンパイル
(add-hook 'haml-mode-hook
          (lambda ()
            (add-hook 'after-save-hook 'haml-compile nil t)))

補足

単にリロードしたい場合は、アンドゥでリロード前の内容に戻れるこちらの方法をお勧めします。

http://www.bookshelf.jp/soft/meadow_24.htmlより


;; 編集中のファイルを開き直す
;; - yes/no の確認が不要;;   - revert-buffer は yes/no の確認がうるさい
;; - 「しまった! 」というときにアンドゥで元のバッファの状態に戻れる
;;   - find-alternate-file は開き直したら元のバッファの状態に戻れない
;;
(defun reopen-file ()
  (interactive)
  (let ((file-name (buffer-file-name))
        (old-supersession-threat
         (symbol-function 'ask-user-about-supersession-threat))
        (point (point)))
    (when file-name
      (fset 'ask-user-about-supersession-threat (lambda (fn)))
      (unwind-protect
          (progn
            (erase-buffer)
            (insert-file file-name)
            (set-visited-file-modtime)
            (goto-char point))
        (fset 'ask-user-about-supersession-threat
              old-supersession-threat)))))

(define-key ctl-x-map "C-r"  'reopen-file)

おすすめ

Hamlの文法エラーを逐次チェックしてくれるelispがありましたのでご紹介します。
purcell / flymake-haml - github

おわりに

Hamlは確かに閉じ忘れはなくなるけど、なんというか使い続ければ良さが分かるのかもしれない..