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:
parent
78b8b4c0f1
commit
b4d55c409c
4 changed files with 64 additions and 80 deletions
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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*" ""))
|
||||
|
|
|
@ -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> \}))
|
||||
|
|
Loading…
Reference in a new issue