asciidoc用メジャーモードを作る

AsciiDocはマークアップのため記法(Nortation)の1つだ。AsciiDocをEmacsで表示したり編集する場合様々な方法がある。

adoc-mode

AsciiDocのために書かれたメジャーモードに adoc-mode がある。adoc-modeはEmacs上でAsciiDoc形式のファイルを扱うためのメジャーモードです。しかしデフォルトの設定では、コメントやメタ情報の表示サイズがとても小さくなってしまう。これでは編集時に読めないので、ちょうどよい値に設定し直しなおす必要がある。

(use-package adoc-mode :ensure t :defer t
  :config
  (set-face-attribute markup-comment-face nil :width 'normal :height 1)
  (set-face-attribute markup-meta-face nil :width 'normal :height 1 :foreground "red")
  )
adoc-modeの設定の例

僕の場合、 adoc-mode を自分の納得がいくような設定ができなかったため、自分でメジャーモードを実装していく事にした。これについては後述する。

ewwを用いてAsciiDocを表示する

AsciiDocは、HTMLとして生成できる。そのためEmacsの組み込みブラウザであるewwで表示できる。そのためのユーティリティを実装した。asciidocコマンドを呼び出すため、事前にインストールしておく必要がある。

(defun asciidoc-view ()
  (interactive)
  (shell-command (format "asciidoc -o /tmp/foo.html %s" (buffer-file-name)))
  (eww-open-file "/tmp/foo.html"))

実装してみたけれど、実際にはあまり使わなかった。

自分でメジャーモードを書く

adoc-mode は、見出しの階層やマークアップの状態によって文字のサイズが大きく変わる。こういった表示が好みの人もいるかもしれないが、僕の好みではない。そこでメジャーモードを自分で少しずつ実装していく事にした。

asciidoc.el

;;; asciidoc --- AsciiDoc utility. -*- lexical-binding: t -*-

;; Copyright (C) 2024 TakesxiSximada

;; Author: TakesxiSximada <[email protected]>
;; Maintainer: TakesxiSximada <[email protected]>
;; Version: 1
;; Package-Version: 20240324.0000
;; Package-Requires: ((emacs "29.1"))
;; Date: 2024-03-24

;; This file is not part of GNU Emacs.

;;; License:

;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU Affero General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; Affero General Public License for more details.

;; You should have received a copy of the GNU Affero General Public
;; License along with this program.  If not, see
;; <https://www.gnu.org/licenses/>.

;;; Code:

(defgroup asciidoc nil
  "AciiDoc for Emacs"
  :prefix "asciidoc-"
  :group 'tools)


;;;###autoload
(define-derived-mode asciidoc-mode fundamental-mode "AsciiDoc"
  "AsciiDoc Major Mode"
  (kill-all-local-variables)

  (setq major-mode 'asciidoc-mode
	mode-name "AsciiDoc")

  (setq-local comment-start "//"
	      comment-start-skip "//[ \t]*")

  (progn
    (modify-syntax-entry ?/ ". 12" asciidoc-mode-syntax-table)
    (modify-syntax-entry ?\n ">" asciidoc-mode-syntax-table)
    (set-syntax-table asciidoc-mode-syntax-table)
    (set-face-foreground 'font-lock-comment-face "gray")
    (set-face-background 'font-lock-comment-face "ansi-color-inverse")

    (setq font-lock-keywords nil)
    (font-lock-add-keywords
     nil
     '(("^=\\{1\\}\s.+" . 'outline-1)
       ("^=\\{2\\}\s.+" . 'outline-2)
       ("^=\\{3\\}\s.+" . 'outline-3)
       ("^=\\{4\\}\s.+" . 'outline-4)
       ("^=\\{5\\}\s.+" . 'outline-5)
       ("^=\\{6\\}\s.+" . 'outline-6)
       ))

    (font-lock-mode t)
    (font-lock-fontify-buffer))
  (run-mode-hooks))

(provide 'asciidoc)
;; asciidoc.el ends here