😗

Obsidian → Hugo の運用方法 2

2022/02/26に公開

ざっくり

タイトルにある通り, これは Obsidian → Hugo の運用方法 の続編です.
↑ のノートを書いた後に, Obsidian エクスポート用ツールの obsdconv を改良し, 運用方法がもう少しシンプルにできたのでまとめてみました.

エクスポート前後の状況

Obsidian のフォルダ構成

.
|-- .obsidian/
|-- _template/
|-- private/
    |-- notes/
    |-- static/
|-- public/
    |-- notes/
        |-- ABC.md
        |-- DEF.md
    |-- static/
        |-- GHI.png

こういったフォルダ構成を採用している理由はもとのノート Obsidian → Hugo の運用方法 > Obsidian のフォルダ構成 で説明しているので省略します.

Hugo のフォルダ構成

.
|-- content/
|-- static/
|-- config/
|-- layouts/
|-- assets/
|-- themes/

こちらはデフォルトのフォルダ構成です.
前回は, obsidian ディレクトリを用意して, それを content ディレクトリの代わりに使っていました.
新しい方法ではそういった面倒な設定などは必要ありません.

エクスポート後はこうしたい

ファイルの移動先

こんな感じ ↓ に public/ 以下をそれぞれ適切なフォルダに出力したいです.

  • public/notes/*.mdcontent/notes/*.md
  • public/static/*static/images/obsidian/*

ファイルの変換内容

Obsidian には独自の記法があり, Hugo で処理するためには変換が必要です.
ここでは, 特に, 新しい方法を採用する上で注意したいポイントを説明します.
基本的な内容は Obsidian → Hugo の運用方法 > Obsidian フォルダからブログ用フォルダにエクスポート を参照ください.

内部リンクの処理

Obsidian では Vault 内の他のノートを [[ファイル名 | 表示名]] の形式で参照できます.
元の方法ではこれを Hugo で処理できるように, [表示名](ファイルへのパス) と変換していました.
しかし, 新しい方法ではもう少し手を加える必要があります.
というのも ↑ のフォルダ構成で , DEFpublic/notes/DEF.md とパスが解決されますが, これをそのまま Hugo で使うことはできません.
public/ 部分が不要だからです.
つまり, 内部リンクの変換には ↓ の2つの処理が必要です.

  1. パスの解決 (例: DEFpublic/notes/DEF.md)
  2. パスのプリフィックスの変換 (例: public/notes/DEF.mdnotes/DEF.md)

画像の埋め込みの処理

Obsidian では Vault 内の画像を ![[ファイル名 | ALT]] の形式で埋め込むことができます.
こちらも内部リンクと同様にパスの解決とパスのプリフィックスの変換が必要です.
Obsidian から Hugo にエクスポートしてきた画像は static/images/obsidian に配置したいので, 必要な処理はこんな感じ ↓ です.

  1. パスの解決 (GHI.pngpublic/static/GHI.png)
  2. パスのプリフィックスの変換 (public/static/GHI.png/images/obsidian/GHI.png)

front matter の処理

Hugo では特別な意味を持つ front matter のフィールドがあります.
例えば, datetype です.
私は Obsidian のノートを Zenn にもエクスポートしているのですが, Zenn のノートでは type を指定する必要があります.
なので, Zenn に投稿するノートを Hugo にエクスポートしようとすると, Zenn 用の type が Hugo で予期せぬ動作を引き起こす場合があります.
そのため, type フィールドを削除する, あるいは rename しなければいけません.

やり方

使うツール

Obsidian → Hugo の運用方法Obsidian → Zenn の運用方法 でも説明した通り, 自作している obsdconv というプログラムを使用します.

実行するコマンド全部

SRC=/path/to/your/obsidian/vault
TMP=tmp
DST_NOTES=content/notes/
DST_IMAGE=static/images/obsidian
obsdconv -src $SRC -tgt "${SRC}/public" -dst $TMP \
-title -cptag -remapkey='type:' \
-rmtag -link -cmmt -rmh1 \
-remapPathPrefix='public/notes/>notes/|public/static/>/images/obsidian/'
mv "${TMP}/notes/"* $DST_NOTES
mv "${TMP}/static/"* $DST_IMAGE
rm -r $TMP

ファイルをまずは tmp ディレクトリに出力し, それからノートは content/notes/, 画像は static/images/obsidian/ に移動しています.

以下では, 特に ファイルの変換内容 で説明した変換を行うために大切なオプション -remapkey-remapPathPrefix について説明します.
その他のオプションについては Obsidian → Zenn の運用方法 > コマンドの説明 を参照ください.

-remapkey

front matter のキーの rename を行うためのオプションです.
通常は -remapkey=original:new といったように, 元のキー:新しいキー といった形式で使いますが, 今回はシンプルに type フィールドを削除したいだけなので空文字 "" を指定しています.

-remapPathPrefix

内部リンクや埋め込みで用いるパスのプリフィックスを変換するためのオプションです.
ここでは, -rempPathPrefix='public/notes/>notes/|public/static/>/images/obsidian/' を使っているため, ↓ のようにリンクのパスが変換されます.

  • public/notes/DEF.mdnotes/DEF.md
  • public/static/GHI.png/images/obsidian/GHI.png

Hugo 側で必要な処理

Obsidian → Hugo の運用方法 > Hugo のフォルダ構成 よりもかなりシンプルになります.
↓ のようなファイル layouts/_default/_markup/render-link.html を作成するだけです.

{{- $url := urls.Parse .Destination -}}
{{- $scheme := $url.Scheme -}}

<a href="
  {{- if eq $scheme "" -}}
    {{- if strings.HasSuffix $url.Path ".md" -}}
      {{- relref .Page .Destination | safeURL -}}
    {{- else -}}
      {{- .Destination | safeURL -}}
    {{- end -}}
  {{- else -}}
    {{- .Destination | safeURL -}}
  {{- end -}}"
  {{- with .Title }} title="{{ . | safeHTML }}"{{- end -}}>
  {{- .Text | safeHTML -}}
</a>

{{- /* whitespace stripped here to avoid trailing newline in rendered result caused by file EOL */ -}}

↑ は obsidian-export の README を参考にし, 修正を加えています.

終わりに

obsdconv の機能拡張を行うことでエクスポートがかなりシンプルにできました.
Obsidian でとったノートを Hugo で公開しようとしている方の参考になれば幸いです😊

Discussion