Skip to content

Commit

Permalink
[New] [weavejester#216] Add support for {:language :both} option (@…
Browse files Browse the repository at this point in the history
…ptaoussanis)

- This implementation attempts to be minimally invasive.
  Most of the logical changes are within `html/write-index` and
  `html/write-namespaces`, where a special path is introduced
  for "cross-platform" projects (= language `:both`).

- NO behavioural changes are intended for traditional
  (non-cross-platform) projects.

- See weavejester#216 for detailed feature discussion.
  • Loading branch information
ptaoussanis committed Jul 5, 2023
1 parent 37f4674 commit 621538f
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 28 deletions.
25 changes: 18 additions & 7 deletions codox/src/codox/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,24 @@
(filter #(some (partial ns-matches? %) ns-filters) namespaces)
namespaces))

(defn- cross-platform?
"Do given options indicate *both* Clojure and ClojureScript sources?"
[{:keys [language] :as opts}]
(= language :both))

(defn- read-namespaces
"Returns {<language> <namespace-seq>} for cross-platform opts,
or <namespace-seq> otherwise."
[{:keys [language root-path source-paths namespaces metadata exclude-vars] :as opts}]
(let [reader (namespace-readers language)]
(-> (reader source-paths (select-keys opts [:exception-handler]))
(filter-namespaces namespaces)
(remove-excluded-vars exclude-vars)
(add-source-paths root-path source-paths)
(add-ns-defaults metadata))))
(if (cross-platform? opts)
{:clojure (read-namespaces (assoc opts :language :clojure))
:clojurescript (read-namespaces (assoc opts :language :clojurescript))}
(let [reader (namespace-readers language)]
(-> (reader source-paths (select-keys opts [:exception-handler]))
(filter-namespaces namespaces)
(remove-excluded-vars exclude-vars)
(add-source-paths root-path source-paths)
(add-ns-defaults metadata)))))

(defn- read-documents [{:keys [doc-paths doc-files] :or {doc-files :all}}]
(cond
Expand Down Expand Up @@ -106,4 +116,5 @@
documents (read-documents options)]
(write-fn (assoc options
:namespaces namespaces
:documents documents)))))
:documents documents
:cross-platform? (cross-platform? options))))))
117 changes: 96 additions & 21 deletions codox/src/codox/writer/html.clj
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,18 @@
(if-let [doc (:doc metadata)]
(markdown-to-html doc project ns))])

(defn- language-fileext
[language]
(case language
:clojure ".clj"
:clojurescript ".cljs"
nil ""))

(defn- index-filename [language]
(str "index" (language-fileext language) ".html"))

(defn- ns-filename [namespace]
(str (:name namespace) ".html"))
(str (:name namespace) (language-fileext (:language namespace)) ".html"))

(defn- ns-filepath [output-dir namespace]
(str output-dir "/" (ns-filename namespace)))
Expand Down Expand Up @@ -241,6 +251,19 @@
[:li.depth-1 {:class (if on-index? "current")}
(link-to "index.html" [:div.inner "Index"])]]))

(defn- platform-links [project _current-doc]
(when (:show-platforms? project)
(let [{:keys [language]} project
clj-selected? (= language :clojure)
cljs-selected? (= language :clojurescript)]
(list
[:h3.no-link [:span.inner "Platforms"]]
[:ul.index-link
[:li.depth-1 {:class (when clj-selected? "current")}
(link-to (index-filename :clojure) [:div.inner "Clojure"])]
[:li.depth-1 {:class (when cljs-selected? "current")}
(link-to (index-filename :clojurescript) [:div.inner "ClojureScript"])]]))))

(defn- topics-menu [project current-doc]
(if-let [docs (seq (:documents project))]
(list
Expand Down Expand Up @@ -275,16 +298,18 @@
(get-in project [:html :namespace-list] default)))

(defn- namespaces-menu [project current-ns]
(let [namespaces (:namespaces project)]
(list
[:h3.no-link [:span.inner "Namespaces"]]
(case (namespace-list-type project)
:flat (flat-namespaces namespaces current-ns)
:nested (nested-namespaces namespaces current-ns)))))
(when (:show-namespaces? project)
(let [namespaces (:namespaces project)]
(list
[:h3.no-link [:span.inner "Namespaces"]]
(case (namespace-list-type project)
:flat (flat-namespaces namespaces current-ns)
:nested (nested-namespaces namespaces current-ns))))))

(defn- primary-sidebar [project & [current]]
[:div.sidebar.primary
(index-link project (nil? current))
(platform-links project current)
(topics-menu project current)
(namespaces-menu project current)])

Expand Down Expand Up @@ -360,16 +385,27 @@
[:ul.topics
(for [doc docs]
[:li (link-to (doc-filename doc) (h (:title doc)))])]))
[:h2 "Namespaces"]
(for [namespace (sort-by :name (:namespaces project))]
[:div.namespace
[:h3 (link-to (ns-filename namespace) (h (:name namespace)))]
[:div.doc (format-docstring project nil (update-in namespace [:doc] util/summary))]
[:div.index
[:p "Public variables and functions:"]
(unordered-list
(for [var (sorted-public-vars namespace)]
(list " " (link-to (var-uri namespace var) (h (:name var))) " ")))]])]]))

(when (:show-platforms? project)
(list
[:h2 "Platforms"]
[:p "This project includes both Clojure and ClojureScript code:"]
[:ul
[:li (link-to (index-filename :clojure) "Clojure")]
[:li (link-to (index-filename :clojurescript) "ClojureScript")]]))

(when (:show-namespaces? project)
(list
[:h2 "Namespaces"]
(for [namespace (sort-by :name (:namespaces project))]
[:div.namespace
[:h3 (link-to (ns-filename namespace) (h (:name namespace)))]
[:div.doc (format-docstring project nil (update-in namespace [:doc] util/summary))]
[:div.index
[:p "Public variables and functions:"]
(unordered-list
(for [var (sorted-public-vars namespace)]
(list " " (link-to (var-uri namespace var) (h (:name var))) " ")))]])))]]))

(defmulti format-document
"Format a document into HTML."
Expand Down Expand Up @@ -465,12 +501,51 @@
(.mkdirs (io/file output-dir dir))))

(defn- write-index [output-dir project]
(spit (io/file output-dir "index.html") (transform-html project (index-page project))))
(let [{:keys [namespaces cross-platform?]} project]

(when cross-platform?
;; Write an index file for each language
(doseq [language (keys namespaces)]
(let [namespaces (map #(assoc % :language language) (get namespaces language))
project
(assoc project
:namespaces namespaces
:language language
:show-platforms? true
:show-namespaces? true)]
(spit (io/file output-dir (index-filename language))
(transform-html project (index-page project))))))

;; Always write a main index file
(let [project (assoc project
:show-platforms? cross-platform?
:show-namespaces? (not cross-platform?))]
(spit (io/file output-dir (index-filename nil))
(transform-html project (index-page project))))))

(defn- write-namespaces [output-dir project]
(doseq [namespace (:namespaces project)]
(spit (ns-filepath output-dir namespace)
(transform-html project (namespace-page project namespace)))))
(let [{:keys [namespaces cross-platform?]} project]

(if cross-platform?
;; Write namespace files for each language
(doseq [language (keys namespaces)]
(let [namespaces (map #(assoc % :language language) (get namespaces language))]
(doseq [namespace namespaces]
(let [project (assoc project
:namespaces namespaces
:language language
:show-platforms? true
:show-namespaces? true)]
(spit (ns-filepath output-dir namespace)
(transform-html project (namespace-page project namespace)))))))

;; Write namespace files for only language
(doseq [namespace namespaces]
(let [project (assoc project
:show-platforms? false
:show-namespaces? true)]
(spit (ns-filepath output-dir namespace)
(transform-html project (namespace-page project namespace))))))))

(defn- write-documents [output-dir project]
(doseq [document (:documents project)]
Expand Down

0 comments on commit 621538f

Please sign in to comment.