Skip to content

Instantly share code, notes, and snippets.

@shaunlebron
Created April 10, 2016 06:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shaunlebron/2165eff75ed6bab4f402b2f5d66f0b6b to your computer and use it in GitHub Desktop.
Save shaunlebron/2165eff75ed6bab4f402b2f5d66f0b6b to your computer and use it in GitHub Desktop.
(ns sitegen.markdown
(:require
[clojure.string :as string]
[planck.core :refer [file-seq slurp]]
[clojure.walk :refer [keywordize-keys]]))
(def ^:dynamic *filename*)
(defn error [msg]
(throw (str "markdown metadata error: " msg " - " *filename*)))
(defn meta-boundary? [line]
(= "---" line))
(defn find-content-start [lines]
(if (meta-boundary? (first lines))
(let [i (->> (map-indexed vector lines)
(rest)
(filter (comp meta-boundary? second))
(first)
(first))]
(when i ;; if closing boundary found, content starts on next line
(inc i)))
0))
(defn clean-value
[value]
(let [value (string/trim value)
dequoted (or (second (re-find #"^\"(.*)\"$" value))
(second (re-find #"^'(.*)'$" value)))]
(if dequoted
(string/trim dequoted)
value)))
(defn parse-meta-line [line]
(let [pattern #"^([a-zA-Z-_]+):(.*)"
[match key value] (re-find pattern line)]
(when-not match
(error (str "key/value line must follow pattern: " pattern)))
[key (clean-value value)]))
(defn parse-meta-lines [lines]
(reduce
(fn [result line]
(let [[key value] (parse-meta-line line)]
(when (contains? result key)
(error (str "duplicate key '" key)))
(assoc result key value)))
{} lines))
(defn get-meta [text]
(let [lines (string/split-lines text)
start-i (find-content-start lines)]
(when-not start-i
(error "metadata never closed"))
(if (zero? start-i)
{:text text}
{:meta (parse-meta-lines (subvec lines 1 (dec start-i)))
:text (string/join "\n" (subvec lines start-i))})))
(defn -main []
(doseq [f (file-seq "news")]
(when (string/ends-with? (:path f) ".md")
(let [filename (subs (:path f) (count "news/"))
{:keys [meta text]} (binding [*filename* filename]
(get-meta (slurp f)))]
(-> meta
keywordize-keys
(assoc :filename filename)
prn)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment