最近、スマフォ関係で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と表示されます。
また、"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?)対応になります。
上記の場合、xhtml1をxhtml5として解釈しているため、Invalidとなってしまっています。こういうときは"C-c C-s C-t"と打って明示的にDocument Typeを指定する事が出来ます。指定したDocument Typeはrng-schema-locating-filesに保存されるので、次回からは指定しなくてもセットされます。
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
|
現在使用しているスキーマファイルを保存する |