feat: Gen help for options
This commit is contained in:
@@ -38,11 +38,15 @@
|
|||||||
(defn- render-p [block]
|
(defn- render-p [block]
|
||||||
(apply println (:content block)))
|
(apply println (:content block)))
|
||||||
|
|
||||||
|
(defn- render-description [depth {{:keys [described]} :arguments :as block}]
|
||||||
|
(printf "%s::\n" described)
|
||||||
|
(run! #(render* (inc depth) %) (:content block)))
|
||||||
|
|
||||||
(defn- render-section [depth {:keys [arguments] :as block}]
|
(defn- render-section [depth {:keys [arguments] :as block}]
|
||||||
(print (apply str (repeat (inc depth) \=))
|
(print (apply str (repeat (inc depth) \=))
|
||||||
(:title arguments)
|
(:title arguments)
|
||||||
"\n\n")
|
"\n\n")
|
||||||
(run! render-p (:content block))
|
(run! #(render* (inc depth) %) (:content block))
|
||||||
(println))
|
(println))
|
||||||
|
|
||||||
(defn- render* [depth block]
|
(defn- render* [depth block]
|
||||||
@@ -52,6 +56,8 @@
|
|||||||
(render-document-header depth block))
|
(render-document-header depth block))
|
||||||
:section (render-section depth block)
|
:section (render-section depth block)
|
||||||
:p (render-p block)
|
:p (render-p block)
|
||||||
|
:description (render-description depth block)
|
||||||
|
:<> (run! #(render* (inc depth) %) (apply concat (:content block)))
|
||||||
(throw (ex-info "no case" {:for (:context block)
|
(throw (ex-info "no case" {:for (:context block)
|
||||||
:block block}))))
|
:block block}))))
|
||||||
|
|
||||||
@@ -64,7 +70,10 @@
|
|||||||
[:section {:title "Name"}
|
[:section {:title "Name"}
|
||||||
[:p "sydnix - Inspect and operate upon the system."]]
|
[:p "sydnix - Inspect and operate upon the system."]]
|
||||||
[:section {:title "Synopsis"}
|
[:section {:title "Synopsis"}
|
||||||
[:p "*sydnix* [_COMMAND_]... [_OPTION_]... [_FILE_]..."]]])
|
[:p "*sydnix* [_COMMAND_]... [_OPTION_]... [_FILE_]..."]]
|
||||||
|
[:section {:title "Options"}
|
||||||
|
[:description {:described "*--flake=URI*"}
|
||||||
|
"UJri is a flake"]]])
|
||||||
|
|
||||||
(defn conform! [spec x]
|
(defn conform! [spec x]
|
||||||
(let [x' (s/conform spec x)]
|
(let [x' (s/conform spec x)]
|
||||||
@@ -72,6 +81,8 @@
|
|||||||
(throw (ex-info "invalid" (s/explain-data spec x)))
|
(throw (ex-info "invalid" (s/explain-data spec x)))
|
||||||
x')))
|
x')))
|
||||||
|
|
||||||
|
;; Currently unrelentingly recursive. We'll fix this if/when it bnecomes a
|
||||||
|
;; problem. Shame Clojure skimps out on general TCO. }:(
|
||||||
(defn render
|
(defn render
|
||||||
"Render an AsciiDoc block to `*out*`."
|
"Render an AsciiDoc block to `*out*`."
|
||||||
[block]
|
[block]
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
:or {required-args {}
|
:or {required-args {}
|
||||||
optional-args {}
|
optional-args {}
|
||||||
content-spec (s/* ::block)}}]
|
content-spec (s/* ::block)}}]
|
||||||
(s/and vector?
|
(s/and seqable?
|
||||||
(s/cat :context (s/and keyword? #{name})
|
(s/cat :context (s/and keyword? #{name})
|
||||||
:arguments (make-block-arguments required-args optional-args)
|
:arguments (make-block-arguments required-args optional-args)
|
||||||
:content content-spec)
|
:content content-spec)
|
||||||
@@ -35,13 +35,23 @@
|
|||||||
(make-block :name :p
|
(make-block :name :p
|
||||||
:content-spec (s/* string?)))
|
:content-spec (s/* string?)))
|
||||||
|
|
||||||
|
(s/def ::description
|
||||||
|
(make-block :name :description
|
||||||
|
:required-opts {:described string?}))
|
||||||
|
|
||||||
(s/def ::section
|
(s/def ::section
|
||||||
(make-block :name :section
|
(make-block :name :section
|
||||||
:required-args {:title string?}))
|
:required-args {:title string?}))
|
||||||
|
|
||||||
|
(s/def ::<>
|
||||||
|
(make-block :name :<>
|
||||||
|
:content (s/coll-of ::block)))
|
||||||
|
|
||||||
(s/def ::block
|
(s/def ::block
|
||||||
(s/and (s/or :document ::document
|
(s/and (s/or :document ::document
|
||||||
:section ::section
|
:section ::section
|
||||||
|
:description ::description
|
||||||
|
:<> ::<>
|
||||||
:p ::p)
|
:p ::p)
|
||||||
;; `s/or` provides tagging that `make-block` already does.
|
;; `s/or` provides tagging that `make-block` already does.
|
||||||
(s/conformer #(nth % 1))))
|
(s/conformer #(nth % 1))))
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
(defn- find-dispatched [dispatch]
|
(defn- find-dispatched [dispatch]
|
||||||
(find-satisfying #(= dispatch (:cmds %)) *cli-table*))
|
(find-satisfying #(= dispatch (:cmds %)) *cli-table*))
|
||||||
|
|
||||||
|
(defn- format-p [s]
|
||||||
|
(-> s
|
||||||
|
(str/replace #"^ +" " ")
|
||||||
|
(str/replace #"\n +" "\n")))
|
||||||
|
|
||||||
(defn- docs-for-command [command-spec]
|
(defn- docs-for-command [command-spec]
|
||||||
(let [command (cons "sydnix" (:cmds command-spec))]
|
(let [command (cons "sydnix" (:cmds command-spec))]
|
||||||
[:document {:title (str (str/join "-" command)
|
[:document {:title (str (str/join "-" command)
|
||||||
@@ -29,13 +34,20 @@
|
|||||||
[:section {:title "Synopsis"}
|
[:section {:title "Synopsis"}
|
||||||
[:p (format "%s [_option_…]"
|
[:p (format "%s [_option_…]"
|
||||||
(str/join " " command))]]
|
(str/join " " command))]]
|
||||||
[:section {:title "Options"}
|
(concat [:section {:title "Options"}]
|
||||||
[:p "synopsis"]]]))
|
(for [[opt opt-spec] (:spec command-spec)]
|
||||||
|
[:description {:described (format "*--%s%s*"
|
||||||
|
(name opt)
|
||||||
|
(if-let [ref (:ref opt-spec)]
|
||||||
|
(str "=" ref)
|
||||||
|
""))}
|
||||||
|
[:p (format-p (:desc opt-spec))]]))]))
|
||||||
|
|
||||||
(defn- render-docs-for-command [command-spec]
|
(defn- render-docs-for-command [command-spec]
|
||||||
(try (ar/render (docs-for-command command-spec))
|
(try (ar/render (docs-for-command command-spec))
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(prn e)
|
(prn e)
|
||||||
|
(s/explain :asciidoc.types/document command-spec)
|
||||||
(throw e))))
|
(throw e))))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user