nextjournal 2025-05-08

Hey friends, I have another question about Markdown. How do you deal with https://frontmatter.codes/docs? If I have some .markdown with some metadata and I want to turn it into a hiccup (to later combine with template and render as html), e.g.,

---
template: article
title: My Article
layout: with-sidebar
partial: false
---

# This is some kind of content
While typing this question I found https://github.com/liquidz/frontmatter/blob/master/src/frontmatter/core.clj old tiny lib — I think I'm just gonna copy the code and use it. Or maybe there is a better approach? Perhaps with some options passed into nextjournal.markdown.transform/->hiccup?

I do this:

(def yaml-frontmatter
  #"^---\n((?:\s|.)+?)---")

(defn yaml->map
  "Convert `yaml` kvs to a Clojure map."
  [yaml]
  (into {} (for [line (str/split yaml #"\n")]
             (let [[k v] (str/split (str/trim line) #":\s")]
               [(keyword k) v]))))

;; usage
(let [[frontmatter yaml] (re-find yaml-frontmatter markdown)]
  (yaml->map yaml))

I don't want yaml tho, I want edn there instead

➕ 1

I guess manual parsing it is then

yeah, turns out - it was far easier than I expected. I shouldn't have wasted anyone's attention and time. Still, thank you for your help.

Of course cjohansen has tread this path before, here's a whole library for this https://github.com/magnars/mapdown

magnars isn't cjohansen although they work together

😱 how embarrassing. of course, I know that hah, sorry for the mistake

Having never met them and because of parens of the dead I think of them as an inseparable duo.

Also cjohansen has built powerpack off of many magnars libs

I recently met both of them in London

just ran across this, this is how I implemented edn frontmatter:

(defn parse-edn-frontmatter
  [lines-seq]
  (if (re-matches #"\{.*" (or (first lines-seq) ""))
    ;; take sequences until you hit an empty line
    (let [meta-lines (take-while (comp not (partial re-matches #"\s*"))
                                 lines-seq)]
      [(->> meta-lines
            ;; join together and parse
            (str/join "\n")
            edn/read-string)
       ;; count the trailing empty line
       (inc (count meta-lines))])
    [nil 0]))
(based it off of yogthos' https://github.com/yogthos/markdown-clj/blob/473411d12c5a98e27b3bf0e035184dbb1f50f785/src/cljc/markdown/transformers.cljc#L375-L390)

makes sense!