## 経緯
[[MkDocs]]と[[Material for MkDocs]]を使って[[Markdown]]ベースのドキュメントを構築しているが、リンクで[[Obsidian]]のような[[wikiリンク]]を使いたくなることが多い。また、[[コールアウト]]もできれば形式をあわせたい。
[[mkdocs-obsidian-bridge]]を使うとできそうなので試してみた。
## 環境
| 対象 | バージョン |
| ----------------------------------- | -------------------- |
| [[Ubuntu]] | 24.04.1 LTS |
| [[Python]] | 3.13.1 |
| [[Pip]] | 24.3.1 |
| [[MkDocs]] | 1.6.1 |
| [[Material for MkDocs]] | 9.6.5 |
| [[mkdocs-obsidian-bridge]] | 1.2.0 (一部変更あり) |
| [[MkDocs Backlinks Section Plugin]] | `b935158` |
## プロジェクト作成
まずは[[MkDocs]]と[[Material for MkDocs]]のみを有効にしたプロジェクトを作成する。
```console
mkdir mkdocs-sandbox
cd $_
python -m venv .venv
source .venv/bin/activate
pip install mkdocs mkdocs-material
mkdir docs
touch mkdocs.yml
```
`mkdocs.yml`
```yaml
site_name: MkDocs for Obsidian
site_author: tadashi-aikawa
theme:
name: material
```
`docs/index.md`
```markdown
Hello MkDocs for Obsidian!!
```
`localhost:8000` にアクセス。
![[Pasted image 20250222132357.png]]
## mkdocs-obsidian-bridge を入れる
[[mkdocs-obsidian-bridge]]をインストール。
```console
pip install mkdocs-obsidian-bridge
```
`plugins` に追加。
`mkdocs.yml`
```yaml
site_name: MkDocs for Obsidian
site_author: tadashi-aikawa
theme:
name: material
plugins:
- obsidian-bridge
```
リンク用のページを2つ追加。
`docs/みみぞう.md`
```markdown
ピギー!!
```
`docs/pets/tatsuwo.md`
```markdown
ウホ♡
```
`docs/index.md`
```markdown
Hello MkDocs for Obsidian!!
- [[みみぞう]]
- [[tatsuwo]]
```
結果は以下の通り。
| 対象 | リンクは有効か? | 備考 |
| ------- | -------- | --------------------- |
| みみぞう | yes | `みみぞう` がないとwarning |
| tatsuwo | yes | `tatsuwo` がないとwarning |
## 不要なwarningを削除する
先ほどのwarningはノイズなので無効化したい。以下のコード部分に手を加える。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
mkdocs-obsidian-bridge/mkdocs_obsidian_bridge/plugin.py at 4d37f750a43a3102659f1d951ab50b80ed967779 · GooRoo/mkdocs-obsidian-bridge
</div>
<div class="link-card-v2-content">
Use Obsidian’s syntax for your website with this MkDocs plugin - GooRoo/mkdocs-obsidian-bridge
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/0dfa3698a6b725edd141a2141a87f489dd0f01eb13c0e80843babac39ba56c9c/GooRoo/mkdocs-obsidian-bridge" />
<a href="https://github.com/GooRoo/mkdocs-obsidian-bridge/blob/4d37f750a43a3102659f1d951ab50b80ed967779/mkdocs_obsidian_bridge/plugin.py#L292"></a>
</div>
```python
else:
link_filepath = Path(matched_filepath.replace('\\', '/'))
new_path = self.find_best_path(link_filepath, page_path)
# if nothing found, try once again but with ".md" file extension
if new_path is None:
new_suffix = link_filepath.suffix + '.md'
new_path = self.find_best_path(link_filepath.with_suffix(new_suffix), page_path)
```
この処理だと
1. `new_path` に[[wikiリンク]]で指定したパスに対する絶対パスを取得
2. 1が存在しない場合は `.md` をつけて再試行
となっているが、1で呼び出される `find_best_path` で必ずwarningが発生してしまう。
```python
def find_best_path(self, link_filepath: Path, page_path: Path) -> Path | None:
def match_link_filepath(p: Path) -> bool:
return p.as_posix().endswith(link_filepath.as_posix())
assert page_path.is_absolute()
assert self.file_map is not None
# Check if the filename exists in the filename to abs path lookup defaultdict
# ★ここに必ず入る
if link_filepath.name not in self.file_map:
# An if-statement is necessary because self.filename_to_abs_path is a
# defaultdict, so the more pythonic try: except: wouldn't work.
logger.warning(
'''[ObsidianBridgePlugin] Unable to find %s in directory %s''',
link_filepath,
self.docs_dir,
)
return
```
今回は `hoge` か `hoge.md` のどちらかが存在すればwarningにはしない...としたいので、以下のように変更した。
```diff
- new_path = self.find_best_path(link_filepath, page_path)
+ if any([link_filepath.name.endswith("." + fmt) for fmt in self.OBSIDIAN_FORMATS]):
+ new_path = self.find_best_path(link_filepath, page_path)
- if new_path is None:
+ else:
new_suffix = link_filepath.suffix + '.md'
new_path = self.find_best_path(link_filepath.with_suffix(new_suffix), page_path)
```
せっかくなのでDiscussionにも投稿しておいた。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
Suppress warning when links do not include the .md extension · GooRoo/mkdocs-obsidian-bridge · Discussion #23
</div>
<div class="link-card-v2-content">
Thank you for this amazing plugin! I often build documentation sites using MkDocs, but after a while, the redund ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/73e24d02f3be1fe6e345bd25cbc307e0073a65d0eaf93a54db6b24e04b0e8425/GooRoo/mkdocs-obsidian-bridge/discussions/23" />
<a href="https://github.com/GooRoo/mkdocs-obsidian-bridge/discussions/23"></a>
</div>
もし利用したい場合は以下のforkしたリポジトリをクローンすれば使える。もし本流で対応されたら戻せばよい。
```console
pip install git+https://github.com/tadashi-aikawa/mkdocs-obsidian-bridge
```
## コールアウトを使う
[[Obsidian]]でよく使う[[コールアウト]]の形式も利用できる。設定に `markdown_extensions` を追加する。
`mkdocs.yml`
```yaml
site_name: MkDocs for Obsidian
site_author: tadashi-aikawa
theme:
name: material
plugins:
- obsidian-bridge
markdown_extensions:
- obsidian_callouts
```
こんな風に書くと...
```markdown
> [!info]
> Calloutの形式で書ける
> [!warning] タイトルつき
> Calloutの形式で書ける
> [!error]- 折り畳み
> Calloutの形式で書ける
```
こうなる。
![[Pasted image 20250222145631.png]]
## Admonitionを使う
説明ついでに[[Admonition (MkDocs)|Admonition]]も入れる。設定の `markdown_extensions` に以下3つを追加。
```yaml
markdown_extensions:
- admonition
- pymdownx.details
- pymdownx.superfences
```
以下のような感じ。で同じ表示になる。
```markdown
!!! info
Calloutの形式で書ける
!!! warning "タイトルつき"
Calloutの形式で書ける
??? danger "折り畳み"
Calloutの形式で書ける
```
## コールアウトとAdmonitionはどちらがいいか
ケースバイケースな気がする。[[Obsidian]]の[[Vault]]と完全互換にするつもりがなければ、[[Admonition (MkDocs)|Admonition]]と[[コールアウト]]両方に対応していいと思う。
- 編集の手間という意味では、[[Admonition (MkDocs)|Admonition]]の方がインデント変更だけで解決するので優れている
- 使っているツールによってはシンタックスハイライトなどの観点で[[コールアウト]]の方が優れている
- [[MkDocs]]の複雑な構文だと[[コールアウト]]でフォローできない可能性あり、そのときは[[Admonition (MkDocs)|Admonition]]を使う
`コールアウト`
```md
> [!info]
> TypeScriptのサンプルコード。
>
> ```typescript title="タイトル"
> const hoge = 1
> const fuga = 10
> console.log(hoge + fuga)
> ```
>
> <span style="color: red">
> hogehoge
> </span>
```
`Admonition`
```md
!!! info
TypeScriptのサンプルコード。
```typescript title="タイトル"
const hoge = 1
const fuga = 10
console.log(hoge + fuga)
```
<span style="color: red">
hogehoge
</span>
```
[[Neovim]]での見た目は[[コールアウト]]に軍配が上がる。
![[Pasted image 20250222150858.png]]
## バックリンクを表示する
[[Obsidian]]のように[[バックリンク]]を表示する。
```console
pip install git+https://github.com/six-two/mkdocs-backlinks-section-plugin
```
[[GitHub]]のリポジトリからインストールしているのは、以下で追加されているオプションを追加したいから。リリースされたら `pip install mkdocs-backlinks-section-plugin` に変更する予定。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
Option to to having backlinks section for empty list · Issue #1 · six-two/mkdocs-backlinks-section-plugin
</div>
<div class="link-card-v2-content">
Hi. ❤ I love your project! ❤ It would be super useful having an option not showing Backlinks section on pages th ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/1f97dee0f41bfa94a32aa1ba1ea4d1c8f9cc5cd1f045c1a6f0ae31925f4916b4/six-two/mkdocs-backlinks-section-plugin/issues/1" />
<a href="https://github.com/six-two/mkdocs-backlinks-section-plugin/issues/1"></a>
</div>
設定を追加する。
```yaml
plugins:
- backlinks_section:
title: "🖇️ Backlinks"
description: ""
add_to_toc: false
hide_if_empty: true
```
[[バックリンク]]のセクションが追加される。
![[Pasted image 20250222155735.png]]
## obsidian.nvim を使う
既に[[Obsidian]]で問題なく編集できるようにはなっているが、普段は[[Neovim]]で開発しているので[[obsidian.nvim]]で編集できるようにしておく。
[[obsidian.nvim]]の設定に今回のワークスペースを追加すればよい。
```lua
require("obsidian").setup({
workspaces = {
{
name = "mkdocs-sandbox",
path = "~/tmp/mkdocs-sandbox",
overrides = {
notes_subdir = "docs",
},
},
},
```
なお、[[obsidian.nvim]]は開発が止まってそうであり、[[Zettelkasten]]の思想が強い方向にカスタマイズされていたり、日本語サポートが弱かったので、forkしたこちらに改修を加えて好きに使っている。日本語圏ユーザーで[[Obsidian]]の素の挙動が好きな方であればある程度はマッチするかなと。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
GitHub - tadashi-aikawa/obsidian.nvim: Obsidian 🤝 Neovim
</div>
<div class="link-card-v2-content">
Obsidian 🤝 Neovim. Contribute to tadashi-aikawa/obsidian.nvim development by creating an account on GitHub.
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/0e864cc474c4cfd338150b8e2186a4edac967d67e5c7762e1ec6e526c6cfbe38/tadashi-aikawa/obsidian.nvim" />
<a href="https://github.com/tadashi-aikawa/obsidian.nvim"></a>
</div>
## まとめ
- [[wikiリンク]]
- [[バックリンク]]
- [[コールアウト]]
- [[Neovim]]での編集
あたりに対応できたのでこの辺にしておく。[[MkDocs]]の更なるカスタマイズに関しては別途整理する予定。せっかくだし[[📒Articles]]でも書こうかな。
### 追記
書きました。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
📘MkDocsでObsidianと互換性の高いドキュメントベースを実現する
</div>
<div class="link-card-v2-content">Obsidianやobsidian.nvimと高い互換性を持ち、Markdown・Python・YAML・ターミナル操作の知識がある方向けに、MkDocsとMaterial for MkDocsを使った無料・クローズドなドキュメントサイト構築方法を詳しく解説します。プラグイン設定やカスタマイズ手順も紹介しています。</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/%F0%9F%93%98Articles/attachments/2025-02-23.webp" />
<a data-href="📘MkDocsでObsidianと互換性の高いドキュメントベースを実現する" class="internal-link"></a>
</div>
%%[[📘MkDocsでObsidianと互換性の高いドキュメントベースを実現する]]%%