[ホーム]-> [emacs]-> [活用法]-> [outline]

Outline Mode

1. Outline Mode って何?

Emacs に元々ついている機能で、文字通り文章をアウトライン構造を把握しながら編集していくことができる mode です。 具体的には、特定のレベル以下の部分や見出し以外の部分、今書いている部分以外の本文を隠したりすることができます。 outline-mode は major-mode で、outline-minor-mode はその minor-mode 版です。 (従って YaTeXyahtml などの他のモードと組み合わせて使うことができます。)

2. Outline Mode の使い方

まず感じを掴んでもらうために Outline Mode で説明します。新規にファイル を開いて、次のようなテキストを書いてみましょう。

     * 第1章
     ** 1.1 はじめに
     何から始めようかな。    
     ** 1.2 最後に
     いきなり終わりかよ。

そして、おもむろに M-x oultine-mode として outline-mode を起動します。

Outline Mode では、ヘッドライン行と本体行の二種類の行があります。ここ で * や ** で始まる行は、ヘッドライン行、その他の行は本体となります。 ヘッドライン行では * の数が多いほど、レベルは低くなっていきます。つま り、より * の数が少ないヘッドラインの枝になっているわけですね。

さて、一行目の先頭にカーソルを置いて、C-c C-d (hide-subtree) とします。すると、画面には

     * 第1章...    

のように表示されるはずです。これは「第1章」の枝にあたる部分を全て隠す コマンドです。このとき実際のバッファの内容は変わったわけではありません。 ただ、表示が変わっただけです。C-c C-a (show-all) とタイプすれば、元のテキストが 全て表示された状態に戻るのが確認できます。

     * 第1章
     ** 1.1 はじめに
     何から始めようかな。    
     ** 1.2 最後に
     いきなり終わりかよ。

今度は、二行目の先頭にカーソルを置いて、C-c C-t (hide-other) とタイプしてみましょう。すると、

     * 第1章
     ** 1.1 はじめに
     何から始めようかな。    
     ** 1.2 最後に...

のように表示されたはずです。これは、現在編集している部分以外の本体部分 を全て隠すコマンドです。文章の全体構造を見ながら編集を行うときに重宝し ます。

また、1.1 にどんなことを書いたっけと思ったなら、* 1.1 の行に移り、 C-c C-e (show-body) とすれば中身を見れます。もう 一度隠すときは C-c C-c (hide-body) です。 ... はここにテキストがたたみ込まれていることを示 しています。実際のテキストがバッファから消えてしまったわけではないので、 cut ;& paste するときとかに戸惑わないようにしましょう。

このような表示は行末コードを LF を CR に変更することで実現されています。 まず普通は起こらないと思いますが、万が一こうなったままテキストが保存さ れてしまった場合も、パニックに陥いらずに、黙ってM-% C-q  RTN  RTN  C-q  C-j  RTNとして復帰 コードを改行コードに置換すれば、元のテキストが復元できます。

他にもいろいろと便利なコマンドが用意されていますが、もしメニューバーが 表示されていれば、Show とか Hide とかいうメニューが表示されているはず なので、試してみると良いでしょう。また、Info の Outline Mode の項にも 詳しい説明があります。

ここで、「私は * でヘッドラインを記述するのは好きじゃないなあ」という 人もいるでしょう。これは、outline-regexp という変数でカスタマイズすることができます。カスタマイズの仕方は上の Info にも説明されていますが、次の Outline Minor Mode のところで、具体 的な例を説明したいと思います。

3. Outline Minor Mode の使い方

さて、Outline Mode は確かに便利です。でもこれだと、他のモード (例えば YaTeX など) と併用することはできません。そこで Outline Minor Mode の出 番です。ここでは私の個人的な好みで YaTeX Mode (LaTeX を編集するための モード)で説明することにしましょう。

まず、YaTeX Mode で、LaTeX で書かれたファイルを開きます。そして、おも むろに M-x outline-minor-mode としましょう。 すると、モードラインには、

 [--]E.:-----Emacs: test.tex       (やてふ Fill Outl)--L1--Top------- 

などのように表示されるはずです。もちろん、環境によってちょっとした違い はあるでしょうが、Outl という文字があれば、ちゃんと Outline Minor mode が起動されています。一々このようなコマンドをタイプするのが面倒であれば、 ファイルの最後に

     %%% Local Variables: ***
     %%% mode:outline-minor ***    
     %%% End: ***

などと書いておけばよいでしょう。次からは自動的に Outline Minor Mode が 起動してくれます。また、yatex-mode では常に outline-minor を起動したい 場合は、.emacs に

(add-hook 'yatex-mode-hook
          '(lambda () (outline-minor-mode t)))

とでも書いておけば良いでしょう。

しかし、勿論これだけでは何の役にも立ちません。LaTeX ファイルではヘッド ラインを * で記述するようにはなっていないので当たり前です。

さて、実際のテキストが次のようだったとしましょう。

     \documentclass{jarticle}
     \usepackage{amsmath,amssymb,amsthm,amscd}    
     \begin{document}
      \section{}
       \subsection{はじめに}
     何から始めようかな。
       \subsection{最後に}
     いきなり終わりかよ。
     \end{document}

LaTeX を知らない人のために説明しておくと \section{} とか \subsection{} というのがヘッドラインになっています。そこ で、Emacs にこれらをヘッドラインだと認識させましょう。前節で説明したよ うに、outline-regexp という変数を書き換えます。この変数、 初めからは局所的な変数になってないみたいで、普通に書き換えると、 global に変わっちゃいます。これは、ファイルに直接 Local variables とし て書込むことを期待してのことかもしれません。それには、上でやったのと同 様にファイルの最後に

     %%% Local Variables: ***
     %%% mode:outline-minor ***
     %%% outline-regexp:"[ \t]*\\\\\\(documentstyle\\|documentclass\\|chapter\\|section\\|subsection\\|subsubsection\\)\\*?[ \t]*[[{]"
     %%% End: ***

のように書けばよいです。しかし、大抵は YaTeX mode では、常に同じ設定を 使いたいのが普通でしょう。この場合は .emacs に次のように書くことになります。

(make-variable-buffer-local 'outline-regexp)
(add-hook
 'yatex-mode-hook
 (function
  (lambda ()
    (setq outline-regexp
          (concat "[ \t]*\\\\\\(documentstyle\\|documentclass\\|"
                  "chapter\\|section\\|subsection\\|subsubsection\\)"
                  "\\*?[ \t]*[[{]")))))

そしてこれらS式の直後にカーソルを持っていって、 C-x C-e とタイプしてこの式を評価し、もう一度 先程の LaTeX ファイルを開き直してみます。これで、 \section などのヘッドラインが認識できてるはずです。試しに、 「最後に」と書かれた行にカーソルを持っていって C-c C-o C-e とタイプしてみましょう。(最近の Emacs だと C-c @ C-e かも。私は C-c @ というプレフィクスは押しにくくて嫌いな ので、.emacs

(setq outline-minor-mode-prefix "\C-c\C-o")

と書いて変更していますが。) すると、画面には

     \documentclass{a4paper,10pt]{jarticle}...    
      \section{}
       \subsection{はじめに}
     何から始めようかな。
       \subsection{最後に}...

と表示されるはずです。しかしこれでもまだ不都合があります。Emacs はヘッ ドラインの親子関係を outline-regexp に一致した長 さで判断しています。(短い程、上位と認識する。) これでは \documentstyle\section よりも下になってしまいます。

この問題は、outline-level という関数を変 更することで可能です。Outline (Minor) Mode では一旦 outline-level という変数を定義して (funcall outline-level) でこの関数を呼出 しているので、次のようにすればバッファローカルに変更することができます。 まず、.emacs

(make-variable-buffer-local 'outline-level)
(setq-default outline-level 'outline-level)
(defun latex-outline-level ()
  (save-excursion
    (looking-at outline-regexp)
    (let ((title (buffer-substring (match-beginning 1) (match-end 1))))
      (cond ((equal (substring title 0 4) "docu") 15)
            ((equal (substring title 0 4) "chap") 0)
            ((equal (substring title 0 4) "appe") 0)
            (t (length title))))))

みたいなのを追加します。これは、outline-regexp を見つけてその level に対応する数を返す関数です。(返す数が大きい程 level は低くなる。) そして、先程の yatex-mode-hook のところを

(add-hook
 'yatex-mode-hook
 (function
  (lambda ()
    (progn
      (setq outline-level 'latex-outline-level)
      (setq outline-regexp
            (concat "[ \t]*\\\\\\(documentstyle\\|documentclass\\|"
                    "chapter\\|section\\|subsection\\|subsubsection\\)"
                    "\\*?[ \t]*[[{]")
     )))))

のように変更して、変数 outline-level を書き換えるようにして おきます。これで、ヘッドラインの上下関係も正しく認識されるようになった はずです。

YaTeX 以外でも上のS式を適当に書き換えれば同じことが可能です。同じく TeX を編集するモードである AUC-TeX は、このような仕組を自前で持ってい るようです。


[ホーム]-> [emacs]-> [活用法]-> [outline]