diff --git a/src/cryogen_core/compiler.clj b/src/cryogen_core/compiler.clj
index bb54d7f..2d8a15e 100644
--- a/src/cryogen_core/compiler.clj
+++ b/src/cryogen_core/compiler.clj
@@ -86,7 +86,8 @@
(update-in page-meta [:layout] #(str (name %) ".html"))
{:file-name file-name
:content content
- :toc (if (:toc page-meta) (generate-toc content))}))
+ :toc (if-let [toc (:toc page-meta)]
+ (generate-toc content :list-type toc))}))
(defn parse-page
"Parses a page/post and returns a map of the content, uri, date etc."
diff --git a/src/cryogen_core/toc.clj b/src/cryogen_core/toc.clj
index f576ccc..0230d75 100644
--- a/src/cryogen_core/toc.clj
+++ b/src/cryogen_core/toc.clj
@@ -18,6 +18,7 @@
headings)))
[] content))
+
(defn make-links
"Create a table of contents from the given headings. This function will look
for either:
@@ -27,26 +28,39 @@
(2) headings with an id attribute, e.g.
Reference Title
In both cases above, the anchor reference becomes \"#reference\" and the
anchor text is \"Reference Title\"."
- [headings]
- (loop [items headings acc nil _last nil]
+ [headings li-tags]
+ (let [[li-open li-close] li-tags]
+ (loop [items headings acc nil _last nil]
(if-let [{tag :tag {id :id} :attrs [{{name :name} :attrs} title :as htext] :content} (first items)]
(let [anchor (or id name)]
(if (nil? anchor)
(recur (rest items) acc nil)
(let [entry [:li [:a {:href (str "#" anchor)} (or title (first htext))]]
jump (compare_index _last tag)]
- (cond (> jump 0) (recur (rest items) (str acc "" (hiccup/html entry)) tag)
+ (cond (> jump 0) (recur (rest items) (str acc li-open (hiccup/html entry)) tag)
(= jump 0) (recur (rest items) (str acc (hiccup/html entry)) tag)
- (< jump 0) (recur (rest items) (str acc (apply str (repeat (* -1 jump) "
"))
+ (< jump 0) (recur (rest items) (str acc (apply str (repeat (* -1 jump) li-close))
(hiccup/html entry)) tag)))))
- (str acc ""))))
+ (str acc li-close)))))
-(defn generate-toc [^String html]
- (-> html
- (.getBytes "UTF-8")
- (java.io.ByteArrayInputStream.)
- (html/parse)
- :content
- (get-headings)
- (make-links)
- (clojure.string/replace-first #"ol" "ol class=\"contents\"")))
+
+(def _list-types {true ["" "
"] :ol ["" "
"] :ul [""]})
+(defn generate-toc [^String html & {list-type :list-type :or {list-type true}}]
+ "Reads an HTML string and parses it for headers, then returns a list of links
+ to them.
+
+ Optionally, a map of :list-type can be provided with value :ul, :ol, or true.
+ :ol and true will result in an ordered list being generated for the table of
+ contents, while :ul will result in an unordered list. The default is an
+ ordered list."
+ (let [li-tags (list-type _list-types)
+ top-tag (li-tags -> first (subs 1 3))]
+ (-> html
+ (.getBytes "UTF-8")
+ (java.io.ByteArrayInputStream.)
+ (html/parse)
+ :content
+ (get-headings)
+ (make-links li-tags)
+ (clojure.string/replace-first
+ (re-pattern top-tag) (str top-tag "class=\"contents\"")))))