Portable markdown links
Table of Contents
aka relative links, local links, file path links. Software supports portable markdown links if for content like this:
[test](folder/test.md)
- For editor: user can Cmd + Click the link and editor will jump to that file
- For static website generator: file pahts are replaced by URLs according generation scheme, for example:
[test](folder/test.md)
β<a href="/folder/test/">test</a>
Example #
portable-hugo-links shows how same links work in Github and website generated by Hugo.
Features #
- Links:
[readme](/readme.md)
, which also includes resolution of relative and absolute paths:[readme](../readme.md)
[readme](readme.md)
[readme](readme.md)
- Anchors:
[readme](/readme.md#heading)
- for editor: Cmd + Click should navigate to specified section
- for static website generator: anchors should be preserved in html links
- Images:
![alt](img.jpg)
- for editor’s preview: images should be displayed
- for static website generator: images should be displayed
Motivation #
Link types #
Let’s say we have file /contnet/posts/intro.md
:
It can have following web links:
/posts/intro/
/posts/intro
(web server will redirect anyway)/posts/intro.html
(withuglyURLs: true
)/posts/2020/01/01/introduction/
(with custom permalinks)/posts/my-first-post/
(withslug: my-first-post
)/articles/my-first-article
(withurl: /articles/my-first-article
)/posts/previous-file-name
(withaliases: [/posts/previous-file-name]
)../intro/
(relative)
It can have following wiki links:
[[intro]]
[[posts/intro]]
(in Foam for disambiguation)- theoretically with configs:
[[my-first-post]]
(withslug: my-first-post
)[[Intoduction]]
(withtitle: Intoduction
)
It can have following portable links:
- absolute:
/contnet/posts/intro.md
- relative:
./posts/intro.md
,posts/intro.md
,../intro.md
Resolution procedure (from link to file path) #
To resolve web links you need:
- configuration for resolution, something like
(path) => "content" + path + "index.md"
- maybe root of the project
- maybe scan all files in the root if there are tricky frontmatter configs used, like
url
,slug
,permalinks
,aliases
To resolve wiki links you need:
- to know root of the project
- scan all files in the root to be able to match name (file name or slug) to wiki link
To resolve portable links you need:
- to know root of the project
- to know file path where link is located (to resolve relative links)
Resolution procedure (from link to href) #
To resolve web links you need:
- to do nothing, but there is a chance that this will be 404 link or none-canonical link
To resolve wiki links you need:
- resolve to file path first
- follow the same procedure as for portable links
To resolve portable links you need:
- read frontmatter of the file
- generate link according to permalinks configuration
Who supports it? #
Software | Does it support PML |
---|---|
Github | Yes |
VSCode | Yes |
Hugo | Yes, with configuration |
Obsidian | Yes |
Docusaurus | Yes, see documentation |
Markdown Language Server | Yes |
markdown-links | Yes |
Jekyll | Yes, with plugin |
Foam | Yes, but bugy |
Astro | No, see discussion |
Next.js | No, AFAIK |
Gatsby | No, AFAIK |
… |
Naming #
Why do I call it portable? Because this simple convention allows to use same markdown files with different software wihtout modifications. In the same vein, we can think of portable markdown frontmatter, etc.
A bit of convention over configuration goes long way.
Related #
Read more: Documentation generators, BEOE