aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/gen_html_docs.clj
diff options
context:
space:
mode:
authorStuart Sierra <mail@stuartsierra.com>2010-01-20 15:39:56 -0500
committerStuart Sierra <mail@stuartsierra.com>2010-01-20 15:39:56 -0500
commit2ede388a9267d175bfaa7781ee9d57532eb4f20f (patch)
treebb42002af196405d7e25cc4e30b4c1c9de5c06d5 /src/clojure/contrib/gen_html_docs.clj
parent1bc820d96048a6536706ff999e9892649b53c700 (diff)
Move source files into Maven-style directory structure.
Diffstat (limited to 'src/clojure/contrib/gen_html_docs.clj')
-rw-r--r--src/clojure/contrib/gen_html_docs.clj539
1 files changed, 0 insertions, 539 deletions
diff --git a/src/clojure/contrib/gen_html_docs.clj b/src/clojure/contrib/gen_html_docs.clj
deleted file mode 100644
index 364d4279..00000000
--- a/src/clojure/contrib/gen_html_docs.clj
+++ /dev/null
@@ -1,539 +0,0 @@
-;;; gen-html-docs.clj: Generate HTML documentation for Clojure libs
-
-;; by Craig Andera, http://pluralsight.com/craig, candera@wangdera.com
-;; February 13th, 2009
-
-;; Copyright (c) Craig Andera, 2009. All rights reserved. The use
-;; and distribution terms for this software are covered by the Eclipse
-;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
-;; which can be found in the file epl-v10.html at the root of this
-;; distribution. By using this software in any fashion, you are
-;; agreeing to be bound by the terms of this license. You must not
-;; remove this notice, or any other, from this software.
-
-;; Generates a single HTML page that contains the documentation for
-;; one or more Clojure libraries. See the comments section at the end
-;; of this file for usage.
-
-;; TODO
-;;
-;; * Make symbols in the source hyperlinks to the appropriate section
-;; of the documentation.
-;; * Investigate issue with miglayout mentioned here:
-;; http://groups.google.com/group/clojure/browse_thread/thread/5a0c4395e44f5a79/3ae483100366bd3d?lnk=gst&q=documentation+browser#3ae483100366bd3d
-;;
-;; DONE
-;;
-;; * Move to clojure.contrib
-;; * Change namespace
-;; * Change license as appropriate
-;; * Double-check doc strings
-;; * Remove doc strings from source code
-;; * Add collapse/expand functionality for all namespaces
-;; * Add collapse/expand functionality for each namespace
-;; * See if converting to use clojure.contrib.prxml is possible
-;; * Figure out why the source doesn't show up for most things
-;; * Add collapsible source
-;; * Add links at the top to jump to each namespace
-;; * Add object type (var, function, whatever)
-;; * Add argument lists for functions
-;; * Add links at the top of each namespace to jump to members
-;; * Add license statement
-;; * Remove the whojure dependency
-
-(ns
- #^{:author "Craig Andera",
- :doc "Generates a single HTML page that contains the documentation for
-one or more Clojure libraries."}
- clojure.contrib.gen-html-docs
- (:require [clojure.contrib.duck-streams :as duck-streams])
- (:use [clojure.contrib seq-utils str-utils repl-utils def prxml])
- (:import [java.lang Exception]
- [java.util.regex Pattern]))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Doc generation constants
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(def *script* " // <![CDATA[
-
-function getElem(id)
-{
- if( document.getElementById )
- {
- return document.getElementById( id )
- }
- else if ( document.all )
- {
- return eval( 'document.all.' + id )
- }
- else
- return false;
-}
-
-function setDisplayStyle(id,displayStyle)
-{
- var elem = getElem (id)
- if (elem)
- {
- elem.style.display = displayStyle
- }
-
-}
-
-function setLinkToggleText (id, text)
-{
- var elem = getElem (id)
- if (elem)
- {
- elem.innerHTML = text
- }
-}
-
-function collapse(id)
-{
- setDisplayStyle (id, 'none')
-}
-
-function expand (id)
-{
- setDisplayStyle (id, 'block')
-}
-
-function toggleSource( id )
-{
- toggle(id, 'linkto-' + id, 'Hide Source', 'Show Source')
-}
-
-function toggle(targetid, linkid, textWhenOpen, textWhenClosed)
-{
- var elem = getElem (targetid)
- var link = getElem (linkid)
-
- if (elem && link)
- {
- var isOpen = false
- if (elem.style.display == '')
- {
- isOpen = link.innerHTML == textWhenOpen
- }
- else if( elem.style.display == 'block' )
- {
- isOpen = true
- }
-
- if (isOpen)
- {
- elem.style.display = 'none'
- link.innerHTML = textWhenClosed
- }
- else
- {
- elem.style.display = 'block'
- link.innerHTML = textWhenOpen
- }
- }
-}
-
- //]]>
-")
-
-(def *style* "
-.library
-{
- padding: 0.5em 0 0 0
-}
-.all-libs-toggle,.library-contents-toggle
-{
- font-size: small;
-}
-.all-libs-toggle a,.library-contents-toggle a
-{
- color: white
-}
-.library-member-doc-whitespace
-{
- white-space: pre
-}
-.library-member-source-toggle
-{
- font-size: small;
- margin-top: 0.5em
-}
-.library-member-source
-{
- display: none;
- border-left: solid lightblue
-}
-.library-member-docs
-{
- font-family:monospace
-}
-.library-member-arglists
-{
- font-family: monospace
-}
-.library-member-type
-{
- font-weight: bold;
- font-size: small;
- font-style: italic;
- color: darkred
-}
-.lib-links
-{
- margin: 0 0 1em 0
-}
-
-.lib-link-header
-{
- color: white;
- background: darkgreen;
- width: 100%
-}
-
-.library-name
-{
- color: white;
- background: darkblue;
- width: 100%
-}
-
-.missing-library
-{
- color: darkred;
- margin: 0 0 1em 0
-}
-
-.library-members
-{
- list-style: none
-}
-
-.library-member-name
-{
- font-weight: bold;
- font-size: 105%
-}")
-
-(defn- extract-documentation
- "Pulls the documentation for a var v out and turns it into HTML"
- [v]
- (if-let [docs (:doc (meta v))]
- (map
- (fn [l]
- [:div {:class "library-member-doc-line"}
- (if (= 0 (count l))
- [:span {:class "library-member-doc-whitespace"} " "] ; We need something here to make the blank line show up
- l)])
- (re-split #"\n" docs))
- ""))
-
-(defn- member-type
- "Figures out for a var x whether it's a macro, function, var or multifunction"
- [x]
- (try
- (let [dx (deref x)]
- (cond
- (:macro (meta x)) :macro
- (fn? dx) :fn
- (= clojure.lang.MultiFn (:tag (meta x))) :multi
- true :var))
- (catch Exception e
- :unknown)))
-
-(defn- anchor-for-member
- "Returns a suitable HTML anchor name given a library id and a member
- id"
- [libid memberid]
- (str "member-" libid "-" memberid))
-
-(defn- id-for-member-source
- "Returns a suitable HTML id for a source listing given a library and
- a member"
- [libid memberid]
- (str "membersource-" libid "-" memberid))
-
-(defn- id-for-member-source-link
- "Returns a suitable HTML id for a link to a source listing given a
- library and a member"
- [libid memberid]
- (str "linkto-membersource-" libid "-" memberid))
-
-(defn- symbol-for
- "Given a namespace object ns and a namespaceless symbol memberid
- naming a member of that namespace, returns a namespaced symbol that
- identifies that member."
- [ns memberid]
- (symbol (name (ns-name ns)) (name memberid)))
-
-(defn- elide-to-one-line
- "Elides a string down to one line."
- [s]
- (re-sub #"(\n.*)+" "..." s))
-
-(defn- elide-string
- "Returns a string that is at most the first limit characters of s"
- [s limit]
- (if (< (- limit 3) (count s))
- (str (subs s 0 (- limit 3)) "...")
- s))
-
-(defn- doc-elided-src
- "Returns the src with the docs elided."
- [docs src]
- (re-sub (re-pattern (str "\"" (Pattern/quote docs) "\""))
- (str "\""
- (elide-to-one-line docs)
-;; (elide-string docs 10)
-;; "..."
- "\"")
- src))
-
-(defn- format-source [libid memberid v]
- (try
- (let [docs (:doc (meta v))
- src (if-let [ns (find-ns libid)]
- (get-source (symbol-for ns memberid)))]
- (if (and src docs)
- (doc-elided-src docs src)
- src))
- (catch Exception ex
- nil)))
-
-(defn- generate-lib-member [libid [n v]]
- [:li {:class "library-member"}
- [:a {:name (anchor-for-member libid n)}]
- [:dl {:class "library-member-table"}
- [:dt {:class "library-member-name"}
- (str n)]
- [:dd
- [:div {:class "library-member-info"}
- [:span {:class "library-member-type"} (name (member-type v))]
- " "
- [:span {:class "library-member-arglists"} (str (:arglists (meta v)))]]
- (into [:div {:class "library-member-docs"}] (extract-documentation v))
- (let [member-source-id (id-for-member-source libid n)
- member-source-link-id (id-for-member-source-link libid n)]
- (if-let [member-source (format-source libid n v)]
- [:div {:class "library-member-source-section"}
- [:div {:class "library-member-source-toggle"}
- "[ "
- [:a {:href (format "javascript:toggleSource('%s')" member-source-id)
- :id member-source-link-id} "Show Source"]
- " ]"]
- [:div {:class "library-member-source" :id member-source-id}
- [:pre member-source]]]))]]])
-
-(defn- anchor-for-library
- "Given a symbol id identifying a namespace, returns an identifier
-suitable for use as the name attribute of an HTML anchor tag."
- [id]
- (str "library-" id))
-
-(defn- generate-lib-member-link
- "Emits a hyperlink to a member of a namespace given libid (a symbol
-identifying the namespace) and the vector [n v], where n is the symbol
-naming the member in question and v is the var pointing to the
-member."
- [libid [n v]]
- [:a {:class "lib-member-link"
- :href (str "#" (anchor-for-member libid n))} (name n)])
-
-(defn- anchor-for-library-contents
- "Returns an HTML ID that identifies the element that holds the
-documentation contents for the specified library."
- [lib]
- (str "library-contents-" lib))
-
-(defn- anchor-for-library-contents-toggle
- "Returns an HTML ID that identifies the element that toggles the
-visibility of the library contents."
- [lib]
- (str "library-contents-toggle-" lib))
-
-(defn- generate-lib-doc
- "Emits the HTML that documents the namespace identified by the
-symbol lib."
- [lib]
- [:div {:class "library"}
- [:a {:name (anchor-for-library lib)}]
- [:div {:class "library-name"}
- [:span {:class "library-contents-toggle"}
- "[ "
- [:a {:id (anchor-for-library-contents-toggle lib)
- :href (format "javascript:toggle('%s', '%s', '-', '+')"
- (anchor-for-library-contents lib)
- (anchor-for-library-contents-toggle lib))}
- "-"]
- " ] "]
- (name lib)]
- (let [ns (find-ns lib)]
- (if ns
- (let [lib-members (sort (ns-publics ns))]
- [:a {:name (anchor-for-library lib)}]
- [:div {:class "library-contents" :id (anchor-for-library-contents lib)}
- (into [:div {:class "library-member-links"}]
- (interpose " " (map #(generate-lib-member-link lib %) lib-members)))
- (into [:ol {:class "library-members"}]
- (map #(generate-lib-member lib %) lib-members))])
- [:div {:class "missing-library library-contents" :id (anchor-for-library-contents lib)} "Could not load library"]))])
-
-(defn- load-lib
- "Calls require on the library identified by lib, eating any
-exceptions."
- [lib]
- (try
- (require lib)
- (catch java.lang.Exception x
- nil)))
-
-(defn- generate-lib-link
- "Generates a hyperlink to the documentation for a namespace given
-lib, a symbol identifying that namespace."
- [lib]
- (let [ns (find-ns lib)]
- (if ns
- [:a {:class "lib-link" :href (str "#" (anchor-for-library lib))} (str (ns-name ns))])))
-
-(defn- generate-lib-links
- "Generates the list of hyperlinks to each namespace, given libs, a
-vector of symbols naming namespaces."
- [libs]
- (into [:div {:class "lib-links"}
- [:div {:class "lib-link-header"} "Namespaces"
- [:span {:class "all-libs-toggle"}
- " [ "
- [:a {:href "javascript:expandAllNamespaces()"}
- "Expand All"]
- " ] [ "
- [:a {:href "javascript:collapseAllNamespaces()"}
- "Collapse All"]
- " ]"]]]
- (interpose " " (map generate-lib-link libs))))
-
-(defn generate-toggle-namespace-script
- [action toggle-text lib]
- (str (format "%s('%s');\n" action (anchor-for-library-contents lib))
- (format "setLinkToggleText('%s', '%s');\n" (anchor-for-library-contents-toggle lib) toggle-text)))
-
-(defn generate-all-namespaces-action-script
- [action toggle-text libs]
- (str (format "function %sAllNamespaces()" action)
- \newline
- "{"
- \newline
- (reduce str (map #(generate-toggle-namespace-script action toggle-text %) libs))
- \newline
- "}"))
-
-(defn generate-documentation
- "Returns a string which is the HTML documentation for the libraries
-named by libs. Libs is a vector of symbols identifying Clojure
-libraries."
- [libs]
- (dorun (map load-lib libs))
- (let [writer (new java.io.StringWriter)]
- (binding [*out* writer]
- (prxml
- [:html {:xmlns "http://www.w3.org/1999/xhtml"}
- [:head
- [:title "Clojure documentation browser"]
- [:style *style*]
- [:script {:language "JavaScript" :type "text/javascript"} [:raw! *script*]]
-
- [:script {:language "JavaScript" :type "text/javascript"}
- [:raw! "// <![CDATA[!" \newline]
- (generate-all-namespaces-action-script "expand" "-" libs)
- (generate-all-namespaces-action-script "collapse" "+" libs)
- [:raw! \newline "// ]]>"]]]
- (let [lib-vec (sort libs)]
- (into [:body (generate-lib-links lib-vec)]
- (map generate-lib-doc lib-vec)))]))
- (.toString writer)))
-
-
-(defn generate-documentation-to-file
- "Calls generate-documentation on the libraries named by libs and
-emits the generated HTML to the path named by path."
- [path libs]
- (duck-streams/spit path (generate-documentation libs)))
-
-(comment
- (generate-documentation-to-file
- "C:/TEMP/CLJ-DOCS.HTML"
- ['clojure.contrib.accumulators])
-
- (defn gen-all-docs []
- (generate-documentation-to-file
- "C:/temp/clj-libs.html"
- [
- 'clojure.set
- 'clojure.main
- 'clojure.core
- 'clojure.zip
- 'clojure.xml
- 'clojure.contrib.accumulators
- 'clojure.contrib.apply-macro
- 'clojure.contrib.auto-agent
- 'clojure.contrib.combinatorics
- 'clojure.contrib.command-line
- 'clojure.contrib.complex-numbers
- 'clojure.contrib.cond
- 'clojure.contrib.def
- 'clojure.contrib.duck-streams
- 'clojure.contrib.enum
- 'clojure.contrib.error-kit
- 'clojure.contrib.except
- 'clojure.contrib.fcase
- 'clojure.contrib.generic
- 'clojure.contrib.generic.arithmetic
- 'clojure.contrib.generic.collection
- 'clojure.contrib.generic.comparison
- 'clojure.contrib.generic.functor
- 'clojure.contrib.generic.math-functions
- 'clojure.contrib.import-static
- 'clojure.contrib.javadoc
- 'clojure.contrib.javalog
- 'clojure.contrib.lazy-seqs
- 'clojure.contrib.lazy-xml
- 'clojure.contrib.macro-utils
- 'clojure.contrib.macros
- 'clojure.contrib.math
- 'clojure.contrib.miglayout
- 'clojure.contrib.mmap
- 'clojure.contrib.monads
- 'clojure.contrib.ns-utils
- 'clojure.contrib.prxml
- 'clojure.contrib.repl-ln
- 'clojure.contrib.repl-utils
- 'clojure.contrib.seq-utils
- 'clojure.contrib.server-socket
- 'clojure.contrib.shell-out
- 'clojure.contrib.sql
- 'clojure.contrib.stream-utils
- 'clojure.contrib.str-utils
- 'clojure.contrib.test-contrib
- 'clojure.contrib.trace
- 'clojure.contrib.types
- 'clojure.contrib.zip-filter
- 'clojure.contrib.javadoc.browse
- 'clojure.contrib.json.read
- 'clojure.contrib.json.write
- 'clojure.contrib.lazy-xml.with-pull
- 'clojure.contrib.miglayout.internal
- 'clojure.contrib.probabilities.finite-distributions
- 'clojure.contrib.probabilities.monte-carlo
- 'clojure.contrib.probabilities.random-numbers
- 'clojure.contrib.sql.internal
- 'clojure.contrib.test-clojure.evaluation
- 'clojure.contrib.test-clojure.for
- 'clojure.contrib.test-clojure.numbers
- 'clojure.contrib.test-clojure.printer
- 'clojure.contrib.test-clojure.reader
- 'clojure.contrib.test-clojure.sequences
- 'clojure.contrib.test-contrib.shell-out
- 'clojure.contrib.test-contrib.str-utils
- 'clojure.contrib.zip-filter.xml
- ]))
- )