🖨️

Emacsのorg-modeで論文を書こう2025

に公開

冬、それは論文の季節。

Emacsのorg-modeを使って、快適な論文執筆環境を作ります。

この記事は、実空間コンピューティング研究室アドベントカレンダー4日目の記事です。

できるようになること

  1. テキストからLaTeXへの変換 : 論文における本文・表・図や引用を、Markdownに近い書き方で記述できるようになる
  2. PDFプレビュー : latexmk を用いて、ファイルを保存するたびにPDFを出力できるようになる
  3. 文献の参照 : 本文中で文献を参照すると、参考文献として記載される。また、文献を対話的に選択できるようになる

ざっくりいうと、 自前のエディタで、プレーンテキストで論文を書きつつ、Overleafに近いワークフローが実現できます。

org-modeで論文を書くメリット

org-modeとはEmacsモードの一つで、アウトライナー機能やタスク管理機能の集合体です。モードというのはVSCodeでいう拡張機能のようなもので、ファイルに設定を記述することで利用します。org-modeには構造化ドキュメントを作成するための独自のマークアップ言語と、その言語で記述された文書をエクスポートする機能が含まれており、今回はこれを利用します[1]

org-modeで論文を書く一番のメリットは、本文に集中できるようになることです。LaTeXマクロの仔細に惑わされる事なく、執筆そのものに重点を置くことができます。

文章だけではわかりづらいと思うので、例を示します。「はじめに〜評価〜おわりに」という構成の論文を org ファイルで記述すると、

#+LATEX_COMPILER: lualatex
#+LATEX_CLASS: ltjsarticle
#+LATEX_CLASS_OPTIONS: [twocolumn]
#+BIBLIOGRAPHY: sample.bib
#+CITE_EXPORT: natbib unsrtnat
#+TITLE: Emacsのorg-modeで論文を書こう2025
#+AUTHOR: gomadoufu, 唯野教授
#+DATE: \today
#+OPTIONS: toc:nil

#+LATEX_HEADER_EXTRA: \usepackage{amsmath}
#+LATEX_HEADER_EXTRA: \usepackage{graphicx}
#+LATEX_HEADER_EXTRA: \usepackage{hyperref}
#+LATEX_HEADER_EXTRA: \usepackage{url}
#+LATEX_HEADER_EXTRA: \usepackage[numbers,sort,compress]{natbib}

#+begin_abstract
本稿では、Emacsのorg-modeを用いた論文執筆環境の構築方法について述べる。
org-modeはプレーンテキストベースで構造化された文書を作成でき、LaTeXへのエクスポート機能により学術論文の執筆に適している。
我々は、org-citeを用いた文献管理、自動PDF生成、ltjsarticleクラスとの統合方法を示す。
提案手法により、Markdown的な記法で可読性の高いソースを保ちながら、高品質な論文PDFを生成できることを確認した。
#+end_abstract

* はじめに
:PROPERTIES:
:CUSTOM_ID: sec:introduction
:END:

学術論文の執筆において、LaTeX[cite:@latexproject]は標準的なツールとして広く利用されている。
しかし、LaTeXの記法は冗長であり、文書の構造が見えにくいという課題がある。
特に初学者にとっては、コマンドの羅列により本来の執筆作業に集中しづらい。

一方、Markdown[cite:@markdown]に代表される軽量マークアップ言語は、シンプルな記法で構造化文書を記述できる。
Emacs[cite:@gnuemacs]のorg-mode[cite:@orgmode]は、Markdown以上の表現力を持ちながら、LaTeXへのエクスポート機能を備えている。

本稿では、org-modeを用いた論文執筆環境の構築方法を提案する。
具体的には、以下の3点について述べる:

1. org-citeによる文献管理の統合
2. ltjsarticleクラスとの連携設定
3. 自動PDF生成ワークフローの実装

これにより、可読性の高いソースコードを維持しながら、学会投稿に適したPDFを生成できる。


* 評価

** 執筆効率の比較

提案手法と従来のLaTeX直接編集における執筆効率を比較した。
被験者10名に、同一内容の2ページ程度の技術文書を作成してもらい、所要時間を計測した。

表[[tab:efficiency]]に結果を示す。
org-modeを用いた場合、平均で23%の時間短縮が見られた。

#+NAME: tab:efficiency
#+CAPTION: 執筆手法別の所要時間比較
#+ATTR_LATEX: :environment tabular :placement [tb]
| 手法          | 平均時間(分) | 標準偏差 |
|---------------+--------------+----------|
| LaTeX直接編集 |         45.3 |      8.2 |
| org-mode      |         34.8 |      6.5 |

** 可読性の評価

ソースコードの可読性について、被験者による主観評価を実施した。
5段階評価(1:読みにくい、5:読みやすい)の結果、org-mode記法は平均4.2点、LaTeX記法は平均2.8点となった。

* おわりに
:PROPERTIES:
:CUSTOM_ID: sec:conclusion
:END:

本稿では、Emacsのorg-modeを用いた論文執筆環境について述べた。
org-citeによる文献管理、ltjsarticleクラスとの統合、自動PDF生成により、効率的な執筆環境を実現した。

#+print_bibliography:

以下のPDFが出力されます[2]

必要なもの

  • Emacs 29+
  • org-mode 9.5+
  • Tex Live 2020以降

OrgファイルをLaTeXファイルに変換する

最新のEmacsはorg-modeを標準搭載しており、さらにorg-modeはデフォルトでLaTeXエクスポート機能(ox-latex)を含んでいます。よって、Emacsをインストールした時点で、OrgファイルをLaTeXファイルに変換することはできます。しかし実用上、追加で以下のような機能が欲しくなりますね

  • エクスポート時に latexmk を利用する
  • 論文投稿先の学会から提供されたクラスファイルを利用する

これらを実現するために、明示的な設定が必要です。

Emacsの設定ファイル init.el に以下を書きます。

(use-package org)
  
  ;;; LaTeX Export設定
(use-package ox-latex
  :ensure nil
  :demand t
  :after org
  :custom

  ;; org-latex-compilerは文字列ではなくnilにする(latexmk使用時)
  (org-latex-compiler nil)

  ;; latexmkを使用してPDF生成
  (org-latex-pdf-process
   '("latexmk -f %f"))

  :config
  ;; LuaLaTeX-ja用のクラス定義
  (add-to-list 'org-latex-classes
               '("ltjsarticle"
                 "\\documentclass{ltjsarticle}
                 [NO-DEFAULT-PACKAGES]
                 \\usepackage{hyperref}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))

org-latex-classes に文書クラスの定義を追加することで、日本語文書クラスに対応させています。もし投稿学会からテンプレートが配布されている場合は、クラスファイルを参考に独自のクラス定義を作成し、このリストに追加することで、変換に使用できるようになります。

クラス定義中に [NO-DEFAULT-PACKAGES] を指定すると、org-modeが自動的に挿入するデフォルトパッケージが読み込まれなくなります。これは、文書クラスや学会テンプレートが独自のパッケージ構成を持っている場合に、競合を避けるために必要になります。特に日本語文書クラスでは platexuplatex が使われていることが多いため、デフォルトパッケージとの噛み合わせが悪いです。したがって、これを設定しておいた方が無難です。後述しますが、パッケージの追加は org ファイル中で指定できます。

org-latex-pdf-process はデフォルトでは pdflatex を利用することになっていて、ここを書き換えることでエクスポート時に任意のコマンドを実行できます。今回はここで latexmk を呼び出すことで、LaTeX特有の環境設定を記述することを回避しています。一般的な場合と同様に、以下のような latexmkrcorg ファイルと同じディレクトリに置いてください。

#!/usr/bin/env perl

# $latex = 'platex -synctex=1 -halt-on-error -interaction=nonstopmode';
# $bibtex = 'pbibtex';  # platex用はpbibtex
# $dvipdf = 'dvipdfmx %O -o %D %S';
# $makeindex = 'mendex %O -o %D %S';
# $pdf_mode = 3;  # 3 = latex → dvi → pdf

# # uplatex + dvipdfmx
# $latex = 'uplatex -synctex=1 -halt-on-error -interaction=nonstopmode';
# $bibtex = 'upbibtex';
# $dvipdf = 'dvipdfmx %O -o %D %S';
# $makeindex = 'mendex %O -o %D %S';
# $pdf_mode = 3;

# lualatex
$lualatex = 'lualatex -synctex=1 -halt-on-error -interaction=nonstopmode';
$bibtex = 'upbibtex';  # または 'bibtex'
$makeindex = 'mendex %O -o %D %S';  # または 'makeindex'
$pdf_mode = 4;  # 4 = lualatex

# 外部PDFビューアを使わない(今回はEmacsで開くため、外部ビューワなどお好みで)
$pdf_previewer = 'none';
$preview_mode = 0;

PDFをプレビューする

設定が長めですが、org-modeのconfigとして以下を設定します。

(use-package spinner)

(use-package async)

(use-package org
  :bind
  ;; 非同期プレビュー
  ("C-c C-v p" . my/org-latex-preview-pdf)
  ;; 同期プレビュー
  ("C-c C-v s" . my/org-latex-export-sync)
  ;; コンパイル中断
  ("C-c C-v k" . my/org-latex-cancel-compile)

  :config
 ;; スピナー変数
  (defvar my/latex-spinner nil "LaTeXコンパイル用スピナー")
  (defvar my/latex-compile-buffer nil "コンパイル中のバッファ")
  
  (defvar my/latex-async-process nil)

  (defun my/org-latex-export-async (on-success)
    (when my/latex-spinner
      (message "⚠️  既にコンパイル中です")
      (cl-return-from my/org-latex-export-async))
    
    (setq my/latex-spinner (spinner-create 'progress-bar-filled t))
    (setq my/latex-compile-buffer (current-buffer))
    (spinner-start my/latex-spinner)
    (message "📄 PDF生成中(非同期)...")
    
    (let ((org-file buffer-file-name)
          (org-file-dir (file-name-directory buffer-file-name))
          (pdf-process org-latex-pdf-process)
          (latex-classes org-latex-classes)
          (latex-default-packages-alist org-latex-default-packages-alist))
      
      ;; プロセスオブジェクトを保存
      (setq my/latex-async-process
            (async-start
             `(lambda ()
                (require 'org)
                (require 'ox-latex)
                (setq org-latex-classes ',latex-classes)
                (setq org-latex-default-packages-alist ',latex-default-packages-alist)
                (setq org-latex-pdf-process ',pdf-process)
                (with-temp-buffer
                  (insert-file-contents ,org-file)
                  (setq buffer-file-name ,org-file)
                  (setq default-directory ,org-file-dir)
                  (org-mode)
                  (condition-case err
                      (let ((pdf-file (org-latex-export-to-pdf)))
                        (if pdf-file
                            (list 'success pdf-file)
                          (list 'error "PDF生成失敗")))
                    (error (list 'error (error-message-string err))))))
             
             (lambda (result)
               (when my/latex-spinner
                 (spinner-stop my/latex-spinner)
                 (setq my/latex-spinner nil))
               
               (cond
                ((eq (car result) 'success)
                 (let ((pdf-file (cadr result)))
                   (funcall on-success pdf-file)))
                ((eq (car result) 'error)
                 (message "❌ PDF生成エラー: %s" (cadr result)))
                (t
                 (message "❌ 不明なエラー")))
               
               (setq my/latex-compile-buffer nil)
               (setq my/latex-async-process nil))))))  

  ;; 自動エクスポート(保存時)
  (defun my/org-latex-export-auto ()
    (when (and (eq major-mode 'org-mode)
               (boundp 'my/auto-export-pdf)
               my/auto-export-pdf)
      (my/org-latex-export-async
       (lambda (pdf-file)
         (message "✅ PDF生成完了: %s" pdf-file)))))

  (add-hook 'after-save-hook #'my/org-latex-export-auto)

  ;; 手動プレビュー
  (defun my/org-latex-preview-pdf ()
    (interactive)
    (my/org-latex-export-async
     (lambda (pdf-file)
       (message "✅ PDF生成完了: %s" pdf-file)
       (find-file-other-window pdf-file))))
  
  ;; コンパイルをキャンセル
  (defun my/org-latex-cancel-compile ()
    "進行中のLaTeXコンパイルをキャンセル"
    (interactive)
    (when my/latex-spinner
      (spinner-stop my/latex-spinner)
      (setq my/latex-spinner nil))
    
    ;; バックグラウンドプロセスをkill
    (when (and my/latex-async-process
               (process-live-p my/latex-async-process))
      (delete-process my/latex-async-process)
      (message "🛑 コンパイルプロセスを強制終了しました"))
    
    (setq my/latex-async-process nil)
    (setq my/latex-compile-buffer nil)
    (message "⚠️  コンパイルをキャンセルしました"))
  
  
  ;; 同期的にPDF生成(デバッグ用)
  (defun my/org-latex-export-sync ()
    (interactive)
    (let ((spinner (spinner-create 'progress-bar-filled t)))
      (spinner-start spinner)
      (condition-case err
          (progn
            (message "📝 PDF生成中(同期)...")
            (redisplay t)
            (org-latex-export-to-pdf)
            (spinner-stop spinner)
            (message "✅ PDF生成完了"))
        (error
         (spinner-stop spinner)
         (message "❌ エラー: %s" (error-message-string err)))))))

このように設定すると、バックグラウンドで latexmk プロセスを走らせて、リアルタイムプレビューを実行することができます。 async パッケージを利用して非同期に処理を進めることで、コンパイル中もバッファの編集が可能です。なお、コンパイル中に保存した場合はコンパイル処理が2つになるわけではなく、後から来た処理がアーリーリターンします。また、もしコンパイル中に問題が起きて処理がハングしてしまった場合、キャンセル関数を呼び出すことで処理を中止できます。

spinner を使って、コンパイル中にお月さまをクルクルさせています。動いてるんだなーってわかって安心できます

Orgファイルの書き方

org ファイルで論文を執筆し、原稿をプレビューすることができるようになりました。ここで、Orgファイルでの論文の書き方を説明します。なお、必要最低限ざっくり説明なので、他にも色々機能はあるはずです

コンパイラ・文書クラス

#+LATEX_COMPILER: lualatex
#+LATEX_CLASS: ltjsarticle
#+LATEX_CLASS_OPTIONS: [twocolumn]

コンパイラ、文書クラスなど、最低限の設定には専用のディレクティブがあります。これについては、LaTeXへの変換結果をみてもらった方が理解が早いですね

% Created 2025-12-04 Thu 22:07
% Intended LaTeX compiler: lualatex
\documentclass[twocolumn]{ltjsarticle}

たとえば学会のテンプレートを使っていて、論文誌と研究報告とを切り替えるトグルがある場合は、この角かっこの中に記述すればいいわけです。

パッケージ

\usepackage 相当の記述をしたいときは、以下のように書きます

#+LATEX_HEADER_EXTRA: \usepackage{amsmath}
#+LATEX_HEADER_EXTRA: \usepackage{graphicx}
#+LATEX_HEADER_EXTRA: \usepackage{hyperref}
#+LATEX_HEADER_EXTRA: \usepackage{url}

ちょっと不恰好ですね、、その代わりLaTeXが見たまんま出るので、 \newcommand などもこちらで。

タイトル・著者情報など

専用のディレクティブがいくつかあります[3]

#+TITLE: Emacsのorg-modeで論文を書こう2025
#+AUTHOR: gomadoufu, 唯野教授
#+DATE: \today
#+OPTIONS: toc:nil

学会指定のクラスファイルで、タイトルや著者情報には専用のコマンドが用意されていることも多いです。そのような時は上記 OPTIONS でタイトル・著者情報を nil にした上で、org-mode内の latex ソースブロックで直接LaTeXを書くことで対応します。

例えば情報処理学会の公式テンプレートを使用する場合、 \usepackage 以下のファイル冒頭は次のようになります。 #+begin_export latex#+end_export で囲まれた箇所が、LaTeXでそのまま出力される[4]ので、タイトルや著者情報が必ず所定の形式で出力されるようになります。

#+LATEX_HEADER_EXTRA: \usepackage[dvipdfmx]{graphicx}
...(略)

#+begin_export latex


\title{Emacsのorg-modeで論文を書こう2025}

\author{gomadoufu}{gomadoufu}{University X}[user@university.example]

\begin{abstract}
ここがアブストラクト
\end{abstract}

\begin{jkeyword}
Emacs, org-mode, LaTeX, 論文執筆
\end{jkeyword}


#+end_export

ここまでで org ファイルを、クラスファイルに沿った形で、PDFに出力することができるようになりました。

参照・参考文献のコントロール

最後に、図表を本文中で参照したり、論文に参考文献を記載できるようにします。

図表の参照

図表の参照にはRefTeX[5]を利用します。文中でorg-modeのリンク記法を使って、図表との相互参照を作ることができます。

init.el に、以下のように設定します

(use-package reftex
  :ensure nil
  :hook
  (org-mode . reftex-mode)
  (LaTeX-mode . reftex-mode)
  
  :custom
  ;; RefTeXとorg-modeの統合
  (reftex-plug-into-AUCTeX t)
  (reftex-default-bibliography '("~/Documents/references.bib"))
  
  ;; ラベルの接頭辞設定
  (reftex-label-alist
   '(("\\section" ?s "sec:" "~\\ref{%s}" t ("section" "Section"))
     ("\\subsection" ?u "subsec:" "~\\ref{%s}" t ("subsection" "Subsection"))
     ("\\subsubsection" ?b "subsubsec:" "~\\ref{%s}" t ("subsubsection"))
     ("\\equation" ?e "eq:" "~\\eqref{%s}" t ("equation" "Equation"))
     ("\\figure" ?f "fig:" "~\\ref{%s}" t ("figure" "Figure"))
     ("\\table" ?t "tab:" "~\\ref{%s}" t ("table" "Table"))))
  
  ;; 目次の設定
  (reftex-toc-split-windows-horizontally t)
  (reftex-toc-split-windows-fraction 0.3))

本文中で、このように利用します

この提案手法全体の概要図を図[[fig:sys-overview]]に示す.

#+NAME: fig:sys-overview
#+CAPTION: 提案手法の概要図
#+ATTR_LATEX: :scale 0.15 :options bb=0 0 2000 1000 :placement [tb]
[[file:image/system.drawio.png]]

表[[tab:efficiency]]に結果を示す。
org-modeを用いた場合、平均で23%の時間短縮が見られた。

#+NAME: tab:efficiency
#+CAPTION: 執筆手法別の所要時間比較
#+ATTR_LATEX: :environment tabular :placement [tb]
| 手法 | 平均時間(分) | 標準偏差 |
|------+----------------+----------|
| LaTeX直接編集 | 45.3 | 8.2 |
| org-mode | 34.8 | 6.5 |

参考文献の参照

org-modeにデフォルトである、org-cite[6]という機能を利用します。文中に [cite:@key] と書くことでLaTeXでいうところの \cite 形式の参照が利用できるようになるほか、 bib ファイルからの文献の検索と挿入が利用できるようになります。これにフロントエンドとしてcitar[7]パッケージを組み合わせることで、モダンな絞り込み検索を可能にします

;;; org-cite設定
(use-package oc
  :ensure nil)

;;; citar設定(org-citeのUI強化)
(use-package citar
  :custom
  (org-cite-insert-processor 'citar)
  (org-cite-follow-processor 'citar)
  (org-cite-activate-processor 'citar)
  :bind
  (:map org-mode-map
        ("C-c b" . citar-insert-citation)))

上記の設定をしたら、 org ファイルの冒頭に以下の内容を加えます

#+BIBLIOGRAPHY: sample.bib
#+CITE_EXPORT: natbib unsrtnat

bibファイル名および使用する文献管理ツールは、適宜調整してください。特記すべきは CITE_EXPORT で、ここにbstファイルを指定することができます。情報処理学会(ipsjunsrt.bst)なら、このように

#+CITE_EXPORT: natbib ipsjunsrt

さて、ここまで設定したら、 bib ファイルを用意した上で、文献を参照したい箇所で C-c b と打ちます。すると、ミニバッファで文献を対話的に選択して、 [cite:@key] を文中に挿入することができるようになります。 文献を選択するときにTAB、挿入するときにTABで、TABキーを2回押します。私はここでEnterを押し続け、参照を挿入することができなくて悩みました。

最後に、論文の末尾で

#+print_bibliography:

と書くと、参考文献リストが自動で出力されます。すごい。

おわりに

なんか記事がめちゃくちゃ長くなっちゃいました!!!!! なにか助けになれば嬉しいです。

Emacsで良い論文執筆ライフ[8]を!

参考

以下の記事が大変参考になります

org → latexに変換する際の、文書クラスの設定などがまとまっています

https://kumaroot.readthedocs.io/ja/latest/emacs/emacs-org-latex.html

内容と関係ないですが、gif画像の作り方はこれが一番良かったです

https://qiita.com/mikene_koko/items/b132f1e9afef82d589b3

脚注
  1. https://takaxp.github.io/org-ja.html#Top ↩︎

  2. orgファイルからtexファイルへの変換はorg-modeによるものですが、組版のステップはTex環境およびlatexmkによるものです。 ↩︎

  3. https://orgmode.org/manual/Export-Settings.html ↩︎

  4. orgファイルの中にLaTeXがそのまま書けることは大きなメリットです。普段は簡便な記法を使いつつも、不測の事態に遭遇したらLaTeXにフォールバックして、インターネットにある解決策を適用できます。 ↩︎

  5. https://www.gnu.org/software/auctex/reftex.html ↩︎

  6. https://orgmode.org/manual/Citations.html ↩︎

  7. https://github.com/emacs-citar/citar ↩︎

  8. 論文執筆には、Emacsの他に、健康が必要です。寒いので体調にお気をつけて〜 ↩︎

GitHubで編集を提案

Discussion