## 経緯 [[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と互換性の高いドキュメントベースを実現する]]%%