Submitting a feature request for the :toc to support both ordered and unordered lists by expanding the vocabulary of the existing :toc directive to include :ul and :ol

This commit is contained in:
Jeff Rabinowitz 2015-10-25 19:14:43 -04:00
parent b96a872654
commit 482700a311
2 changed files with 30 additions and 15 deletions

View file

@ -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."

View file

@ -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. <h1 id=\"reference\">Reference Title</h1>
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 "<ol>" (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) "</ol>"))
(< jump 0) (recur (rest items) (str acc (apply str (repeat (* -1 jump) li-close))
(hiccup/html entry)) tag)))))
(str acc "</ol>"))))
(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>" "</ol>"] :ol ["<ol>" "</ol>"] :ul ["<ul>" "</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\"")))))