The renderer is responsible for converting parsed contents into html files. It uses clostache templates from a selectable theme folder to create them.
(ns sidenotes.renderer (:require [sidenotes.fs :as fs] [markdown.core :as md] [clojure.edn :as edn] [clojure.string :as string] [clostache.parser :as mustache]))
The folder where internal themes can be found.
(def theme-base "themes/")
The list of internal themes. It would be much nicer if this could be automatically read from the resources of the jar, but so far I have no idea how that could be done.
(def internal-themes ["marginalia" "sidenotes"])
Check that itm is not in itms.
(defn in? [itm itms] (not (false? (nil? (some #(= itm %) itms)))))
Check if an external theme is sane. It needs to have theme.edn, toc.html and ns.html files.
(defn external-theme-valid? [theme-name] (and (fs/dir? theme-name) (fs/file? (str theme-name "/theme.edn")) (fs/file? (str theme-name "/toc.html")) (fs/file? (str theme-name "/ns.html"))))
(def message-theme-invalid "The theme you have provided is not valid. Make sure that it contains the following files: theme.edn toc.html ns.html")
Check if the provided theme is external.
(defn external-theme? [theme-name] (in? theme-name internal-themes))
Find the path to the used theme.
(defn find-theme [theme-name] (if (external-theme? theme-name) theme-name (str theme-base theme-name)))
Transform a dependency so mustache can handle it.
(defn transform-dependency [dep] {:name (first dep) :is-mvn (not (nil? (:mvn/version (second dep)))) :version (:mvn/version (second dep)) :is-git (not (nil? (:git/url (second dep)))) :url (:git/url (second dep)) :sha (:sha (second dep))})
Transform the list of dependencies for mustache.
(defn transform-dependencies [deps] (map transform-dependency deps))
Get markdown for an error.
(defn error-md [section] (str "###ERROR\\n" (:error section)))
Convert stacktrace to code.
(defn stacktrace-code [exception] (string/join "\\n" (map str (.getStackTrace exception))))
Transform the comments and parse contained markdown.
(defn transform-section [section] (case (:type section) :error (assoc section :docstring (md/md-to-html-string (error-md section)) :raw (stacktrace-code (:exception section))) :code (assoc section :docstring (md/md-to-html-string (:docstring section)) :span false) :comment (assoc section :docstring (md/md-to-html-string (:raw section)) :raw "" :span true)))
Transform the comments and parse contained markdown.
(defn transform-parsed-source [parsed-source] (assoc parsed-source :sections (map transform-section (:sections parsed-source)) :is-cljs (= "cljs" (:type parsed-source)) :is-cljc (= "cljc" (:type parsed-source)) :is-clj (= "clj" (:type parsed-source))))
Check if a readme exists and contains markdown. If so convert it to html.
(defn transform-readme [readme] (if (and (:has-readme readme) (= "md" (:type readme))) (assoc readme :html (md/md-to-html-string (:content readme))) readme))
Build the parameters for the mustache templates.
(defn toc-template-parameters [parsed-sources project settings readme] {:settings settings :dependencies (transform-dependencies (:deps project)) :readme (transform-readme readme) :sources (map transform-parsed-source parsed-sources)})
Build the parameters for the mustache templates.
(defn ns-template-parameters [parsed-source project settings] {:settings settings :dependencies (transform-dependencies (:deps project)) :source (transform-parsed-source parsed-source)})
Render the table of contents.
(defn render-toc [parsed-sources project settings readme theme external] (let [toc-file (str theme "/toc.html") toc-template (if external (slurp toc-file) (fs/slurp-resource toc-file)) filename (str (:output-to settings) "/" (:toc-filename settings)) tmp (dorun (println (str "Creating table of contents: " filename))) params (toc-template-parameters parsed-sources project settings readme)] (spit filename (mustache/render toc-template params))))
Render the page for one namespace.
(defn render-ns [parsed-source project settings theme external] (let [ns-file (str theme "/ns.html") ns-template (if external (slurp ns-file) (fs/slurp-resource ns-file)) filename (str (:output-to settings) "/" (:ns parsed-source) ".html") tmp (dorun (println (str " ... rendering to " filename))) params (ns-template-parameters parsed-source project settings)] (spit filename (mustache/render ns-template params))))
Copy resources from theme to docs folder.
(defn copy-resources [settings theme external] (dorun (println "Copying resources:")) (dorun (map #(fs/spit-resource % theme (:output-to settings)) (:resources (edn/read-string (fs/slurp-resource (str theme "/theme.edn")))))))
Copy files from theme to docs folder.
(defn copy-files [settings theme external] (dorun (println "Copying resources:")) (dorun (map #(fs/copy-file % theme (:output-to settings)) (:resources (edn/read-string (slurp (str theme "/theme.edn")))))))
Render the documentation.
(defn render [parsed-sources project settings readme] (let [theme (find-theme (:theme settings)) external (external-theme? (:theme settings))] (dorun (map #(render-ns % project settings theme external) parsed-sources)) (render-toc parsed-sources project settings readme theme external) (if external (copy-files settings theme external) (copy-resources settings theme external))))