Defining filters for individual files(個別のファイルにフィルタを定義する)に書かれている例を試してみました。
#+BEGIN_SRC emacs-lisp :exports results :results none (defun tmp-f-timestamp (s backend info) (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)) (defun tmp-f-strike-through (s backend info) "") #+END_SRC time stamp [2020-12-19 Sat 14:06] abc +def+ ghi
この例では二つのフィルタ関数を作成しています。一つはタイムスタンプのブラケット([]や<>)を消去する tmp-f-timestamp
関数、もう一つは取り消し線のテキストをまるまる消去する tmp-f-strike-through
関数です。一般的にフィルタ関数は、引数sの文字列(バックエンドによって変換済みの文字列)を再加工して返すことになっています。
この二つの関数をソースブロック( #+BEGIN_SRC emacs-lisp
~ #+END_SRC
)内に書くことでエクスポートするたびに評価させ関数を定義しています。ヘッダーオプション :exports results :results: none
の指定によって、エクスポートするたびに毎回評価させつつ実際には何も(リスティングや結果等を)エクスポートしないようにしています。
さらに #+BIND:
でそれらの関数を変数 org-export-filter-timestamp-functions
と org-export-filter-strike-through-functions
に設定しています。
これであとはエクスポートすれば time stamp [2020-12-19 Sat 14:06]
の [
と ]
が削除され、 abc +def+ ghi
の部分が abc ghi
になるはず……
あれれ、HTMLでエクスポートしてみましたがフィルタが適用されていません。
ソースブロック(#+BEGIN_SRC
~ #+END_SRC
)の部分はエクスポート時にyes/noの確認がありyesを選択しました。 tmp-f-timestamp
や tmp-f-strike-through
はちゃんとEmacs内に登録されているので評価されていることは間違いありません(エクスポートが終わっても tmp-
で始まる関数が残っているのは不愉快ではありますが)。
変数 org-export-filter-timestamp-functions
や org-export-filter-strike-through-functions
は nil
。となるとBIND( #+BIND:
)の部分が機能していない? しかし調べたところ #+BIND:
はエクスポートの間だけバッファローカル変数になると書かれています。なら今nilでも当然ですが……ははぁ、これはセキュリティがらみですね。BIND部分を無条件で評価してしまうと他人から貰ったorg文書をエクスポートしたときにイタズラされる可能性があります。
探してみると org-export-allow-bind-keywords
という変数があって nil
になっていました。試しにバッファ内で M-: (setq-local org-export-allow-bind-keywords t)
してみたらちゃんとフィルタが機能しました。
うーんしかし org-export-allow-bind-keywords
を常に t
にするのは少々不安ですし、どうするべきなんでしょう。
試しに (setq-local org-export-allow-bind-keywords t)
をソースブロックの中に入れてみました。
#+BEGIN_SRC emacs-lisp :exports results :results none ;;; 追加!!! (setq-local org-export-allow-bind-keywords t) (defun tmp-f-timestamp (s backend info) (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)) (defun tmp-f-strike-through (s backend info) "") #+END_SRC time stamp [2020-12-19 Sat 14:06] abc +def+ ghi
ファイルを開き直してエクスポート(ソースブロックの評価はyes/no確認あり)してみるとちゃんとフィルタが機能してブラケットや取り消し線部分が消去されていました。つまりBINDとソースブロックを評価するセキュリティリスクがソースブロックに一本化されたわけです。どうなんだろうこれ。
最初からBINDなんか使わなければいいんじゃないでしょうか。
#+BEGIN_SRC emacs-lisp :exports results :results none (setq-local org-export-filter-timestamp-functions '(tmp-f-timestamp)) (setq-local org-export-filter-strike-through-functions '(tmp-f-strike-through)) (defun tmp-f-timestamp (s backend info) (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)) (defun tmp-f-strike-through (s backend info) "") #+END_SRC time stamp [2020-12-19 Sat 14:06] abc +def+ ghi
うん、これでもちゃんとフィルタされます。
逆にBINDだけにするなら次のようにすれば良いでしょう。
[2020-12-19 Sat 14:06] abc +def+ ghitime stamp
この場合 org-export-allow-bind-keywords
変数が t
ならフィルタされ nil
ならされません。 org-confirm-babel-evaluate
変数のようにBINDを評価するときにyes/no確認が出せれば良いのかもしれないが、そういう設定は見当たりません。まぁ、そこまでするならソースブロックで良いでしょう。
ちなみにソースブロックを使う方法で tmp-*
関数が残ってしまうのが気に入らなければ次のようにlambdaにしてしまえば良いのでしょうきっと。
#+BEGIN_SRC emacs-lisp :exports results :results none (setq-local org-export-filter-timestamp-functions (list (lambda (s backend info) (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)))) (setq-local org-export-filter-strike-through-functions (list (lambda (s backend info) ""))) #+END_SRC time stamp [2020-12-19 Sat 14:06] abc +def+ ghi
評価するかいちいち確認するのが嫌ならば(かつ org-confirm-babel-evaluate
を nil
にするのが嫌ならば)、あらかじめ何らかの条件で自動的にフィルタが設定されるようにどこかに仕込んでおくことになりそうです。