Issues with latest Clerk, relative links, index
I'm attempting to convert the r2r essays to the latest clerk to use the new index.
Relative links in markdown fail
Relative links in the static build should be specified relative to the root address (like reality.mentat.org). When I include
;; Get started reading at the [Introduction](essays/reality/introduction).
from essays/reality/index.clj, the link tries to redirect to essays/reality/essays/reality/introduction, relative to the current page.
links fail without .clj
when I add a link to essays/reality/introduction or introduction or introduction.html, thinking of the final static build, Clerk doesn't figure out the file i mean. this all works if I link to introduction.md. But will that work in the final static build, with a rewrite?
Index
When I specify an index and click the index button at the top of the page, I don't go back to the index... I see
In prose blocks, for regular markdown links like [text](url) the url is passed as-is to the anchor href. In interactive mode, relative urls are routed to notebooks at such path (relative to project root) hence they need be valid fs paths.
If you output your links as markdown or html results, then you can use the helper
(clerk/doc-url fs-path) ;;=> valid href in both static and interactive mode
We're discussing in #451 how to conveniently convey the doc-url handling into markdown prose. If I recall correctly you wished for a way to customize the text to be rendered in the wiki-style links [[path/to/notebook]].
If you want something that works today :-) you can provide your own implementation of markdown links in terms of the viewer api (not so easy atm) to do something like:
;; Go to this [Introduction](doc:notebooks/rule_30.clj) what.
(defn handle-md-href [href]
(if (str/starts-with? href "doc:")
(clerk/doc-url (str/replace href "doc:" ""))
href)) ;; or whatever
(def md-viewer
(update viewer/markdown-viewer :transform-fn #(comp %2 %1)
(fn [wrapped-val]
(update wrapped-val :nextjournal/viewers viewer/add-viewers
[{:name :nextjournal.markdown/link
:transform-fn (viewer/into-markup #(vector :a (update (:attrs %) :href handle-md-href)))}]))))
(clerk/add-viewers! [md-viewer])
or even setup such viewer globally for the whole project.
When I specify an index a
Is that interactive mode or a static build? That looks like the default index is being taken (nextjournal.clerk.index) and it cannot infer the list of notebooks from your local deps.edn.
Now @mk is suggesting that what I propose above should be the default. Not even using a special notation, but reflect on the nature of the href used in links to decide if we pass it through doc-url. That could even supersede #451.
@zampino I actually don't keep my notebook list in deps.edn, but put the list inside user.clj and provide my own serve! and build! so that I can run either one from the REPL. If I put the exec-args inside of deps.edn then I'd have to duplicate the arguments to run things at the REPL.
Also I like (clerk/doc-url fs-path), BUT I can't figure out how to use that
;; in the flow of the document, in a comment like this
I tried to use clerk/md or clerk/htmlto build a string that injected an anchor tag, but I ended up always with an extra newline after the paragraph that I built with those methods.
So rewriting relative links to potentially go through doc-url sounds like a great solution to me.
@sritchie @zampino I have just started to try out clerk. It appears that I'm having the same issue with markdown notebooks and relative links between other markdown and/or clj notebooks.
Is there an appropriate test case(s) where this behavior could be added?
Thank you
With the latest clerk (42e15d2203fc93101e656985fee7f094002c512a) you can add it in user land like so:
;; # Markdown Links
(ns linking
(:require [nextjournal.clerk.viewer :as v]))
(defn ->doc-url [href]
(if (clojure.string/starts-with? href "/")
(v/doc-url (subs href 1))
href))
(def markdown-link-viewer
{:name :nextjournal.markdown/link
:transform-fn (v/into-markup (fn [node]
(vector :a (update (:attrs node) :href ->doc-url))))})
(def markdown+link-viewer
(update v/markdown-viewer :add-viewers v/add-viewers [markdown-link-viewer]))
(v/add-viewers! [markdown+link-viewer])
;; ## [Hello](/notebooks/rule_30.clj)
I've opted to only act on absolute links here but that can be changed of course.
the link tries to redirect to
essays/reality/essays/reality/introduction, relative to the current page.
What is even worse, there's different behaviour between serve! and build! when it comes to relative links:
- in
serve!, relative links are relative to the index - in
build!, relative links are relative to the current page
@borkdude @mk Any chance of having the same behaviour for relative links when using serve! and build!?