org-modeのツリーでスライドショー

Table of Contents

1 はじめに

この記事は Emacs Advent Calender 2011 の3日目です.前の記事は,@peccu さんの MewでiCloudのメールを読み書き です.後ろの記事は,@HKe7 さんの パスをまとめよう (Emacs Advent Calendar jp: 2011) です.

@takaxpは,今年3月から自分で elisp を書き始めた elisp 初心者です.Emacs歴12年,Org-mode歴3年です.Emacs Advent Calender には初参戦で,今回は拙作の org-tree-slide.el を紹介します.

2 これは何?

org-modeの各ツリーを「一枚のスライド」として扱うための elisp です.org-mode ユーザ向けです.

こんな人におすすめです.

  • Emacs でプレゼンテーションしたい!((org-modeでプレゼン内容を組み立てている時に「この話をまた Keynote や Powerpoint でスライドにするの面倒だ」と思ったのが作り始めるきっかけ.))
  • 長いorgファイル((org-modeで編集されたバッファ))の内容を素早く確認したい
  • プレゼンしながら編集もしたい(協調編集((ブレインストーミングをする時に便利です.スライド一枚がホワイトボードに対応すると考えられます.参加者の意見をスライド状のorgファイルにまとめいき,後で適当な形式で出力できます.orgファイルをそのまま配ってもいいし,HTML化,PDF化してもOK.なんなら数式入りのTex経由でPDF化もできます.素晴らしきorg-mode!)))
  • narrowing を多用するけど,次のツリーに移るのが面倒

2.1 位置づけ

org-mode には,バッファの内容を表示するために3つの状態が用意されています.

  • SHOW ALL(すべての記述内容を表示)
  • OVERVIEW(トップレベルの見出しを表示)
  • CONTENT(特定レベル以上の見出しを表示)

これらの状態は,S-<TAB>を押すことで,循環させながら切り替えられます.数千行の長いファイルも,不要(詳細)な部分を素早く隠せるので,全体を簡単に見通すことができます.

org-tree-slide は,ここに「第4の状態を追加する」イメージです.

  • org-tree-slide(注目するツリーと包含するツリーの見出しだけを表示)

表示の方法を変えるだけなので,org-tree-slide を有効にしても,org-mode の機能をそのまま使えます.また,バッファのアウトラインだけならば CONTENT((M-x org-content)) で確認できますが,ツリーの内容も確認したい場合には,スライド状に表示してくれる org-tree-slide が便利です.

第四の状態

2.2 デモ

百聞は一見に如かず,ということで,実際に使っている動画をご覧ください.音は入っておりません.

demo

3 インストール

3.1 org-tree-slide.el の入手

MEPLAから配信しているので, M-x list-packages で表示されるリストから選んでインストールできます.
また org-tree-slide.el を Github から入手するか,次を評価してください.

(auto-install-from-url "https://raw.github.com/takaxp/org-tree-slide/master/org-tree-slide.el")

入手した org-tree-slide.el を load-path に保存して,.emacs に次を追加します.

(require 'org-tree-slide)

これでインストール完了です.

3.2 動作環境

以下の環境での動作を確認しています.不具合がありましたらぜひご連絡ください.

OS Emacs Org mode
MacOSX (Lion) 24.0.91 7.7
MacOSX (Lion) 23.3.50 7.7
MacOSX (Lion) 23.3.50 6.33x
openSUSE (12.1) 23.3.1 6.33x
Windows (7) 23.3.1 6.33x

それほど複雑なことはしていないので,多くの環境で動作すると思います((6.33xだとタイマーがうまく動かないようです.)).

3.3 シンプルに使う

すべてのエフェクトをオフにして,org-tree-slide をシンプルに使うためには,M-x org-tree-slide-simple-profile とします.この設定を常に有効にしておくには,

(when (require 'org-tree-slide nil t)
  (org-tree-slide-simple-profile))

としておけばOKです.

マイナーモードに対応したので,次のようにキーバインドを割り当てれば,シングルキーの連打でスライドショーの開始と終了を切り替えられます.また,S-<f8> のトグルで,TODOステータスのツリーだけを追えるようになります. org-tree-slide-modeline-display'outside'lighter に設定すれば,モードラインで現在のスライド番号もしくは残りのTODOの数を確認できます.

(global-set-key (kbd "<f8>") 'org-tree-slide-mode)
(global-set-key (kbd "S-<f8>") 'org-tree-slide-skip-done-toggle)

3.4 スライド番号の表示例

この例は,TODO追跡用のプロファイルを適用した場合です.以下のコマンドでプロファイルを適用できます.

M-x org-tree-slide-narrowing-control-profile

<f8>org-tree-slide-mode をトグルすると,ツリーがスライド化してモードラインにスライド番号が表示されます.次の例では,有効なツリー((org-tree-slide-skip-outline-levelを設定しているとカウントしないツリーもあります))は418あり,11番目を表示していることを意味しています.

スライド番号/有効なツリーの総数

S-<f8>org-tree-slide-skip-done-toggle をトグルすると,スライド番号が変化するのがわかります.TODOステータス((カスタマイズした名称も拾います))になっているツリーが259あり,9番目を表示していることになります.この状態で C-<right> すれば,TODOなツリーだけ連続表示できます.

スライド番号/残されたTODOの数

3.5 使ってみる

orgファイルを開いた状態で,M-x org-tree-slide-mode としてマイナーモードを有効にします.スライドショーが自動的に始まります.モードラインにスライド番号,もしくは「TSlide」と表示されることを確認してください.

スライドショーが始まったら, C-<right> でスライドを進めて, C-<left> でスライドを戻します.That's simple!

スライドショーの途中でツリーを一覧表示したくなったら,M-x org-tree-slide-content もしくは C-x s c を押します.orgファイルの表示状態が CONTENT になるので,表示したいツリーにカーソル移動させ, C-<right> でスライドショーを再開します((CONTENT の状態でも,TABでツリーを開いてファイルを編集できます.)).

スライドショーを終了するには,M-x org-tree-slide-mode をもう一度押してマイナーモードを無効にします.モードラインの表示からスライド番号,もしくは「TSlide」が消えます.スライドショーが終了すると, C-<right> / C-<left> を押してもツリーを移動しません.

TODOステータスのツリーだけをスライドショーしたい場合は, org-tree-slide-skip-done-toggle で切り替えられます.

関数名 キーバインド アクション
org-tree-slide-mode なし(<f8>などの割り当てを推奨) 開始/終了
org-tree-slide-skip-done-toggle なし(S-<f8>などの割り当てを推奨) TODOなツリーだけを移動
org-tree-slide-content C-x s c ツリーの一覧表示
org-tree-slide-move-next-tree C-S-. 次のツリーに移動
org-tree-slide-move-previous-tree C-S-, 前のツリーに移動
org-tree-slide-play-with-timer なし タイマーを指定してスライドを開始

マイナーモードに対応したため,org-tree-slide-play( C-x s p )とorg-tree-slide-stop( C-x s s )は M-x org-tree-slide-mode によるトグルになりました.

4 プレゼンテーションに使う

普段使いでは,前述のシンプルモードがいいでしょう.ただ,スライドショーというからには,プレゼンテーションのための機能とエフェクトが欲しいところですね.

いくつか実装してあるので以下に紹介します.なお,M-x org-tree-slide-simple-profile を実行した後では,すべてのオプションが強制的に OFF になっているので気をつけてください.

M-x org-tree-slide-presentation-profile を実行すると,ヘッダ表示とスライドインが有効になります.

機能一覧:

  • スライドヘッダを表示する
  • 特定のレベル以下をスキップする
  • 発表時間をカウントダウンする

エフェクト一覧

  • ツリーをスライドインさせる
  • ツリーの見出しを強調する

4.1 スライドヘッダの表示(デフォルト:ON)

スライドの上部に「タイトル」「日付」「名前」「メールアドレス」を表示します. 将来的には,#+TITLE で指定するファイル名を表示するようにします.調査中φ(. _. )

日付以外の値はorg-modeのヘッダから抽出しようと試みます.日付はスライドを表示する当日のものを利用します.

#+TITLE: スライドのタイトル
#+AUTHOR: 名前
#+EMAIL: hoge@hogehoge.com

このようにorgバッファで記述されていれば((最初の見出しよりも前の部分に書かれている必要があります)),

 [スライドのタイトル]
2011-12-31  名前  hoge@hogehoge.com

という形式でスライドのヘッダを表示します.

なお,名前とメールアドレスを省略すると空白となり,タイトルを省略するとバッファ名が使われます.

4.1.1 制御方法

  • 起動時にヘッダを表示しないようにする
(setq org-tree-slide-header nil)
  • スライドショーの途中でヘッダー表示/非表示を切り替える
M-x org-tree-slide-display-header-toggle

4.2 特定レベル以上のツリーをスキップする(デフォルト:OFF)

@peccu さんからコメントをいただいて追加しました.

ツリーのレベルが高くなると,ツリーをスライドではなく単純なアイテムとして扱いたくなるかもしれません. org-tree-slide-skip-outline-level を設定すれば,該当するツリーをスライド化せずにスキップできます.

実装してから気づきましたが,この機能は, 説明したくないスライドをスキップする ためにも使えますね.もしスキップされるツリーに補足資料などが入っているなら,そのツリーにカーソルに移動して C-<right> すれば,スキップせずにスライドとして表示できます.

4.2.1 制御方法

  • レベル4以上((*が4つの見出し))のツリーはスライド化しない
(setq org-tree-slide-skip-outline-level 4)
  • すべてのツリーをスライド化する(デフォルト)
(setq org-tree-slide-skip-outline-level 0)

4.3 発表時間のカウントダウン(スライド開始時に指定)

モードラインに発表時間の残り時間を表示します.M-x org-tree-slide-play-with-timer で起動します.発表時間を指定するようにプロンプトが出るので.プレゼン時間を指定します.単位は「分」です.スライド開始と共に,自動的に org-tree-slide-mode が有効になります.

この機能は,単純に org-timer-set-timer を実行しているだけです.6.33x では,C-u 無しで起動した後で, C-c C-x ; とすれば,プロンプトがでると思います.が,先ほど確認したらプロンプトは出るけどカウントが始まらない状態でした Orz.今後の課題ということでお許し下さい...

4.4 ツリーをスライドインさせる(デフォルト:ON)

スライドを移動すると,ツリーの内容が中央付近から最上部に移動します.ちょっとした動きが出て,スライドの切り替わりをアピールできます.居眠り対策ではありません.

環境に応じて移動スピードが違うようなので,好みの設定を探してみてください.

4.4.1 制御方法

  • 起動時にヘッダを表示しないようにする
(setq org-tree-slide-slide-in-effect nil)
  • スライドインのスピードを調節する(数値を変えてください)
(setq org-tree-slide-slide-in-waiting 0.02)
  • スライドインの開始位置を調節する(行数を指定)
(setq org-tree-slide-slide-in-brank-lines 10)
  • スライドショーの途中でスライドインエフェクトの有効/無効を切り替える
M-x org-tree-slide-slide-in-effect-toggle

スライドスピードの調節は,行数(10[line])×速度(0.02[s/line])=移動時間(0.2[s])と考えてください.実際の振る舞いとはだいぶ差があるので,あくまで目安です.

4.5 ツリーの見出しを強調する(デフォルト:OFF)

メリハリをつけるために,ツリーの見出しを強調できます.

見出しの強調

もし,文字全体が小さいなと思ったら, C-x C- でフォントサイズを拡大してください.縮小するときは, C-x C-- で,標準サイズに戻すときは, C-x C-0 です.これらは,face-remap.el の機能です.

外部出力解像度が 800×600[画素]の時は,Emacsのウィンドウサイズが横80,縦35程度で十分な表示サイズになります.解像度が高くなると,相対的に文字が小さくなるので,フォントサイズの調節が必須になります.解像度に合わせてフォントサイズを変更する機能を探しています. あるのかな. see moom.el

4.5.1 制御方法

  • 起動時に見出しを強調する
(setq org-tree-slide-heading-emphasis t)
  • スライドショーの途中で有効/無効を切り替える
M-x org-tree-slide-heading-emphasis-toggle
  • 文字サイズを調節する
機能 キーバインド
文字拡大 C-x C-=
文字縮小 C-x C--
標準サイズ C-x C-0

4.6 スライドの開始と終了時に独自の処理を加える(デフォルト:OFF)

org-tree-slide は,スライド開始時にはプロファイルで指定したカスタマイズを適用し,終了時にはそれらを解いてスライド開始前の状況に戻します.特定のバッファを表示するなどのカスタマイズを加える場合に,次のフックが使えます.

  • org-tree-slide-mode-play-hook スライド開始時のフック
  • org-tree-slide-mode-stop-hook スライド終了時のフック

4.6.1 制御方法

  • スライド開始時にウィンドウを分割する
(add-hook 'org-tree-slide-mode-play-hook
          '(lambda () (split-window-below)))
  • スライド終了時にウィンドウの分割を解く
(add-hook 'org-tree-slide-mode-stop-hook
          '(lambda () (delete-window)))

5 その他の設定

5.1 <left>/<right> 以外でスライドを移動する

org-tree-slide の利用頻度が高くなると,標準の移動のキーバインド( C-<left> / C-<right> )を不自由に感じるかもしれません.これは,バッファを編集しているときはカーソル移動が C-f / C-b ですが,編集結果を眺めるときに C-<left> / C-<right> を使うことがあるからです.

そんな習慣がある方は, C-<left> / C-<right> ではないキーを割り当てます.例えば, <f8> で戻り, <f9> で進むように設定します.この設定は,org-tree-slide でスライドショーしている間だけ有効になります.

(define-key org-tree-slide-mode-map (kbd "<f9>")
  'org-tree-slide-move-previous-tree)
(define-key org-tree-slide-mode-map (kbd "<f10>")
  'org-tree-slide-move-next-tree)

私はさらに, <f11>org-tree-slide-content に割り当てています.これにより, <f8> / <f9> / <f10> / <f11> キーで集中管理できます.右手だけで済みます.

もしくは,マウスアクションに割り当ててもいいかもしれません.ただ,クリックする場所が限定的なので,あまり使い勝手はよくないかもしれません.

(define-key org-tree-slide-mode-map (kbd "S-<mouse-1>")
  'org-tree-slide-move-previous-tree)
(define-key org-tree-slide-mode-map (kbd "<mouse-1>")
  'org-tree-slide-move-next-tree)

新しいキーバインドには,Emacs の編集中に使わないキーを割り当てないと,スライドショーしながら編集するときに面倒なことになりますので,ご注意ください((j/kは危険かと)).

5.2 何か重いと感じたら(スライド番号表示方法)

org-tree-slide-narrowing-control-profile のデフォルトの設定では,カーソルが見出し行にあると常にスライド番号を更新します.そのため,一覧表示などで C-n/C-p を押しっぱなしにすると,描画が間に合わない可能性があります(ファイルサイズに依存).そんな時は,スライド番号の表示位置を変えてみてください.

(setq org-tree-slide-modeline-display 'outside)

こうすれば,次のように表示位置が変わり動作が軽くなります.ただし,スライド番号の更新は スライドの表示が更新されるときだけ に限定されます.

outside

また, nil を指定すれば,スライド番号は一切表示されなくなります.

5.3 既知の問題

  • 複数バッファで org-tree-slide-play を開始するとバグる

大問題なので,次の課題として着手します.マイナーモードで回避でしょうか. => マイナーモードに対応したことで回避!

  • session.el 利用にて,スライド表示中に Emacs を再起動すると narrowing したままになる.

解消方法)org-reveal(C-c C-r) を呼ぶ,もしくは,M-x widen で narrowing を解いて編集後,上書き保存する.session.el は保存時の状態を保持するので注意が必要.同じ事は,M-x org-narrow-to-subtree でも発生します.

  • タイマー周りの制御(スライド終了時にクリアがうまくいかない場合がある)
  • 見出しを強調しているとき,ヘッダの表示が影響を受ける場合がある.

5.4 謝辞

ここまでお読みいただき,ありがとうございました m(_ _)m.冒頭でも述べましたが,書いた elisp がまだ数個の素人なので,アドバイス等ございましたらコメントいただければ幸いです.

6 おまけ

6.1 org-mode 翻訳プロジェクト

たくさんの有志の方の積極的なご協力の元,org-mode の英語マニュアルを翻訳しています.このプロジェクトの最大の目的は,本家のマニュアルアップデートを継続的にフォローすることです.

このプロジェクトは,Emacs と org-mode が消えない限り永遠に続けます.私の寿命が尽きても誰かが引き継いでくれるはず :-)

お手伝いくださる方は,Twitter で #org2ja ハッシュタグをつけて叫ぶか,@takaxp にメンションを飛ばすか,翻訳作業用の ML((過去ログは非公開にしてあります)) に参加依頼を投げてください.現在は,初期翻訳がほぼ完了し,これから査読作業に入る段階です.バージョン7.5の PDF と INFO を work directory からダウンロードできます.

このプロジェクトで培ったUTF-8環境下のノウハウは,将来的に本家にフィードバックします.英語を含む多言語の info ファイルが頒布されるようになれば,org-mode の利用者は地球規模で増えるでしょう.

6.2 @orgmode_bot アカウント

org-mode の関数と,対応するキーバインドを毎日@orgmode_botツイートしています.org-mode の機能をまったりと知りたい方や,新しい機能を発見したい方は,ぜひフォローしてください.

ツイートは日本語と英語で行なっています.これも将来的には多言語化するつもりです.

ユニコーンロゴの利用は,Dominik先生のお墨付き:-). Org7.8 のリリースに伴い,公式サイトにリンクが張られました!また,日本語ページのコミッタになったので,読みにくい箇所などありましたらお知らせ下さい m(_ _)m

6.3 おまけのおまけ

Emacs で text-mode を使っている人は,すぐに org-mode を使い始めましょう.

以下を .emacs に貼るだけでOKです.

(push '("\\.txt\\'" . org-mode) auto-mode-alist)

7 付録:関連ツール

7.1 org-info-js を使う

org-info-js は,orgファイルをXHTMLエクスポートした後で,info で使うようなショートカットでコンテンツを閲覧するためのモジュールです.

http://orgmode.org/Changes.html#sec-1 に行くと,どんな感じかわかります.

n で進んで, p で戻ります.この方法は,エクスポートするのが前提なので,リアルタイム編集はできません.

7.2 org の narrowing を使う

<f5> のトグルでナローイングを切り替えるのは,良く知られた設定です.

(define-key org-mode-map (kbd "<f5>") 'org-narrow-to-subtree)

これを使えば,orgファイルの任意のツリーにフォーカスして編集できます.ただし,あるツリーにナローイングしているときに,ワンアクションで次のツリーに移れないのが欠点です.

7.3 org-simple-presentation-mode.el を使う

@r_takaishi さんの作品です.Github から入手できます.きちんとしたマイナーモードです.不可視領域を独自に overlay で構築しているのが特徴です.

7.4 org-tree-slide

今回紹介した elisp です.org-simple-presentation-mode が正統派elispとすると,このツールは,いわば「org-mode プログラミング」の産物です.コア機能の多くが org-mode が提供する関数((org.el,2万行を読む!))を利用しているので,elisp 素人な私でも簡単に作ることができました.機能面では,タイマー機能,ヘッダ表示,スライドエフェクト,ツリーの一覧表示に対応しています.実装途中ですが,オートプレイも可能((スライドインエフェクト付きでスライドショーを開始し, C-x s a を押すと,自動で進める枚数を指定してください.))です.

8 Review

  • マスタカさんのブログでご紹介していただきました m(_ _)m

Emacsでお手軽にプレゼンできるorg-tree-slideはかなり良い感じ!

Author: Takaaki ISHIKAWA

Created: 2020-11-24 Tue 22:55

Validate