2011年10月27日木曜日

Emacs nxml-modeの設定

最近、スマフォ関係でhtml5で書くことが多くなってきました。今まで使用していたpsgml-modeはhtml5と相性が悪く、インデントやタグの補完がうまく動かないので、nxml-modeに変更してみることにしました。

nxml-modeはCarbon Emacsやemacs23以降には標準搭載されているので、インストールは特に不要ですが、別途hober/html5-elをインストールする必要があります。

nxml-modeの設定

最初にnxml-modeの設定を行って、正常に動作するかチェックします。下記のように設定しました。

(setq auto-mode-alist
      (append '(
                ;;("\\.\\(html\\|xhtml\\|shtml\\|tpl\\)\\'" . xml-mode)
                ("\\.\\(html\\|xhtml\\|shtml\\|tpl\\)\\'" . nxml-mode)
                ("\\.php\\'" . php-mode)
                )
              auto-mode-alist))

(load "rng-auto.el" 't)
(add-hook 'nxml-mode-hook
          (lambda ()
            ;; 更新タイムスタンプの自動挿入
            (setq time-stamp-line-limit 10000)
            (if (not (memq 'time-stamp write-file-hooks))
                (setq write-file-hooks
                      (cons 'time-stamp write-file-hooks)))
            (setq time-stamp-format "%3a %3b %02d %02H:%02M:%02S %:y %Z")
            (setq time-stamp-start "Last modified:[ \t]")
            (setq time-stamp-end "$")
            ;;
            (setq auto-fill-mode -1)
            (setq nxml-slash-auto-complete-flag t)      ; スラッシュの入力で終了タグを自動補完
            (setq nxml-child-indent 2)                  ; タグのインデント幅
            (setq nxml-attribute-indent 4)              ; 属性のインデント幅
            (setq indent-tabs-mode t)
            (setq nxml-bind-meta-tab-to-complete-flag t) 
            (setq nxml-slash-auto-complete-flag t)      ; </の入力で閉じタグを補完する
            (setq nxml-sexp-element-flag t)             ; C-M-kで下位を含む要素全体をkillする
            (setq nxml-char-ref-display-glyph-flag nil) ; グリフは非表示
            (setq tab-width 4)))

custom-set-faces
 '(nxml-comment-content-face
   ((t (:foreground "red"))))                            ; コメント
 '(nxml-comment-delimiter-face
   ((t (:foreground "red"))))                            ; <!-- -->
 '(nxml-delimited-data-face
   ((t (:foreground "DarkViolet"))))                     ; 属性値やDTD引数値など
 '(nxml-delimiter-face
   ((t (:foreground "blue"))))                           ; <> <? ?> ""
 '(nxml-element-local-name-face
   ((t (:inherit nxml-name-face :foreground "blue"))))   ; 要素名
 '(nxml-name-face
   ((t (:foreground "dark green"))))                     ; 属性名など
 '(nxml-element-colon-face
   ((t (:foreground "LightSteelBlue"))))                 ; :(xsl:paramなど)
 '(nxml-ref-face
   ((t (:foreground "DarkGoldenrod"))))                  ; &lt;など
 '(nxml-tag-slash-face
   ((t (:inherit nxml-name-face :foreground "blue")))))  ; /(終了タグ)

設定後htmlファイルを開くと、モードラインにnXMLと表示されます。そしてHTML構文に誤りが無ければValidと表示されます。

nxml-mode

また、"C-c C-s C-w"で現在どのスキーマを使用しているか表示してみると'/Applications/Emacs.app/Contents/Resources/site-lisp/nxml-mode/schema/xhtml.rnc'が使われているのがわかります。

hober/html5-elのインストール

次にDownloads for hober's html5-elのページからファイルをダウンロードして適当なディレクトリに展開します。

$ cd ~/.elisp
$ tarxvfz ~/hober-html5-el-934944b.tar.gz
$ cd html5-el
$ make relaxng
$ make webapps
$ 

インストールが完了したら、README.markdownに従って設定を行います。

(add-to-list 'load-path "~/.elisp/html5-el/")
(eval-after-load "rng-loc"
   '(add-to-list 'rng-schema-locating-files "~/.elisp/html5-el/schemas.xml"))
(require 'whattf-dt)

設定後、同じファイルを開いて使用されてるスキーマを調べると'~/.elisp/html5-el/relaxng/xhtml5.rnc'となりhtml5(xhtml5?)対応になります。

nxml-mode html5

上記の場合、xhtml1をxhtml5として解釈しているため、Invalidとなってしまっています。こういうときは"C-c C-s C-t"と打って明示的にDocument Typeを指定する事が出来ます。指定したDocument Typeはrng-schema-locating-filesに保存されるので、次回からは指定しなくてもセットされます。

Document Type

rng-schema-locating-filesを修正

まだ、xhtmlで書くことの方が多いから、デフォルトはxhtmlでhtml5を編集する場合は"C-c C-s C-t"で明示的に指定したいと言うときは、rng-schema-locating-filesに定義したファイルを修正すれば出来ると思います。rng-schema-locating-filesはhober/html5-elをインストールしたときに"~/.elisp/html5-el/schemas.xml"に設定しました。

(eval-after-load "rng-loc"
   '(add-to-list 'rng-schema-locating-files "~/.elisp/html5-el/schemas.xml"))

このファイルの中身をみると下記のように記述されています。

<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
  <uri pattern="*.html" typeId="XHTML5"/>
  <uri pattern="*.xhtml" typeId="XHTML5"/>
  <namespace ns="http://www.w3.org/1999/xhtml" typeId="XHTML5"/>
  <documentElement localName="html" typeId="XHTML5"/>
  <typeId id="XHTML5" uri="relaxng/xhtml5.rnc"/>
</locatingRules>

これを次のように記述すれば良いと思います。

<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
  <uri pattern="*.html" typeId="XHTML"/>
  <uri pattern="*.xhtml" typeId="XHTML"/>
  <namespace ns="http://www.w3.org/1999/xhtml" typeId="XHTML5"/>
  <documentElement localName="html" typeId="XHTML5"/>
  <typeId id="XHTML5" uri="relaxng/xhtml5.rnc"/>
</locatingRules>

使い方

最初使い方がわからなかったのですが、youtubeにチュートリアルな動画がありましたので、それを見て大体の使い方は理解出来ました。



主なキーアサイン

主なキーアサインをまとめておきました。

編集系のキーアサイン
キー 関数 機能
C-c C-x nxml-insert-xml-declaration xml宣言文を挿入
C-return nxml-complete タグ・属性の補完
/ nxml-electric-slash 直前の「開始タグ」に対応する「終了タグ」で補完する
C-c tab nxml-balanced-close-start-tag-inline 直前の「開始タグ」に対応する「終了タグ」を同じ行に挿入する
C-c C-b nxml-balanced-close-start-tag-block 直前の「開始タグ」に対応する「終了タグ」を改行して挿入する
C-c C-u nxml-insert-named-char HTML Character Entityを挿入する
C-c C-d nxml-dynamic-markup-word 選択文字列をカレントバッファから探し、同じタグで補完する
移動系のキーアサイン
キー 関数 機能
ESC h nxml-mark-paragraph 現在の段落を選択する
ESC } nxml-forward-paragraph 上の段落に移動する
ESC { nxml-backward-paragraph 下の段落に移動する
ESC C-p nxml-backward-element 1要素後ろに移動する
ESC C-n nxml-forward-element 1要素前に移動する
ESC C-d nxml-down-element 下の階層の要素に移動する。(下の階層があれば)
ESC C-u nxml-backward-up-element 上の階層の要素に移動する。(上の階層があれば)
検証系のキーアサイン
キー 関数 機能
C-c C-v rng-validate-mode 検証モードの切り替え
C-c C-n rng-next-error エラーが発生した箇所に移動する
C-c C-s C-w rng-what-schema 現在どのスキーマを使用しているか表示する
C-c C-s C-t rng-set-document-type-and-validate 現在開いている文章のDocument Typeをセットし検証を行う
セットしたDocument Typeはスキーマファイルに保存される
C-c C-s C-f rng-set-schema-file-and-validate 指定したスキーマファイルを読込み検証を行う
C-c C-s C-a rng-auto-set-schema-and-validate 現在開いている文章に最適なスキーマを読込み検証を行う
C-c C-s C-l rng-save-schema-location 現在使用しているスキーマファイルを保存する

0 コメント:

コメントを投稿