Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable link-style generation #103

Open
MatteoJoliveau opened this issue Aug 26, 2022 · 4 comments
Open

Configurable link-style generation #103

MatteoJoliveau opened this issue Aug 26, 2022 · 4 comments

Comments

@MatteoJoliveau
Copy link
Contributor

MatteoJoliveau commented Aug 26, 2022

Hi, it's me again!

Currently fn fix_link(dest: CowStr) -> CowStr converts markdown links from something/something.md to something/something.html. This makes it difficult to support clean URLs (aka /my/page instead of /my/page.html). In my case, I actually generate HTML files as independent index.html files in dedicated directories. For instance, this is the conversion my SSG performs:

Source File Generated File Live URL
README.md index.html /
an-article.md an-article/index.html /an-article
a/nested/README.md a/nested/index.html /a/nested

Proposed solution

Have the Vault accept an additional (optional) configuration flag that asks whether to generate clean URLs or not. Since the output of the actual HTML files is up to the caller, the only thing this flag does is change the behaviour of fix_link(). The flag can be false by default to keep the current behaviour as the default one.

/// Generate /my/page.html and /categories/README.html links. Default behaviour
mdzk::VaultBuilder::default().source(out_dir).clean_urls(false)


/// Generate /my/page and /categories links
mdzk::VaultBuilder::default().source(out_dir).clean_urls(true)

Currently, I worked around this by parsing the generated HTML and applying some heuristics based on the current note path, fixing relative links and cleaning up file extensions, but it's cumbersome (around 60 LOC of pretty inefficient string manipulation) and the built-in solution would be much cleaner and more efficient.

Alternatives I considered

One alternative would be to skip Note::as_html and implement Markdown parsing myself using pulldown-cmark. That could work, and I may have to do it anyway in the future for stuff like custom HTML nodes, but I still think this could be a useful feature for use-cases that do not require such fine-grained control over the parsed DOM.

@MatteoJoliveau
Copy link
Contributor Author

Actually, since HTML generation doesn't happen until Note::as_html is called, the flag can just be passed to the function, maybe as an enum to be more explicit.

note.as_html(LinkStyle::Clean)

This would be an API breaking change tho

@kmaasrud
Copy link
Member

Great question, and something that definitely needs to be considered! However, firstly we need to establish the following: Seeing as you want clean links to all your internal pages, can we assume the option you want should only apply to wikilinks?

  • If yes: I'm planning an interface for custom wikilink handlers, which could be chained to the wiklink parsing process. This would allow you to customize how the wikilinks are converted into Markdown, allowing you to output clean links pretty easily. I've not decided on the exact API here yet, but you can read more on this in Wikilink handlers #77
  • If no: Then you would indeed need to hook into the Markdown to HTML-part of the proceedure. Note::as_html is mainly provided as a convenience function, so I think skipping it and doing the Markdown parsing yourself would perhaps be the best solution. pulldown_cmark has an excellent event system, so doing clean links should be pretty trivial.

Excited to hear your thoughts!

@MatteoJoliveau
Copy link
Contributor Author

I think a pluggable interface to customize link generation is a very good idea! It would allow downstream projects to do what they wish with links without bloating mdzk with a ton of conditional logic.

Do you have a roadmap for #77? I can take a swing at implementing it if you have a design in mind for the API

@kmaasrud
Copy link
Member

@MatteoJoliveau check out #104! It's still a work in progress, but you should get an idea of how I'm imagining the API to be. Feel free to leave any suggestions there, if you'd like 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants