(var docs (set sibilant 'docs { definitions []
                                undocumented {} }))

(def docs.record (type namespace name node)
     (var doc docs.last-doc)
     (if (defined? doc)
         (do
          (delete (get sibilant.docs.undocumented name))
          (sibilant.docs.definitions.push (merge-into doc { name name
                                                            type type
                                                            namespace namespace
                                                            definition node })))
         (set sibilant.docs.undocumented name true))
     (delete sibilant.docs.last-doc))

(def docs.tags ()
     (var tags (|> docs.definitions (pluck 'tags) flatten)
          counts {})
     (each tag tags
           (set counts tag (|> counts (get tag) (or 0) (+ 1))))
     counts)





(def docs.text ()
     (|> docs.definitions
         (.sort (#(a b)
                  (.locale-compare
                   (prettify a.name false)
                   (prettify b.name false))))

         (.map (#(definition)
                 (concat
                  "name: " definition.type " " definition.namespace "/" (prettify definition.name) "\n"
                  "description: " definition.doc-string "\n"
                  (if definition.references
                      ("references:\n  " (|> definition.references
                                             (.map (#-> transpile output-formatter eval))
                                             (.join "\n  ")
                                             (concat "\n")))
                      "")

                  (if definition.tags
                      ("tags: " (join definition.tags ", ") "\n")
                      "")

                  "arguments: " (|> definition.definition.contents third prettify) "\n"
                  
                  "examples: \n" (|> definition.examples (or [])
                                     (.map (#> (concat
                                                (prettify #0 true) "\n"
                                                (|> #0 transpile output-formatter))))
                                     (.join "\n\n"))
                  "\n\n")))
         join))

(def docs.text-no-color ()
     (require! strip-ansi "strip-ansi")
     (|> (docs.text)
         strip-ansi))

(def docs.json ()
     (JSON.stringify (docs.data)))

(def docs.data ()
     (docs.definitions.map
      (#(definition)
        { name (prettify definition.name false)
          namespace definition.namespace
          type definition.type
          description definition.doc-string
          references (if definition.references
                         (definition.references.map (#-> (get 'token) (.slice 1 -1)))
                         [])
          arguments (|> definition.definition.contents
                        third
                        (get 'contents)
                        (.map (#-> (prettify false))))
          definition (prettify definition.definition false)
          examples (|> definition.examples (or [])
                       (.map (#>
                              { javascript (pipe #0 transpile output-formatter)
                                sibilant (prettify #0 false) })))
          tags: definition.tags
          })))
