Obsidian ➡️ MkDocs Bridge
An MkDocs plugin that helps exporting your Obsidian vault as an MkDocs site.
What it does
I began writing this plugin to simplify exporting my Obsidian vault to GitHub Pages using MkDocs. The plugin is still in development since there are a lot more features that could possibly be implemented, however, currently it has the following features:
- Auto-expand incomplete Markdown links
- Auto-expand incomplete Obsidian's internal links
- Detect and mark invalid links (to style them differently)
Auto-expanding incomplete links
By auto-expanding I mean that you don't need to write a full path to the page you are linking to (exactly like in Obsidian). Consider the following folder structure:
docs/
├── 2021/
│ ├── Books.md
│ └── Games.md
└── 2022/
└── Sport.md
If you are editing Sport.md
, you could write:
[Books](../2021/Books.md)
but with this plugin you can just drop the path:
[Books](Books.md)
or even write the Obsidian way:
[[Books]]
Name clashes
What if you have Books.md
in both 2021 and 2022?
docs/
├── 2021/
│ ├── Books.md
│ └── Games.md
└── 2022/
├── Books.md
└── Sport.md
By default, the plugin tried to find the shortest relative path (again, like Obsidian), e.g.
[[Books]]
is translated into:
[Books](./Books.md)
But you can also give the resolver a hint by specifying the path partially:
[[2021/Books]]
or
[Books](2021/Books.md)
Both variants work equivalently.
How to enable
Install the plugin with:
pip install mkdocs-obsidian-bridge
The plugin depends on some features of Python 3.10, so this is the minimum required version.
Then you can enable it in your mkdocs.yml
config:
plugins:
- obsidian-bridge
Why one more plugin?
I wouldn't ever write this one if I could achieve what I need with other ones. Maybe, I just couldn't find the solution, but here we are.
Autolinks Plugin
Differences to- Autolinks Plugin doesn't try to resolve the shortest path out of the list of potential candidates.
- It also doesn't support incomplete relative paths. In other words, it works only with file names.
Roamlinks Plugin
Differences toThis one, actually, was the reason why I started developing my own plugin in the first place. However, it had the following drawbacks for my use-case:
- As well as Autolinks Plugin, the Roamlinks Plugin does not try to match the best path if there several of those, does it?
- Also, in case it can't resolve the
[[Roam link]]
, it leaves it as a text, while Obsidian Bridge still transforms it into the Markdown link although invalid one.
EZLinks Plugin
Differences toThis one looked like a perfect choice for my needs, however:
- I didn't spent much time playing with it, but EZLinks Plugin generated incorrect links for me. Probably because it doesn't resolve any incomplete paths as well as two previous plugins.
- At the same time, it does convert the
[[internal links]]
into actual links. - It has no ability to distinguish between valid and invalid
[[internal links]]
. Maybe it could be solved by another plugin, but I haven't searched for it.
WikiLinks extension for Python-Markdown
Differences to- I haven't tried this one, but it looks like WikiLinks is unable to automatically resolve paths at all without an additional (and a bit cumbersome) config.
- Also, not sure if it supports all the Obsidian's features.
Advanced topics
Styling of invalid links
See for yourself!
The plugin translates Obsidian-style [[internal links]]
to markdown [internal links](internal%20links)
even if the resulting link is invalid. If you want to distinguish such links from the rest, you can assign them a custom CSS style.
In order to do that, you should add an invalid_link_attributes
config option to your mkdocs.yml
AND enable the attr_list
Markdown extension:
markdown_extensions:
- attr_list
plugins:
- obsidian-bridge:
invalid_link_attributes:
- '.invalid'
extra_css:
- stylesheets/extra.css
The .invalid
in this example translates to class="invalid"
HTML attribute accordingly to the rules of Attribute Lists extension.
After that, you can extend extra.css
with some style (just don't forget to add extra_css
property to your mkdocs.yml
too as above):
a.invalid {
color: red;
}
Alternatively, if your style is going to be simple, you can just write it in the attribute itself as following:
markdown_extensions:
- attr_list
plugins:
- obsidian-bridge:
invalid_link_attributes:
- 'style="color: red"'
What's next
My current preliminary roadmap is the following:
- Obsidian's callouts ➡️ MkDocs's admonitions
- Support for Obsidian's nested tags
- Obsidian's comments
%% ... %%
➡️ HTML comments<!-- ... -->
I give no guarantees about the deadlines or whether I implement anything at all. I do it for myself and currently I do see a need, so probably I'll continue.
Feedback
I do appreciate any kind of constructive feedback.
- If you found a bug, please, report it.
- If you want to request a feature, please, post an idea.
- In all other cases, don't hesitate to start a discussion.