日本語文を含む org ファイルを jsarticle クラスの LaTeX にエクスポートして PDF に変換する方法

(2010-11-27 記事修正: org.el, org-latex.el の直接修正から .emacs での変数定義に変更)

普段 GTD ツールとして使っている Emacs org-mode は、アウトラインプロセッサとしても便利だけど、いろいろな形式にエクスポートできて、org ファイルを基点にしていろいろなデータを生成できるところもポイントが高い。一番よく使う機能は、 HTML でエクスポート→ web ブラウザで全文コピー→ Lotus Notes へ貼り込み、というもの。こうすると Notes 文書に RTF として貼り込まれるので、見出し・箇条書きを維持したまま他の人と情報共有できる。

今日の本題は HTML ではなく LaTeX へのエクスポートについて。

LaTeX へのエクスポート機能は以前から実装されていたし使ったこともあったけど、今日いろいろ試していて、日本語文を含む org ファイルをエクスポートするときは、ひと工夫するとかなり意図通りに出力できることが判ったので、記録として残すべく、ここに書いておきます。前提として .emacs ファイルに

(require 'org)

という必須の指定に加えて、更に

(require 'org-latex)

と記述されていることが必要です。

問題の確認

  • 問題: タイプセットに使われるコマンドが pdflatex なので、日本語スタイルファイルを使えない
  • 解決のための手段: org mode が内部で呼び出しているタイプセットコマンドを pdflatex から pdfplatex.bat に切り替える。ついでにクラスファイルとして jsarticle を使えるようにする。

手順 (1) タイプセットコマンド指定を変更

org mode の LaTeX に関する関数は主に ${org}/lisp/org-latex.el (ただし ${org} は org mode のインストールディレクトリ、以下同様)で定義されている。タイプセットコマンドもここで定義されており、 org-latex-to-pdf-process という変数を変更すればよい。.emacs に以下のような記述を追加する。

(setq org-latex-to-pdf-process 
      '("pdfplatex.bat %f"
        "pdfplatex.bat %f"
        "pdflatex %f")
)

手順 (2) jsarticle クラスを利用可能にする

同じく org-latex.el の中に

(defcustom org-export-latex-classes
  '(("article"
 "\\documentclass[11pt]{article}"
 ("\\section{%s}" . "\\section*{%s}")
 ("\\subsection{%s}" . "\\subsection*{%s}")
 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
 ("\\paragraph{%s}" . "\\paragraph*{%s}")
 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
  ("report"
 "\\documentclass[11pt]{report}"

という記述があるので、これを参考にして .emacs に以下のような記述を追加する。

(setq org-export-latex-classes 
      (append org-export-latex-classes
              '(
                ("jsarticle"
                 "\\documentclass{jsarticle}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}")
                 )
                )
      )
)

手順 (3) タイプセットコマンド(バッチファイル)を修正(pdfplatex.bat)

これだけでは終わらない。次に pdfplatex を書き換える。角藤版 TeX では ${tex}/bin/ (ただし ${tex} は TeX のインストールディレクトリ)に保存されているので、この中身を以下のように書き換える。

 @echo off
 platex -synctex=1 -kanji=utf8 %~d1%~p1%~n1
 dvipdfmx %~d1%~p1%~n1

こうしないと拡張子の関係でうまく pdfplatex.bat が動かない。

手順 (4) パッケージオプションの修正(org.el)

最後に ${org}/lisp/org.el で定義されている LaTeX 用パッケージ指定を修正する。なんとなく org-latex.el があるんだから LaTeX 関係の記述は全部そこにあるんじゃないかと錯覚してしまうけれど、実は org.el にも関連する記述がある。

   (defcustom org-export-latex-default-packages-alist
  '(("AUTO" "inputenc"  t)
    ("T1"   "fontenc"   t)
    (""     "fixltx2e"  nil)
    (""     "graphicx"  t)
    (""     "longtable" nil)
    (""     "float"     nil)
    (""     "wrapfig"   nil)
    (""     "soul"      t)
    (""     "textcomp"  t)
    (""     "marvosym"  t)
    (""     "wasysym"   t)
    (""     "latexsym"  t)
    (""     "amssymb"   t)
    (""     "hyperref"  nil)

hyperref パッケージにオプションを指定するために、以下のような指定を .emacs に追加する。 (スマートじゃないけど、elisp で「文字列検索して特定の値がリストに含まれている要素だけ置き換える」コードが書けない…)

(setq org-export-latex-default-packages-alist
  '(("AUTO" "inputenc"  t)
    ("T1"   "fontenc"   t)
    (""     "fixltx2e"  nil)
    (""     "graphicx"  t)
    (""     "longtable" nil)
    (""     "float"     nil)
    (""     "wrapfig"   nil)
    (""     "soul"      t)
    (""     "textcomp"  t)
    (""     "marvosym"  t)
    (""     "wasysym"   t)
    (""     "latexsym"  t)
    (""     "amssymb"   t)
    ("dvipdfmx"     "hyperref"  nil)
    "\\tolerance=1000"
    )
)

こうしないと pdfplatex 内部で呼び出される dvipdfmx が hyperref の処理の際に大量のエラーを吐く。

手順 (5) ソースを書く

org ファイルの先頭に

#+LaTeX_CLASS: jsarticle
#+LaTeX_CLASS_OPTIONS: [english]
#+LaTeX_HEADER: \usepackage{txfonts}

と書いて jsarticle を指定する。OPTIONS と HEADER はお好みで。

以上で C-c C-e p とやれば、かなり時間がかかるけどちゃんと PDF に出力できます。