Pulling out the form parse logic into multimethods to provide a finer level of per-form parse control. This would also form the hook that others can use to provide their own parsing.

This commit is contained in:
fogus 2011-01-18 12:54:43 -05:00
parent 78b8b4c0f1
commit b4d55c409c
4 changed files with 64 additions and 80 deletions

View file

@ -1,4 +1,4 @@
(defproject marginalia "0.3.2"
(defproject marginalia "0.5.0-alpha"
:description "lightweight literate programming for clojure -- inspired by [docco](http://jashkenas.github.com/docco/)"
:main marginalia.core
:eval-in-leiningen true
@ -13,7 +13,7 @@
;;Needed for testing lein plugin
[hiccup "0.3.0"]
[org.markdownj/markdownj "0.3.0-1.0.2b4"]
[marginalia "0.3.2"]]
[marginalia "0.5.0-alpha"]]
;;Needed for testing cake plugin
:tasks [marginalia.tasks]
;;Needed for testing Latex equation formatting. You must download

View file

@ -117,59 +117,6 @@
:else (recur (merge-line (first lines) cur-group) groups (rest lines)))))
;; Hacktastic, these ad-hoc checks should be replaced with something
;; more robust.
(defn docstring-line? [line sections]
(let [l (last sections)
last-code-text (get l :code-text "")]
(try
(or
;; Last line contain defn &&
;; last line not contain what looks like a param vector &&
;; current line start with a quote
(and (re-find #"\(defn" last-code-text)
(not (re-find #"\[.*\]" last-code-text))
(re-find #"^\"" (str/trim (str line))))
;; Is the last line's code-text a deftask, and does the
;; current line start with a quote?
(and (re-find #"^\(deftask" (str/trim last-code-text))
(re-find #"^\"" (str/trim (str line))))
;; Is the last line's code-text the start of a ns
;; decl, and does the current line start with a quote?
(and (re-find #"^\(ns" last-code-text)
(re-find #"^\"" (str/trim (str line))))
;; Is the last line's code-text the start of a defprotocol,
;; and does the current line start with a quote?
(and (re-find #"^\(defprotocol" last-code-text)
(re-find #"^\"" (str/trim (str line))))
;; Is the last line's code-text the start of a defmulti,
;; and does the current line start with a quote?
(and (re-find #"^\(defmulti" last-code-text)
(re-find #"^\"" (str/trim (str line))))
;; Is the last line's code-text the start of a defmethod,
;; and does the current line start with a quote?
(and (re-find #"^\(defmethod" last-code-text)
(re-find #"^\"" (str/trim (str line))))
;; Is the last line's code-text the start of a defmacro,
;; and does the current line start with a quote?
(and (re-find #"^\(defmacro" last-code-text)
(re-find #"^\"" (str/trim (str line))))
;;
(and (re-find #".*\[this" last-code-text)
(re-find #"^\"" (str/trim (str line))))
;; Is the prev line a docstring, prev line not end with a quote,
;; and the current line empty?
(and (:docstring-text l)
(not (re-find #"\"$" (str/trim (:docstring-text l)))))
;; Is the prev line a docstring, the prev line not end with a quote,
;; and the current line not an empty string?
(and (:docstring-text l)
(not (re-find #"[^\\]\"$" (str/trim (:docstring-text l))))
(= "" (str/trim (str line)))))
(catch Exception e nil))))
(re-find *comment* " ;; this is a comment")
(defn path-to-doc [fn]
(let [ns (-> (java.io.File. fn)
(read-file-ns-decl)
@ -230,7 +177,7 @@
(uberdoc! (str *docs* "/" file) sources (parse-project-file))
(println "Done generating your documentation, please see"
(str *docs* "/" file))
(println))))))
(println ""))))))
(defn -main
"The main entry point into Marginalia."

View file

@ -61,20 +61,56 @@
;; HACK: to handle types
(catch Exception _)))
(defmulti dispatch-form (fn [form _ _] (first form)))
(defn- extract-common-docstring
[form raw nspace-sym]
(let [sym (-> form second)
_ (when-not nspace-sym (require sym))
nspace (find-ns sym)]
(let [docstring (if nspace
(-> nspace meta :doc)
(get-var-docstring nspace-sym sym))]
[docstring
(strip-docstring docstring raw)
(if nspace sym nspace-sym)])))
(defmethod dispatch-form 'def
[form raw nspace-sym]
(extract-common-docstring form raw nspace-sym))
(defmethod dispatch-form 'defn
[form raw nspace-sym]
(extract-common-docstring form raw nspace-sym))
(defmethod dispatch-form 'ns
[form raw nspace-sym]
(extract-common-docstring form raw nspace-sym))
(defmethod dispatch-form 'defprotocol
[form raw nspace-sym]
;; this needs some work to extract embedded docstrings
(extract-common-docstring form raw nspace-sym))
(defmethod dispatch-form 'defmulti
[form raw nspace-sym]
(extract-common-docstring form raw nspace-sym))
(defmethod dispatch-form 'defmethod
[form raw nspace-sym]
(let [ds (nth form 4)
docstring (when (string? ds) ds)]
[docstring
(strip-docstring docstring raw)
nspace-sym]))
(defmethod dispatch-form :default [_ raw nspace-sym]
[nil raw nspace-sym])
(defn extract-docstring [m raw nspace-sym]
(let [raw (join "\n" (subvec raw (-> m :start dec) (:end m)))
form (:form m)]
(if (re-find #"^(def|ns)" (-> form first name))
(let [sym (-> form second)
_ (when-not nspace-sym (require sym))
nspace (find-ns sym)]
(let [docstring (if nspace
(-> nspace meta :doc)
(get-var-docstring nspace-sym sym))]
[docstring
(strip-docstring docstring raw)
(if nspace sym nspace-sym)]))
[nil raw nspace-sym])))
(dispatch-form form raw nspace-sym)))
(defn- ->str [m]
(replace (-> m :form .content) #"^;+\s*" ""))

View file

@ -6,7 +6,7 @@
;; Should have only this comment in the left margin.
;; See [https://github.com/fogus/marginalia/issues/#issue/4](https://github.com/fogus/marginalia/issues/#issue/4)
(defn parse-bool [v] (condp = (.trim (text v))
(defn parse-bool [v] (condp = (.trim (str v))
"0" false
"1" true
"throw exception here"))
@ -66,15 +66,16 @@
; Define single-character indicator rules.
; I use `clojure.template/do-template` to reduce repetition.
(do-template [rule-name token]
(h/defrule rule-name
"Padded on the front with optional whitespace."
(h/lit token))
<escape-char-start> \\
<str-delimiter> \"
<value-separator> \,
<name-separator> \:
<array-start> \[
<array-end> \]
<object-start> \{
<object-end> \})
(comment
(do-template [rule-name token]
(h/defrule rule-name
"Padded on the front with optional whitespace."
(h/lit token))
<escape-char-start> \\
<str-delimiter> \"
<value-separator> \,
<name-separator> \:
<array-start> \[
<array-end> \]
<object-start> \{
<object-end> \}))