 
 (defmacro defkey
   "Define one or more keys as vars using argument vectors. Every argument vector must have one of the following arities:
+
+  ```
   [key]
   [key options]
   [key validator description]
   [key validator description options]
-  See `make-key` for details. First argument to `defkey` can optionally be a base option-map for all argument vectors.
-  Examples:
+  ```
+
+  The `validator` is a predicate fn `(fn [parsed-value])->boolean` that returns true for valid values, false otherwise.
+
+  See [[make-key]] for options. First argument to `defkey` can optionally be a base option-map for all argument vectors.
+
+  ## Examples
+
+  ```
   (defkey
     ip   [:ip-address]
     port [:port #(< 1023 % 65535) \"Server port\" {:parser str->int :default 3000}])
+
   (defkey
     {:lookup lookup-key}
     ip   [\"server.ip.address\"]
     port [\"server.port\" #(< 1023 % 65535) \"Server port\" {:parser str->int :default 3000}])
-  See: make-key"
+  ```
+
+  See: [[make-key]]"
   [the-sym arg-vec & more]
   (let [options (if (odd? (count more))
                   (i/expect-arg the-sym map? ["Expected an option map, found" (pr-str the-sym)])



(defn lookup-keypath
  "Look up a key path in an associative data structure - Java map or something that implements clojure.lang.Associative."
  [the-map ks validator description value-parser default-value? default-value not-found]
  (let [value (loop [data the-map
                     path ks]



(defn lookup-key
  "Look up a key in an associative data structure - a map or something that implements `clojure.lang.Associative`."
  [the-map the-key validator description value-parser default-value? default-value not-found]
  (when-not (or (instance? Map the-map)
              (instance? Associative the-map))
