Emacs

org-mode で日本語LaTeXを出力する方法

More than 5 years have passed since last update.

org-mode はもともとLaTeXと組み合わせて使うことを想定している。

しかし、org-mode で日本語LaTeXを使うためには、使用するエンジンに合わせて、スタイルファイルなどをカスタマイズする必要がある。(euptexは jsbook、xetexはbxjsreport、luatexはltjsarticleなど)

以下に、XeTeX, upTeX, LuaTeX を切り替えて使う場合の org-mode での設定例を示す。

最初に、upTeX以外のTeXやHTMLは、日本語の途中で改行があると、それを空白とみなしてしまうので、それを除去するようにする。ここでは単純に、U+2000 以降の文字同士が改行で分割されていた場合は改行を削除する関数に例を示す。

(defun remove-org-newlines-at-cjk-text (&optional _mode)
  "先頭が '*', '#', '|' でなく、改行の前後が日本の文字の場合はその改行を除去する。"
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward "^\\([^|#*\n].+\\)\\(.\\)\n *\\(.\\)" nil t)
    (if (and (> (string-to-char (match-string 2)) #x2000)
               (> (string-to-char (match-string 3)) #x2000))
        (replace-match "\\1\\2\\3"))
    (goto-char (point-at-bol))))

(with-eval-after-load "ox"
  (add-hook 'org-export-before-processing-hook 'remove-org-newlines-at-cjk-text))

これによって、org-mode を他ファイルに出力するときは、日本語文字同士の間の改行が削除される。

なお、 with-eval-after-load は、Emacs 24.4 からの関数である。
Emacs 24.3 より前の場合は、eval-after-load を使うが、その場合は progn で囲んで quote する。

次に、LaTeXから自動的に PDF にするのに、latexmk を使うようにする。
以下は、各 TeX エンジンに適したlatexmk のコマンドオプションを出力する関数例である。

(defun my-latexmk-command (latex options &optional target output)
  "Generate LatexMk command for LATEX, (LatexMk-)OPTIONS, TARGET and OUTPUT directory."
  (let* ((latex-options
         '("-src-specials" "-file-line-error" "-interaction=nonstopmode"
           "-shell-escape" "-synctex=1"))
         (luatex-option
          (mapconcat (lambda (opt) (concat "-" opt)) latex-options " "))
         (latex-option
          (mapconcat 'identity latex-options " ")))
    (concat "latexmk -gg " options " "
            (case latex
              ('euptex "-pdfdvi -latex='uplatex ")
              ('xetex  "-pdf -pdflatex='xelatex ")
              ('luatex "-pdf -pdflatex='lualatex "))
            (case latex
              ('luatex luatex-option)
              (t latex-option))
            "' "
            (if output (concat "-output-directory=" output " "))
            target)))

そして、ox-latex が読み込まれた後で 使いたいエンジンに応じた設定を行う関数を実行するよう、hookを設定する。

(なお、auctex の変数 `TeX-engine' には、luatex/xetex/euptex など、自分で使う TeXエンジンを事前に設定しておく。)

(defvar my-org-latex-math-symbols-packages-alist
  '(("" "amssymb"   t)
    ("" "amsmath"   t)
    ("" "amsxtra"   t)
    ("" "bussproofs" t)
    ("" "isomath"   t)
    ("" "latexsym"  t)
    ("" "marvosym"  t)
    ("" "stmaryrd"  t)
    ("" "textcomp"  t)
    ("" "wasysym"   t)))

(with-eval-after-load "ox-latex"

  (add-hook 'org-export-before-processing-hook 'my-ox-latex-tex-engine-setup)

  (defun my-ox-latex-tex-engine-setup (backend)
    (message "backend=%s" backend)
    (when (equal backend 'latex)
      (my-ox-latex-engine-set TeX-engine)))

  (defun my-ox-latex-engine-set (latex)
    "Set up LATEX environments."

    (setq org-latex-default-packages-alist
          `(
            ,@(case latex
                ('luatex '(("" "luacode" t)
                           ("" "luatexja-otf" t)))
                ('xetex  '(;; noCJKchecksiingle で、\meaning の非BMPでの分割を抑止
                           ("AutoFallBack=true,noCJKchecksingle" "zxjatype" t)
                           ))
                ('euptex '(("uplatex,multi" "otf" t)
                           ("" "okumacro" t)))
                (t nil))
            ("" "fixltx2e" nil)
            ("" "fancyvrb" t)
            ("" "longtable" nil)
            ("" "float" nil)
            ;; LaTeX標準文字記号マクロ
            ,@my-org-latex-math-symbols-packages-alist
            ;;("" "tabulary" t)
            ("" "bigtabular" t)
            ("" "multicol" t)
            ;; その他のデフォルトで使用するLaTeX設定(以下は例)
            ,(concat
              "\\tolerance=1000\n"
              "\\providecommand{\\alert}[1]{\\textbf{#1}}\n"
              "\\fvset{xleftmargin=2em}\n")
            ))

    (setq org-latex-packages-alist
          `(
            ,(case latex
               ('xetex  '("" "graphicx"  t))
               ('euptex '("dvipdfmx" "graphicx"  t))
               (t       '("pdftex" "graphicx"  t)))
            ;; hyperref: PDFでハイパーリンクを生成
            ;; colorlinks=true を入れると、graphicx が dvipdfmx で失敗するので注意。
            ,(case latex
               ('luatex '("pdftex,pdfencoding=auto" "hyperref" t))
               ('euptex '("dvipdfm" "hyperref"  t))
               ('xetex  '("xetex" "hyperref"  t))
               (t       '("pdftex" "hyperref"  t)))
            ;; biblatex を入れると重くなるので、使用するorg-fileのみ、
            ;; `+LATEX_HEADER: \usepackage[backend=biber]{biblatex}'
            ;; で入れるほうが良い。。
            ;; ("backend=biber", "biblatex" t)
            ("" "listings")
            ("" "color")))

    (setq org-latex-classes
          `(("article"
             ,(case latex
                ('luatex "\\documentclass{ltjsarticle}\n")
                ('xetex  "\\documentclass[a4paper]{bxjsarticle}\n")
                ('euptex "\\documentclass[a4j,uplatex]{jsarticle}\n")
                (t       "\\documentclass[11pt]{article}"))
             ("\\section{%s}" . "\\section*{%s}")
             ("\\subsection{%s}" . "\\subsection*{%s}")
             ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
             ("\\paragraph{%s}" . "\\paragraph*{%s}")
             ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
            ("report"
             ,(case latex
                ('luatex "\\documentclass{ltjsarticle}\n")
                ('xetex  "\\documentclass[a4paper]{bxjsreport}\n")
                ('euptex "\\documentclass[11pt,report,uplatex]{jsbook}\n")
                (t       "\\documentclass[11pt]{article}"))
             ("\\section{%s}" . "\\section*{%s}")
             ("\\subsection{%s}" . "\\subsection*{%s}")
             ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
             ("\\paragraph{%s}" . "\\paragraph*{%s}")
             ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
            ("book"
             ,(case latex
                ('luatex "\\documentclass{ltjsarticle}\n")
                ('xetex  "\\documentclass[9pt,a4paper]{bxjsreport}\n")
                ('euptex "\\documentclass[9pt,a5j,uplatex]{jsbook}\n")
                (t       "\\documentclass[11pt]{book}"))
             ("\\part{%s}" . "\\part*{%s}")
             ("\\chapter{%s}" . "\\chapter*{%s}")
             ("\\section{%s}" . "\\section*{%s}")
             ("\\subsection{%s}" . "\\subsection*{%s}")
             ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
            ("beamer"
             ,(concat
               (case latex
                 ('xetex
                  "\\documentclass[compress,xdvipdfmx]{beamer}\n")
                 (t "\\documentclass[compress,dvipdfmx]{beamer}\n"))
               "\\usetheme{AnnArbor}\n"
               "\\setbeamertemplate{navigation symbols}{}\n"
               "[NO-PACKAGES]\n"
               "\\usepackage{graphicx}\n")
             org-beamer-sectioning)))

    (setq org-latex-pdf-process (list (my-latexmk-command TeX-engine "-pv" "%f" "%o"))))


  ;; "verbatim" → "Verbatim" 置換
  (defun my-org-latex-filter-fancyvrb (text backend _info)
    "Convert begin/end{verbatim} to begin/end{Verbatim}.
  Allows use of the fancyvrb latex package."
    (when (or (org-export-derived-backend-p backend 'beamer)
              (org-export-derived-backend-p backend 'latex))
      (replace-regexp-in-string
       "\\\\\\(begin\\|end\\){verbatim}"
       "\\\\\\1{Verbatim}" text)))
  (add-to-list 'org-export-filter-final-output-functions
               'my-org-latex-filter-fancyvrb)

  ;; "tabular" →  "Tabular"  置換
  (defun my-org-latex-filter-bigtabular (text backend _info)
    "Convert begin/end{tabular} to begin/end{Tabular}."
    (when (or (org-export-derived-backend-p backend 'beamer)
              (org-export-derived-backend-p backend 'latex))
      (replace-regexp-in-string
       "\\\\\\(begin\\|end\\){tabular}"
       "\\\\\\1{Tabular}" text)))
  (add-to-list 'org-export-filter-final-output-functions
               'my-org-latex-filter-bigtabular))

本来、org-latex-default-packages-alist には、org-mode 公認のすべての
LaTeX出力に共通なパッケージが設定されており、この変数は変更すべきものではない。しかし、本変数のデフォルト設定には、日本語で使用するには不適切なパッケージがあるので、それらを除外するために再設定する。ここで指定するパッケージは、upTeX/LuaTeX/XeTeX の日本語で動作するものに制限する。

org-latex-packages-alist には、org-mode 非標準の各スタイルファイルに共通なパッケージを入れる。

org-latex-classes には、 article/book/report など、各スタイルに特有の設定を入れる。

最後の 'my-org-latex-filter-fancyvrb' と、 `my-org-latex-filter-bigtabular` は、それぞれtabular の代わりにTabularを、verbatim の代わりにVerbatim を使いたい場合に置換を行うものである。(ただし、これで変換した LaTeX は、PanDoc を使ってもテーブルは正しく変換されないので注意する。)