PSGML の導入

html-helper-mode はファイルを新規作成したときにフォントがおかしくなったりしてよく分からないので、前から気になっていた PSGML に乗り換えることにした。
しかしけっこうめんどくさかった。。
なので自分でもしまた同じことをししたり、他の人がやろうとしたときに思いっきり楽ができるようにしておこうと思った。
以下の手順ですぐに使えるようになります!たぶん。
html-helper-mode と違ってフォントがおかしくなったりしないので安心して使えてます。

;;; psgml の設定
;; http://www9.plala.or.jp/kirii/computer/psgml.html
(setq load-path (cons (expand-file-name "~/site-lisp/psgml-1.3.1/") load-path))
(autoload 'sgml-mode "psgml" "Major mode to edit SGML files." t)
(autoload 'xml-mode "psgml" "Major mode to edit XML files." t)
(add-to-list 'auto-mode-alist '("\\.\\(htm\\|html\\|shtm\\|shtml\\|xml\\|xhtml\\)\\'" . xml-mode))

;; カタログファイルの指定
(setq sgml-catalog-files '("CATALOG" "~/dtd/catalog"))
;; (setq sgml-ecat-files '("ECAT" "~/dtd/ecat"))

;; DTD の指定 (DTD の名前と実際に挿入する部分との対応付け)
(setq sgml-custom-dtd
      '(("HTML 4.01 Strict" 
         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"
\"http://www.w3.org/TR/html4/strict.dtd\">")
        ("HTML 4.01 Transitional" 
         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
\"http://www.w3.org/TR/html4/loose.dtd\">")
        ("HTML 4.01 Frameset" 
         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"
\"http://www.w3.org/TR/html4/frameset.dtd\">")
        ("XHTML 1.0 Strict" 
         "<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n")
        ("XHTML 1.0 Transitional" 
         "<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n")
        ("XHTML 1.0 Frameset" 
         "<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n")
        ("XHTML 1.1"
         "<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n")
        ))

;; インデントの設定など
(add-hook 'sgml-mode-hook
          (lambda ()
            (setq tab-width                             2
                  sgml-indent-step                      2
                  sgml-indent-data                      t
                  indent-tabs-mode                      nil
                  sgml-xml-p                            t
                  sgml-always-quote-attributes          t
                  sgml-system-identifiers-are-preferred t
                  sgml-auto-activate-dtd                t
                  sgml-recompile-out-of-date-cdtd       t
                  sgml-auto-insert-required-elements    t
                  sgml-insert-missing-element-comment   t
                  sgml-balanced-tag-edit                t
                  sgml-default-doctype-name             "XHTML 1.1"
                  sgml-ecat-files                       nil
                  sgml-general-insert-case              'lower
                  sgml-entity-insert-case               'lower
                  sgml-normalize-trims                  t
                  sgml-insert-defaulted-attributes      nil
                  sgml-live-element-indicator           t
                  sgml-active-dtd-indicator             t
                  sgml-minimize-attributes              nil
                  sgml-omittag                          nil
                  sgml-omittag-transparent              nil
                  sgml-shorttag                         nil
                  sgml-tag-region-if-active             t
                  sgml-xml-validate-command             "xmllint --noout --valid %s %s"
                  )))

;; font-lock
(font-lock-mode 1)
(setq font-lock-support-mode   'jit-lock-mode
      jit-lock-stealth-verbose nil
      font-lock-verbose nil)

;; My original font-lock-keywords
(add-hook 'sgml-mode-hook
          '(lambda ()
             (make-local-variable 'font-lock-defaults)
             (setq sgml-set-face nil
                   font-lock-defaults '(xml-font-lock-keywords-2 nil))
             (turn-on-font-lock)
             ))

(defvar xml-font-lock-keywords-1
  (list
   ;; タグ開始区切子 & タグ終了区切子
   '("<\\|>" 0 font-lock-keyword-face t)
   ;; スラッシュ
   '("\\(/\\)>" 1 font-lock-keyword-face t)
   '("<\\(/\\)" 1 font-lock-keyword-face t)
   ;; 要素名
   '("\\(</?\\)\\([a-zA-Z]+[a-zA-Z0-9-_:]*\\)" 2  font-lock-builtin-face t)
   ;; コメント
   '("\\(<!--\\([^-]\\|-[^-]\\|--[^>]\\)*-->\\)" 1 font-lock-comment-face t)
   ;; 命令処理
   '("\\(<\\?[a-zA-Z]*\\>[^<>]*\\(<[^>]*>[^<>]*\\)*\\?>\\)" 1 font-lock-type-face t)
   ;; DOCTYPE, ENTITY, ATTLIST, NOTATION等々 マーク宣言
   '("\\(<![a-zA-Z]+\\>[^<>]*\\(<[^>]*>[^<>]*\\)*>\\)" 1 font-lock-constant-face t)
   ;; °
   '("\\<\\([a-zA-Z]+[a-zA-Z-_:]*\\)=" 1 font-lock-variable-name-face t)
   ;; 属性値
   '("=?\\(\"[^\"]*\"\\|'[^\']*'\\)" 1 font-lock-string-face t)
   ;; 数値文字参照, 文字実体参照, パラメータ実体参照
   '("\\(&#[0-9]+;\\|&[a-zA-Z]+;\\|%[^'\";]+;\\)" 1 font-lock-reference-face t)
   ;; CDATA 等々 マーク区間 (マーク指定区域)
   '("\\(<!\\[[^\\[]+\\[[^]]+]]>\\)" 1 font-lock-warning-face t)
   ))

(defvar xml-font-lock-keywords-2
  (append
   xml-font-lock-keywords-1
   (list
    ;; SSI
    `(,(concat "\\(<!--#\\(fsize\\|flastmod\\|printenv\\|"
               "include\\|echo\\|config\\|exec\\|set\\|"
               "if\\|elif\\|else\\|endif\\)\\>[ \t\n]+"
               "\\([^-]\\|-[^-]\\|--[^>]\\)*-->\\)")
      1 'bold t)
    ;; php
    '("\\(<\\?\\(php\\|=\\)[^?>]+\\?>\\)" 1 font-lock-function-name-face t)
    ;; eRuby, JSP, ASP
    '("\\(<%\\(=\\)?\\>[^%>]+%>\\)" 1 font-lock-function-name-face t)
    )))

追記

コメントでご指摘を頂いたので、内容を一部修正しました。
20080302 以前にこの記事の手順にそって PSGML を導入されている場合は、.emacs の記述を上記のものに置き換え、catalog の内容を以下のように修正することをお勧めします。

CATALOG "html4.01/HTML4.cat"
CATALOG "xhtml1.0/xhtml.soc"
CATALOG "xhtml1.1/xhtml11.cat"
修正箇所
  • catalog の内容を修正
  • .emacs に追加する記述を修正
    • Translational を Transitional に置換
  • PSGMLを導入するのタイトルが「no title」になっていたのを修正

参考