Hi Christophe, hi list, I really like clojure.contrib.javadoc; I've wanted something like this for a while. But I wanted it to work for other packages besides the core Java API, so this patch (attached) does that. It also works for both local and remote Javadoc files. What do you think? In the process, I separated the web-browser functions into a separate lib, since those might be useful elsewhere.
-Stuart Sierra --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
Index: src/clojure/contrib/javadoc.clj =================================================================== --- src/clojure/contrib/javadoc.clj (revision 268) +++ src/clojure/contrib/javadoc.clj (working copy) @@ -6,44 +6,69 @@ ; the terms of this license. ; You must not remove this notice, or any other, from this software. -; a repl helper to quickly open JDK javadocs. +; a repl helper to quickly open javadocs. -(ns clojure.contrib.javadoc) +(ns clojure.contrib.javadoc + (:use clojure.contrib.browse) + (:import (java.io File))) -(defn- open-url-in-browser [url] - (try - (when (clojure.lang.Reflector/invokeStaticMethod "java.awt.Desktop" - "isDesktopSupported" (to-array nil)) - (-> (clojure.lang.Reflector/invokeStaticMethod "java.awt.Desktop" - "getDesktop" (to-array nil)) - (.browse (java.net.URI. url))) - url) - (catch ClassNotFoundException e - nil))) - -(defn- open-url-in-swing [url] - (let [htmlpane (javax.swing.JEditorPane. url)] - (.setEditable htmlpane false) - (.addHyperlinkListener htmlpane - (proxy [javax.swing.event.HyperlinkListener] [] - (hyperlinkUpdate [#^javax.swing.event.HyperlinkEvent e] - (when (= (.getEventType e) (. javax.swing.event.HyperlinkEvent$EventType ACTIVATED)) - (if (instance? javax.swing.text.html.HTMLFrameHyperlinkEvent e) - (-> htmlpane .getDocument (.processHTMLFrameHyperlinkEvent e)) - (.setPage htmlpane (.getURL e))))))) - (doto (javax.swing.JFrame.) - (setContentPane (javax.swing.JScrollPane. htmlpane)) - (setBounds 32 32 700 900) - (show)))) +(def + #^{:doc "Ref to a list of local paths for Javadoc-generated HTML + files."} + *local-javadocs* (ref (list))) +(def *core-java-api* + "http://java.sun.com/javase/6/docs/api/") + +(def + #^{:doc "Ref to a map from package name prefixes to URLs for remote + Javadocs."} + *remote-javadocs* + (ref (sorted-map + "java." *core-java-api* + "javax." *core-java-api* + "org.ietf.jgss." *core-java-api* + "org.omg." *core-java-api* + "org.w3c.dom." *core-java-api* + "org.xml.sax." *core-java-api* + "org.apache.commons.codec." "http://commons.apache.org/codec/api-release/" + "org.apache.commons.io." "http://commons.apache.org/io/api-release/" + "org.apache.commons.lang." "http://commons.apache.org/lang/api-release/"))) + +(defn add-local-javadoc + "Adds to the list of local Javadoc paths." + [path] + (dosync (commute *local-javadocs* conj path))) + +(defn add-remote-javadoc + "Adds to the list of remote Javadoc URLs. package-prefix is the + beginning of the package name that has docs at this URL." + [package-prefix url] + (dosync (commute *remote-javadocs* assoc package-prefix url))) + +(defn find-javadoc-url + "Searches for a URL for the given class name. Tries + *local-javadocs* first, then *remote-javadocs*. Returns a string." + [classname] + (let [path (.replace classname \. File/separatorChar)] + (if-let [file (first + (filter #(.exists %) + (map #(File. % (str path ".html")) + @*local-javadocs*)))] + (str "file://" (.getAbsolutePath file)) + ;; If no local file, try remote URLs: + (some (fn [[prefix url]] + (when (.startsWith classname prefix) + (str url path ".html"))) + @*remote-javadocs*)))) + (defn javadoc - "Opens a browser window displaying the javadoc for the argument." - [class-or-object] + "Opens a browser window displaying the javadoc for the argument. + Tries *local-javadocs* first, then *remote-javadocs*." + [class-or-object] (let [c (if (instance? Class class-or-object) class-or-object - (class class-or-object)) - url (str "http://java.sun.com/javase/6/docs/api/" - (-> c .getName (.replace \. \/) (.replace \$ \.)) - ".html")] - (or (open-url-in-browser url) (open-url-in-swing url)))) - + (class class-or-object))] + (if-let [url (find-javadoc-url (.getName c))] + (browse-url url) + (println "Could not find Javadoc for" c)))) Index: src/clojure/contrib/browse.clj =================================================================== --- src/clojure/contrib/browse.clj (revision 0) +++ src/clojure/contrib/browse.clj (revision 0) @@ -0,0 +1,43 @@ +;;; browse.clj -- start a web browser from Clojure; requires Java 6 + +; Copyright (c) Christophe Grand, December 2008. All rights reserved. +; The use and distribution terms for this software are covered by the +; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) +; which can be found in the file CPL.TXT 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. + + +(ns clojure.contrib.browse + (:import (java.awt Desktop) + (java.net URI))) + +(defn open-url-in-browser + "Opens url (a string) in the default system web browser. May not + work on all platforms. Returns url on success, nil if not + supported." + [url] + (when (Desktop/isDesktopSupported) + (.browse (Desktop/getDesktop) (URI. url)) + url)) + +(defn open-url-in-swing + "Opens url (a string) in a Swing window." + [url] + (let [htmlpane (javax.swing.JEditorPane. url)] + (.setEditable htmlpane false) + (.addHyperlinkListener htmlpane + (proxy [javax.swing.event.HyperlinkListener] [] + (hyperlinkUpdate [#^javax.swing.event.HyperlinkEvent e] + (when (= (.getEventType e) (. javax.swing.event.HyperlinkEvent$EventType ACTIVATED)) + (if (instance? javax.swing.text.html.HTMLFrameHyperlinkEvent e) + (-> htmlpane .getDocument (.processHTMLFrameHyperlinkEvent e)) + (.setPage htmlpane (.getURL e))))))) + (doto (javax.swing.JFrame.) + (.setContentPane (javax.swing.JScrollPane. htmlpane)) + (.setBounds 32 32 700 900) + (.show)))) + +(defn browse-url [url] + (or (open-url-in-browser url) (open-url-in-swing url)))