読者です 読者をやめる 読者になる 読者になる

align-rules-listを用いたTeXの表の整列

emacs LaTeX

先日,以下の記事を見つけた.

この記事では,以下のコマンドでTeXの表(tabular環境の中に記述してるアレ)を整列できることが紹介されている.

M-x align-regexp RET &

M-x align-regexpを実行し,カラムを表す文字列を指定しているというわけだ.
さらに記事では,Emacsの設定ファイルに

(require 'align)
(add-to-list 'align-rules-list
             '(yatex-table
               (regexp . "\\(\\s-*\\)&")
               (modes  . '(yatex-mode))))

と書くことで,リージョンを指定してM-x alignとするだけで整列可能ということまで紹介してあった.
上記のmodesのところを各人のlatex編集時のmajor-modeにすればよい.

ただ,この方法だと個人的に不満を感じるところがあった.
例えば以下の表を整列するとしよう.

 \begin{table}[htbp]
  \centering
  \begin{tabular}{|c||c|c|}\hline
   hoge & 1 & 100000 \\ \hline\hline
   hogehoge & 10000 & 1 \\ \hline
   fuga & 100 & 1000 \\ \hline
  \end{tabular}
 \end{table}

この表を整列すると,

 \begin{table}[htbp]
  \centering
  \begin{tabular}{|c||c|c|}\hline
   hoge     & 1     & 100000 \\ \hline\hline
   hogehoge & 10000 & 1 \\ \hline
   fuga     & 100   & 1000 \\ \hline
  \end{tabular}
 \end{table}

のように,行末の'\\ \hline'まで整列してくれない.
せっかく自動で整列させるならこいつらまで整列させたいわけで,以下の設定を書いた.

  (lazyload (align align-regexp align-newline-and-indent) "align" nil
    (append-to-list align-rules-list
      (list '(yatex-tabular
             (regexp . "\\(\\s-*\\)&")
             (modes . '(yatex-mode))
             (repeat . t))
            '(yatex-tabular2
              (regexp . "\\(\\s-+\\)\\\\\\\\")
              (modes . '(yatex-mode))))))

上記の表に対する実行結果は以下のようになる.

 \begin{table}[htbp]
  \centering
  \begin{tabular}{|c||c|c|}\hline
   hoge     & 1     & 100000 \\ \hline\hline
   hogehoge & 10000 & 1      \\ \hline
   fuga     & 100   & 1000   \\ \hline
  \end{tabular}
 \end{table}

lazyloadやappend-to-listは以下で定義されるマクロである.

(defmacro lazyload (func lib docstring &rest body)
  "遅延ロード.funcにオートロードさせたい関数を並べる.
例:\(lazyload \(func1 func2\) \"hogehoge\"\)"
  (declare (indent 3))
  `(when (locate-library ,lib)
     ,@(mapcar (lambda (f) `(autoload ',f ,lib ,docstring t)) func)
     (eval-after-load ,lib
       `(funcall #',(lambda () ,@body)))))
(defmacro append-to-list (to list)
  " list に append する際に要素を複数指定"
  (declare (indent 1))
  `(setq ,to (append ,list ,to)))

以上.