0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Emacs 精進 01: 考える方が速いに決まってる

Last updated at Posted at 2025-11-30

この記事は Emacs 精進 Advent Calendar 2025 1 日目の投稿です。

背景

2025 年 Qiita アドベントカレンダーの『完走賞』を狙って Emacs の記事を 25 本投稿します。審査は厳し目らしく、記事の品質を高めに保つ必要があります:

https://blog.qiita.com/adventcalendar-2025-qiitapresents/

とはいえガチガチの技術記事 25 本となると、読み書きともに現実的ではなくなります。流し読みできる程度の濃度で 25 本書いて行こうと思います。

対象読者

Emacs ユーザが主なターゲットです。設定の効果を主に紹介するため、環境構築全般に興味がある人も対象になるかと思います。

Qiita 執筆環境構築

初日は『Emacs 精進』の執筆環境を構築します。 12 月中に Markdown 記事を 25 本書くことになりますが、これらの記事を 1 つの org-mode ファイル内に記載したいと思います。

.org ファイルの構成

以下の .org ファイルに 25 記事を全て記載し、 .org ファイルから 25 個の Markdown ファイルを生成することにします:

2025-emacs.org
#+TITLE: Emacs 精進
#+BOOK_DIR: ../public
#+FILETAGS: :emacs:

* Emacs 精進 01: 考える方が速いに決まってる
:PROPERTIES:
:EXPORT_FILE_NAME: emacs-2025-01
:END:

この記事は [[https://qiita.com/advent-calendar/2025/emacs-25][Emacs 精進 Advent Calendar 2025]] 1 日目の記事です。

..

* Emacs 精進 25: 最強の小指
:PROPERTIES:
:EXPORT_FILE_NAME: emacs-2025-25
:END:

#+BOOK_DIR および EXPORT_FILE_NAME は独自のプロパティです。後ほど使用します。

  • BOOK_DIR で出力先のディレクトリを設定します。 (Zenn Book を意識した名前です)
  • EXPORT_FILE_NAME で出力先のファイル名を設定します。

Emacs 上では次のように見えます。各記事に相当する見出しを折り畳むことで、一連の投稿をエディタから一望できます:

ファイル構成

以下のファイル構成で、 increments/qiita-cli によりローカル環境でプレビューができます:

.
├── public
│   ├── emacs-2025-01.md
│   ├── ..
│   └── emacs-2025-25.md
└── org
    └── emacs-2025.org

increments/qiita-cli はフラットなファイル構成を要求しますから、 public 内には Emacs 精進以外の記事も混ざっていますが、 emacs-2025.org には Emacs 精進の記事のみが入っています。

org-qiita-export-buffer-to-book の作成

後は .org ファイルからの Markdown ファイルの展開を実装します。幸い org ドキュメントの subtree に対する export という概念があり、 org-mode はこのような処理が得意です。

詳しくは Zenn Book における解説記事 に譲ることにして、 Qiita 版は次のようになりました:

記事の ID や更新時刻の同期は考えていません 。 GUI からの投稿を前提としています。

(leaf ox-qmd
  :commands (org-qiita-export-buffer-to-book)
  :config
  ;; Converts org-mode tags into front matter tag.
  (defun qmd2-template-tags ()
    (let ((tags (or (mapcar #'substring-no-properties (org-get-tags))
                    "")))
      (string-join
       (mapcar (lambda (s) (format "\"%s\"" s)) tags)
       ",")))

  ;; Markdown file template for `@qiita/qiita-cli'.
  (defun qmd2-template (contents info)
    (let* ((title (or (substring-no-properties (car (plist-get info :title))) ""))
           (tags (qmd2-template-tags)))
      (concat
       "---\n"
       "title: \"" title "\"\n"
       "tags: [" tags "]\n"
       "private: false\n"
       "updated_at: \"\"\n"
       "id: null\n"
       "organization_url_name: null\n"
       "slide: false\n"
       "---\n\n"
       contents)))

  ;; The Qiita Markdown export backend, built on top of `ox-qmd'.
  (org-export-define-derived-backend 'qmd2 'qmd
    :options-alist
    '((:title "TITLE" nil nil t)
      (:tags "TAGS" nil nil space))
    :translate-alist '((template . qmd2-template)))

  ;; Exports a subtree of org file into a Markdown file.
  (defun org-qmd2-export-to-markdown (&optional async subtreep visible-only)
    (interactive)
    (let ((outfile (org-export-output-file-name ".md" subtreep)))
      (org-export-to-file 'qmd2 outfile async subtreep visible-only)))

  ;; Exports each level 1 heading into a Markdown file.
  (defun org-qiita-export-buffer-to-book (&optional org-dir)
    "Runs subtree export to each level 1 heading, respecting `#+BOOK_DIR'."
    (interactive)
    (require 'ox-qmd)
    (let* ((default-dir default-directory)
           (pub-dir (car (cdr (car (org-collect-keywords '("BOOK_DIR")))))))
      (cd pub-dir)
      (unwind-protect
          (org-map-entries
           (lambda ()
             (let ((exports (org-entry-get nil "EXPORT_FILE_NAME")))
               (when exports
                 (org-qmd2-export-to-markdown nil t))))
           "LEVEL=1")
        (cd default-dir)))))

Qiita CLI によるプレビューと Emacs (on Kitty & tmux) を並べると次のようになります:

01-overview.png

これで org-mode と Qiita CLI が協調するようになりました。 Qiita が自分のフィールドになったような気がします。

なお Zenn 版のスクリプト の通り Zenn Book としても出力できます:

01-zenn-book.png

PDF 出力も可能です。

まとめ

『Emacs 精進』の執筆環境を構築しました。 25 記事が 1 つの org ファイルに収まり、あるべき姿でスタートを切れたと思います。

Qiita のコミュニティガイドラインも達成できたのではないでしょうか:

  • 再利用性・汎用性がある
  • メモや走り書きに留まらない
  • 正確性の検証が十分である

それでは次の記事でお会いしましょう!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?