普段、技術的なメモは Emacs の org-mode で書いたものを 自身の Github リポジトリ に公開している。ただ、これはあくまで個人的なメモなので、それほど他人が見ることを意識したものではない。より見やすい記事として公開するために、個人のブログを、静的サイトジェネレーターの Hugo + Netlify で開始したが、力を入れて書いた技術記事は Qiita にも公開して、広く読んでもらえるようにしたい。
そこで、これまで通り、org ファイルは同じリポジトリで管理しつつ、1 つの org ファイルから個人ブログ向けと Qiita 向けの Markdown をエクスポートできないか試してみた。
生成されるファイル
まずは、結論から。個人ブログ向け・ Qiita 向け、それぞれの出力結果がこちらである。いくつかの機能差分はあるが、普段よく使う内容については概ね Hugo/Qiita どちらも Markdown として出力できそうなことがわかった。
なお .org
や .md
を Github 上で閲覧すると github/markup によって自動的にレンダリングされるので、ソースは「Raw」から見てほしい。
ここから、具体的に設定項目、org-mode との機能差分を見ていく。
動作確認バージョン
ソフトウェア | バージョン |
---|---|
OS | Ubuntu 18.04 |
Emacs | 26.3 |
org-mode | 9.2.6 |
Hugo | 0.59.1/extended |
Qiita 向けの Markdown Exporter の選択
Hugo 向けの Exporter は ox-hugo
一択でよいだろう。Qiita 向けの Markdown の生成には、いつくかの候補を検討した後に、最も機能の差分が少なかった ox-gfm
を選択した。他の選択肢としては、標準の ox-md
や、こちらの記事で紹介されている ox-qmd
などがある。特に ox-qmd
はそのものズバリで、最も org-mode から Qiita への再現性が高いと思われた。しかし、自分の設定が悪いのか、org の table が HTML として出力されてしまい、その結果、文字修飾が有効にならないという問題があったため断念した。他にも ox-pandoc
からも Markdown を出力できるが、今回は試していない。
ox-hugo と ox-gfm のインストール
ox-hugo
と ox-gfm
のインストールは非常に簡単で、特に必要な設定項目はない。 load-path
に追加して読み込むだけで完了である。
(add-to-list 'load-path "/path/to/ox-hugo")
(require 'ox-hugo)
(add-to-list 'load-path "/path/to/ox-gfm")
(require 'ox-gfm)
M-x org-export-dispatch
のメニューに "Export to Hugo-compatible Markdown" と "Export to Github Flavored Markdown" が表示されていれば、インストール成功だ。
ox-hugo の設定
ox-hugo
から Hugo ブログを生成する方法として、2 つの方式がある。
- "One post per Org subtree" 方式: 1 つの org ファイルから、複数の Markdown を生成する
- "One post oer Org file" 方式: 1 つの org ファイルから 1 つの Markdown を生成する
1 の方式が ox-hugo
の売りのひとつでもあるが ox-gfm
との併用を考えると 2 の方式を選択せざるを得ない。
また ox-hugo
のサンプルには、見出しの下に :PROPERTIES:
を設定している例が見られるが、そうしてしまうと ox-gfm
でエクスポートした際に、そのまま記事として出力されてしまうため、必要な設定項目は全て最初の見出しより上に記載する必要がある。
この記事を例にヘッダーでの Hugo に関連する設定項目を見てみよう。
#+OPTIONS: author:nil H:6 toc:nil
#+HUGO_BASE_DIR: ~/Dropbox/repos/github/five-dots/blog
#+HUGO_SECTION: post/2019/11/
#+TITLE: 1 つの org ファイルから Hugo と Qiita の Markdown を生成する
#+DATE: 2019-11-05
#+HUGO_CATEGORIES: emacs
#+HUGO_TAGS: org-mode markdown hugo
#+HUGO_CUSTOM_FRONT_MATTER: :toc true
以下本文...
-
:OPTIONS: author:nil H:6 toc:nil
-
ここに記載されているように
auther:nil
にすることで "著者名が配列として cast できないエラー" を回避している - 後述するように、デフォルトでは h4 までしか出力されないため
H:6
で h6 までの出力に変更している - Qiita では自動で ToC が生成されるので、
toc:nil
に設定することで、不要なox-gfm
側での ToC を生成を止めている
-
ここに記載されているように
-
#+HUGO_BASE_DIR: ~/Dropbox/repos/github/five-dots/blog
- org ファイルと blog 自体のリポジトリを分けているので、絶対パスで出力場所を指定している
-
#+HUGO_CUSTOM_FRONT_MATTER: :toc true
- Hugo 側にはこの項目で ToC が自動で生成されるようにしている
Qiita への投稿フロー
現状は、org ファイルがある同じディレクトリに同名の .md
としてエクスポートし、Qiita の投稿画面に手動で貼り付けている。こちらの記事で紹介されていた qiita.el
はまだきちんと試すことができていないが、Qiita への投稿頻度が増えてきたら、導入を検討したい。
org-mode の出力確認
以降の章で、org-mode の記法毎に出力結果を確認していく。両者に共通して利用できるものに絞って記事を作成することで、二重管理を避けていくことが主目的だ。
Hugo テーマは Even を利用している。その他のテーマでは、この記事と異なる結果になる可能性もあるので、その点は注意が必要だ。
見出し
Hugo=h2 / Qiita=h1
Hugo=h3 / Qiita=h2
Hugo=h4 / Qiita=h3
Hugo=h5 / Qiita=h4
Hugo=h6 / Qiita=h5
メモ
- Hugo
- Hugo では
*
がタイトルとして扱われるため、**
(h2) から見出しとして機能する。そのため Qiita とは 1 階層ずれるが、大きな問題にはならない - org-mode のデフォルトでは、h4 までしか出力されないため、それ以上の深さが必要な場合は
#+OPTIONS: H:6
のように追加で設定が必要 - Even theme では h6 が最小
- Hugo では
表・文字修飾
項目 | org-mode | 結果 |
---|---|---|
太字 | *bold* |
bold |
イタリック | /italic/ |
italic |
下線 | _underline_ |
underline |
取り消し線 | +strikethrough+ |
|
コード | ~code~ |
code |
逐語 | =verbatim= |
verbatim |
上付き | hoge^{super} |
hogesuper |
下付き | hoge_{sub} |
hogesub |
ギリシャ文字 | \alpha |
α |
メモ
- Hugo
- 下線は
span.underline {text-decoration: underline;}
をstatic/css/custom.css
に追加した場合の表示結果 - コードは
(setq org-hugo-use-code-for-kbd t)
に設定した場合の表示結果
- 下線は
- Qiita
- 下線・コードは有効でない
リスト
順序なしリスト
- hoge
- hoge
- fuga
- piyo
- fuga
- piyo
チェックボックス
- hoge
- fuga
- piyo
順序ありリスト
- hoge
- hoge
- fuga
- piyo
- fuga
- piyo
定義リスト
- リンゴ: 赤いフルーツ
- オレンジ: 橙色フルーツ
メモ
- Hugo
- チェックボックスは、チェックをつけてしまうとなぜか表示されなくなってしまう
- Qiita
- チェックボックス自体が有効にならない
引用
Everything should be made as simple as possible, but not any simpler —Albert Einstein
メモ
- Hugo/Qiita ともに問題なく表示されている
数式
インライン
$y=f(x)$
$y=f(x)$
ブロック
$$y=f(x)$$
$$y=f(x)$$
メモ
- Qiita
- ox-gfm のエクスポート時に Latex Fragment の
$ ... $
が\( ... \)
に$$ ... $$
が\[ ... \]
に変換されてしまう - Qiita の数式記法 では、この記法に対応していないので、公式やここやここを参考にフィルタを作成して再変換する
- ox-gfm のエクスポート時に Latex Fragment の
(require 's)
(require 'dash)
(defun my/org-replace-latex-wrap (text backend _info)
(when (org-export-derived-backend-p backend 'gfm)
(cond
((s-starts-with? "\\(" text)
(--> text
(s-chop-prefix "\\(" it)
(s-chop-suffix "\\)" it)
(s-wrap it "$")))
((s-starts-with? "\\[" text)
(--> text
(s-chop-prefix "\\[" it)
(s-chop-suffix "\\]" it)
(s-wrap it "$$"))))))
(add-to-list 'org-export-filter-latex-fragment-functions 'my/org-replace-latex-wrap)
脚注
- org-mode1
[fn:name]
メモ
- Qiita
- Qiita では有効でない
水平線
-----
メモ
- Hugo
- 5 つの
-
で Markdown 側では---
に変換される
- 5 つの
コードブロック
Emacs Lisp
(emacs-version)
GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.30)
of 2019-09-17
R
コード出力
R.version
_
platform x86_64-pc-linux-gnu
arch x86_64
os linux-gnu
system x86_64, linux-gnu
status
major 3
minor 6.1
year 2019
month 07
day 05
svn rev 76782
language R
version.string R version 3.6.1 (2019-07-05)
nickname Action of the Toes
表
library(tidyverse)
head(iris)
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5 | 3.6 | 1.4 | 0.2 | setosa |
5.4 | 3.9 | 1.7 | 0.4 | setosa |
プロット
library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point()
メモ
- Qiita
- Hugo 向けには
ox-hugo
が自動で画像ファイルをstatic/ox-hugo/
へ移動してくれるが、Qiita へは手動で画像をアップロードする必要がある - そのため org-babel からプロット画像を出力する先を Dropbox フォルダに設定し、共有リンク機能を利用して画像を公開する
- org-babel は
:exports code
に設定することで、ファイルリンク出力を抑制しつつ、手元ではプロットをインライン画像で確認できる - ここの記事を参考に、Dropbox の直リンクに変換し、以下のように HTML として出力する
- 将来的には Dropbox API + Emacs Lisp で自動化したい
- Hugo 向けには
#+attr_html:
[[https://dl.dropboxusercontent.com/s/4j5jstkg1fsvdiw/iris.png]]
Python
import sys
sys.version
3.6.8 (default, Oct 7 2019, 12:59:55)
[GCC 8.3.0]
まとめ
一部、Qiita 側で有効にならない記法が見られたが、無いと致命的、という項目はなかった。また、不足している項目も (org-export-filter-TYPE-funstions)
を利用すれば、それほど苦労もなくカスタマイズしていけそう、ということもわかった。これから快適なブログライフを送っていきたい。
それでは Happy blogging !!
参考
- Qiita 関連
- ox-hugo 関連
- org-mode フィルタ関連
- Dropbox 関連