プログラミング
Gleam、Org-Mode、Pandocを使ったブログ
Blogging with Gleam, Org-Mode and Pandoc (byzantine-systems.github.io)
要約
この記事では、EmacsとOrg-modeを中心に、Gleam、Pandoc、d2などのツールを組み合わせて静的サイトを構築する手法を紹介しています。Org-modeの強力な機能とEmacsのエコシステムを活用し、コードブロックの実行や図の生成までをシームレスに行うことで、開発者がコンテンツ作成に集中できる環境を目指しています。
全文翻訳
Gleam、Org-mode、Pandocを使ったブログ
2026年10月01日
なぜ執筆はEmacsの中に留まるのか
私はプログラムを構成する手法に出会い、それが非常に気に入っています。実際、私の熱意は非常に大きいので、読者には、大きな光を見たばかりだと信じている狂信者のたわごととして、私が言うことの多くを割り引くように警告しなければなりません。(Knuth 1984, 1)
Byzantine Systemsの最初のブログ投稿へようこそ。これは私がOrg-modeを中心にウェブサイトを構築する初めての試みではありません。私はすでに自身の個人ブログでEmacsマキシマリズムへの道のりについて書いており、そこではEmacs、いくつかの疑わしいスクリプト、そしてNixがすべてをまとめていました。今回は、機能した部分(すべてをEmacsで書くこと)を維持しつつ、公開側をより小さく、型付けされ、理解しやすくしたいと考えました。
最終的な実験では、以下のツールを使用します。
Orgmodeをソースフォーマットとして、Emacsを書く環境として使用。
宣言的な図を作成するためにd2を使用。
Orgをさらに強力にするためにBabelを使用。
堅牢で成熟したコンバーターとしてPandocを使用。
ビルド環境を固定するためにNix、flakes、devenvを使用。
小さな型付けされた静的サイトパイプラインのためにGleamとBlogattoを使用。
独立したテンプレート言語を導入せずに、周囲のHTMLを定義するためにLustreを使用。
最後の2つのポイントは、単純な静的ページには過剰に見えるかもしれませんが、投稿を一覧表示するページをどのように作成するかで判断していただければと思います。それは単なるLustre要素を返すGleam関数です。
pub fn posts_page(posts: List(Post(msg))) -> Element(msg) {
let sorted = list.sort(posts, fn(a, b) {
timestamp.compare(b.date, a.date)
});
layout("Posts", [
html.h2([], [html.text("Posts")]),
case sorted {
[] -> html.p([], [html.text("No posts yet.")])
_ -> html.ul([], list.map(sorted, post_link))
},
])
}
このブログ記事のtl;drバージョンは次のようになります。私はOrgドキュメントにのみ触れます。Nixは、パイプラインの残りの部分を快適に平穏なものにする接着剤です。重要な詳細ですが、前の図はEmacs内で生成されました。私は「コードとしての図」というアイデアを生き続けさせたいと考えており、今のところd2は私にとってうまく機能しています。これは、Emacsの魔法を排除して結果(画像)のみを保持した場合の図のコードです。
direction: right
style.fill: "#ffffff" # デフォルトのノードスタイリング
*.shape: rectangle
*.style: {
border-radius: 8
stroke-width: 2
font-size: 12
}
# デフォルトのエッジスタイリング
(* -> *)[*].style: {
stroke: "#64748b"
font-color: "#475569"
stroke-width: 2
font-size: 10
}
emacs: "1. Emacs + Orgmode\nWrite raw content (.org)" {
style: {
fill: "#f3e8ff"
stroke: "#a855f7"
font-color: "#581c87"
}
}
pandoc: "2. Pandoc + plugins\nConvert Org to Markdown (.md)" {
style: {
fill: "#e0f2fe"
stroke: "#0284c7"
font-color: "#075985"
}
}
blogatto: "3. Blogatto\nGenerate final HTML" {
style: {
fill: "#dcfce7"
stroke: "#16a34a"
font-color: "#14532d"
}
}
emacs -> pandoc: Export
pandoc -> blogatto: Build
なぜすべてをEmacsの中に保つのか?
moderatly relatedですが、私の親友Marcos Maguetaは「GNU Shepherd is the abstraction for a better computing age」という興味深いビデオを作成しました。そこで彼はBLOAT、UNIXの世界で非常に軽蔑されている言葉ですが、ほとんどの人が無意識に行っていることについて論じています。
BLOATが本当に何であるかを正しく定義すること。
GOOD BLOATがあなたに何を与えられるかを知らずに。
Emacsは、UNIX哲学の観点から見ると、純粋なブロートです。確かに、EmacsはUNIXの「一つのことをうまくやる」という原則に従っていません。それは実際には良いことだとさえ主張できます。統一された環境の欠如は、結局、ユーザーランドのBLOATを引き起こします。この定義によれば、Emacsは良いブロートということになります。
一貫性は、標準を普及させる中央機関による集中的な努力を必要とします。Macintosh上のアプリケーションは、Appleが発行したガイドブックに従っているため一貫性があります。Unixユーティリティについては、そのような機関は存在したことがありません。その結果、一部のユーティリティはダッシュで始まるオプションを使用しますが、そうでないものもあります。標準入力を読み取るものもあれば、そうでないものもあります。標準出力を書き込むものもあれば、そうでないものもあります。ファイルを世界書き込み可能にするものもあれば、そうでないものもあります。エラーを報告するものもあれば、そうでないものもあります。オプションとファイル名の間にスペースを入れるものもあれば、そうでないものもあります。(Garfinkle, Weise, and Strassmann 1994, 25–26 chap.2)
また、Emacsを離れることは敗北を認めることになります。ブログ記事(またはメモ)を書くことは、私にとって単なる段落を書く以上のことです。ソースコードを周りに配置するのが好きです。時にはメモをエクスポートしたいこともあります。適切なbibtex引用が常に機能することを望んでいます。これらのそれぞれに別のアプリケーションが必要な場合、作業は同じアイデアの断片を含むウィンドウ(またはTUI)のツアーになります。長期的な目標は、最終的にすべてをEmacs内に移動することですが、その日は今日ではありません。
なぜMarkdownではなくOrg-modeなのか?
(…)Org-modeの些細な使い方は、単なるテキスト編集に過ぎず、そこからユーザーはドキュメントに特別なプレーンテキストOrg-mode要素を追加し始めることができます。したがって、Org-modeは採用が容易であり、計算言語と自然言語が混在するプロジェクトの作成のための一般的なソリューションとなることを目指しています。複数のプログラミング言語、エクスポートターゲット、ワークフローをサポートしています。(Schulte et al. 2012, 2)
私たちはすでにMarkdownを持っていますよね?それはユビキタスで、読みやすく、ほとんどすべての静的サイトジェネレーターでサポートされています。実際、このサイトはPandocが生成するMarkdownを使用し、Blogattoがそれを消費します。私はそれを直接書くだけではありません。
その理由は、Orgmodeがはるかに優れたフォーマットであり、唯一の欠点は、完全に楽しむためにはEmacs内にいる必要があること(そしてそれは許容できるトレードオフのように思えます)です。本当にそれを望むなら、.orgは単純な軽量マークアップフォーマットのままでいることができます…または、カスタムコマンド引数と生成された結果の場所さえある、Orgドキュメント内で任意のソースブロックを実行できます。
それがそれを非常に強力にしている理由であり、私がd2図をOrgメモに埋め込むのが好きな理由です。これにより、オンデマンドで画像を/図を常に再生成できます。それは、有名なJupyter Notebookに非常に似た、小さく再現可能な(研究のような)環境です。
Org-modeは、Emacsをシンプルで強力なマークアップ言語で拡張し、階層的に整理されたテキストドキュメントを作成、解析、操作するための言語に変えます。その豊富な機能セットには、テキスト構造化、プロジェクト管理、およびさまざまな形式にエクスポートできる公開システムが含まれます。ソースコードとデータはアクティブブロックに配置され、テキストセクションとは区別されます。「アクティブ」とは、コードとデータブロックを評価してその内容または計算結果を返すことができることを意味します。コードブロックの評価結果は、ドキュメント内の名前付きデータブロックに書き込まれ、そこから別のコードブロックで参照できます。これらのコードブロックは、異なるコンピューティング言語で記述できます。このように、Org-modeバッファは、さまざまなコンピューター言語が互いに通信する場所になります。Emacsと同様に、Org-modeは拡張可能です。ユーザーは、少数のEmacs Lisp関数の定義を通じて、新しい言語のサポートをモジュール式に追加できます。(Schulte et al. 2012, 7)
Markdownは、拡張機能や外部ツールを通じてこの一部を模倣できますが、その場合、作成モデルは特定のパーサー、エディター、プラグインコレクションの偶然の交差点になります。Org-modeの機能は、同じ一貫したシステムに属しています。さらに重要なのは、それらはビルド後に意味を持つ指示ではなく、エディター内でインタラクティブであることです。
Pandocを境界として
魅力的なアプローチの1つは、BlogattoにOrgを直接解析させることです。私はこれを長期的に探求し、メインリポジトリにプッシュすることさえするつもりです。今のところ、PandocはすでにOrgを理解しており、すでにGitHub Flavored Markdownを出力し、すでに引用処理プログラムを持っているため、変換ステージは退屈なままで済みます。
pandoc -s org/posts/example.org \
-t gfm \
--citeproc \
--bibliography=priv/bibtex/emacs.bib \
-o blog/posts/example/index.md
実際のコマンドはsrc/convert.gleamによって組み立てられます。これは、すべてのOrgページと投稿を見つけ、priv/bibtexの下にあるすべてのBibLaTeXデータベースを追加し、MarkdownをBlogattoのディレクトリ構造に書き込みます。