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:
- 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