{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveFunctor #-}

module Language.Ginger.BuiltinsAutodoc
where

import Control.Monad.Random (MonadRandom (..), RandomGen (..), random, randoms)
import Control.Monad.Identity (Identity, runIdentity)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Vector as Vector
import Language.Haskell.TH (getDoc, putDoc, DocLoc (..), DecsQ, runIO)

import Language.Ginger.Interpret
import Language.Ginger.Interpret.Builtins
    ( builtinGlobals
    , builtinGlobalsNonJinja
    , builtinBoolAttribs
    , builtinIntAttribs
    , builtinFloatAttribs
    , builtinStringAttribs
    , builtinListAttribs
    , builtinDictAttribs
    , BuiltinAttribs
    )
import Language.Ginger.Interpret.DefEnv
    ( builtinTests
    , builtinFilters
    )
import Language.Ginger.AST
import Language.Ginger.Value

newtype Document a = Document { forall a. Document a -> Identity a
unDocument :: Identity a }
  deriving ((forall a b. (a -> b) -> Document a -> Document b)
-> (forall a b. a -> Document b -> Document a) -> Functor Document
forall a b. a -> Document b -> Document a
forall a b. (a -> b) -> Document a -> Document b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Document a -> Document b
fmap :: forall a b. (a -> b) -> Document a -> Document b
$c<$ :: forall a b. a -> Document b -> Document a
<$ :: forall a b. a -> Document b -> Document a
Functor, Functor Document
Functor Document =>
(forall a. a -> Document a)
-> (forall a b. Document (a -> b) -> Document a -> Document b)
-> (forall a b c.
    (a -> b -> c) -> Document a -> Document b -> Document c)
-> (forall a b. Document a -> Document b -> Document b)
-> (forall a b. Document a -> Document b -> Document a)
-> Applicative Document
forall a. a -> Document a
forall a b. Document a -> Document b -> Document a
forall a b. Document a -> Document b -> Document b
forall a b. Document (a -> b) -> Document a -> Document b
forall a b c.
(a -> b -> c) -> Document a -> Document b -> Document c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> Document a
pure :: forall a. a -> Document a
$c<*> :: forall a b. Document (a -> b) -> Document a -> Document b
<*> :: forall a b. Document (a -> b) -> Document a -> Document b
$cliftA2 :: forall a b c.
(a -> b -> c) -> Document a -> Document b -> Document c
liftA2 :: forall a b c.
(a -> b -> c) -> Document a -> Document b -> Document c
$c*> :: forall a b. Document a -> Document b -> Document b
*> :: forall a b. Document a -> Document b -> Document b
$c<* :: forall a b. Document a -> Document b -> Document a
<* :: forall a b. Document a -> Document b -> Document a
Applicative, Applicative Document
Applicative Document =>
(forall a b. Document a -> (a -> Document b) -> Document b)
-> (forall a b. Document a -> Document b -> Document b)
-> (forall a. a -> Document a)
-> Monad Document
forall a. a -> Document a
forall a b. Document a -> Document b -> Document b
forall a b. Document a -> (a -> Document b) -> Document b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b. Document a -> (a -> Document b) -> Document b
>>= :: forall a b. Document a -> (a -> Document b) -> Document b
$c>> :: forall a b. Document a -> Document b -> Document b
>> :: forall a b. Document a -> Document b -> Document b
$creturn :: forall a. a -> Document a
return :: forall a. a -> Document a
Monad)

runDocument :: Document a -> a
runDocument :: forall a. Document a -> a
runDocument = Identity a -> a
forall a. Identity a -> a
runIdentity (Identity a -> a) -> (Document a -> Identity a) -> Document a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Document a -> Identity a
forall a. Document a -> Identity a
unDocument

data MockGen = MockGen

instance RandomGen MockGen where
  genWord64 :: MockGen -> (Word64, MockGen)
genWord64 MockGen
g = (Word64
0, MockGen
g)
  genWord32 :: MockGen -> (Word32, MockGen)
genWord32 MockGen
g = (Word32
0, MockGen
g)
  split :: MockGen -> (MockGen, MockGen)
split MockGen
g = (MockGen
g, MockGen
g)

instance MonadRandom Document where
  getRandomR :: forall a. Random a => (a, a) -> Document a
getRandomR (a
a, a
_) = a -> Document a
forall a. a -> Document a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
  getRandomRs :: forall a. Random a => (a, a) -> Document [a]
getRandomRs (a
a, a
_) = [a] -> Document [a]
forall a. a -> Document a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> Document [a]) -> [a] -> Document [a]
forall a b. (a -> b) -> a -> b
$ a -> [a]
forall a. a -> [a]
repeat a
a
  getRandom :: forall a. Random a => Document a
getRandom = a -> Document a
forall a. a -> Document a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Document a)
-> ((a, MockGen) -> a) -> (a, MockGen) -> Document a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, MockGen) -> a
forall a b. (a, b) -> a
fst ((a, MockGen) -> Document a) -> (a, MockGen) -> Document a
forall a b. (a -> b) -> a -> b
$ MockGen -> (a, MockGen)
forall g. RandomGen g => g -> (a, g)
forall a g. (Random a, RandomGen g) => g -> (a, g)
random MockGen
MockGen
  getRandoms :: forall a. Random a => Document [a]
getRandoms = [a] -> Document [a]
forall a. a -> Document a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> Document [a]) -> [a] -> Document [a]
forall a b. (a -> b) -> a -> b
$ MockGen -> [a]
forall g. RandomGen g => g -> [a]
forall a g. (Random a, RandomGen g) => g -> [a]
randoms MockGen
MockGen

markdownToHaddock :: Text -> Text
markdownToHaddock :: Text -> Text
markdownToHaddock =
  HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
Text.replace Text
"'" Text
"\\'" (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
Text.replace Text
"\"" Text
"\\\"" (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
Text.replace Text
"`" Text
"@" (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
Text.replace Text
"```" Text
"@"

addHaddockFromFile :: FilePath -> DecsQ
addHaddockFromFile :: String -> DecsQ
addHaddockFromFile String
path = do
  src <- IO String -> Q String
forall a. IO a -> Q a
runIO (IO String -> Q String) -> IO String -> Q String
forall a b. (a -> b) -> a -> b
$ String -> IO String
readFile String
path
  doc <- fromMaybe "" <$> getDoc ModuleDoc
  putDoc ModuleDoc $ doc ++ src
  pure []

extractAttribs :: Monoid a
               => BuiltinAttribs a Document
               -> [(Identifier, Value Document)]
extractAttribs :: forall a.
Monoid a =>
BuiltinAttribs a Document -> [(Identifier, Value Document)]
extractAttribs =
  a -> BuiltinAttribs a Document -> [(Identifier, Value Document)]
forall a.
a -> BuiltinAttribs a Document -> [(Identifier, Value Document)]
extractAttribsWith a
forall a. Monoid a => a
mempty

extractAttribsWith :: a
                   -> BuiltinAttribs a Document
                   -> [(Identifier, Value Document)]
extractAttribsWith :: forall a.
a -> BuiltinAttribs a Document -> [(Identifier, Value Document)]
extractAttribsWith a
dummy =
  Map Identifier (Value Document) -> [(Identifier, Value Document)]
forall k a. Map k a -> [(k, a)]
Map.toAscList (Map Identifier (Value Document) -> [(Identifier, Value Document)])
-> (BuiltinAttribs a Document -> Map Identifier (Value Document))
-> BuiltinAttribs a Document
-> [(Identifier, Value Document)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  ((a -> Document (Either RuntimeError (Value Document)))
 -> Value Document)
-> BuiltinAttribs a Document -> Map Identifier (Value Document)
forall a b. (a -> b) -> Map Identifier a -> Map Identifier b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (
    (RuntimeError -> Value Document)
-> (Value Document -> Value Document)
-> Either RuntimeError (Value Document)
-> Value Document
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Value Document
forall a. HasCallStack => String -> a
error (String -> Value Document)
-> (RuntimeError -> String) -> RuntimeError -> Value Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuntimeError -> String
forall a. Show a => a -> String
show) Value Document -> Value Document
forall a. a -> a
id (Either RuntimeError (Value Document) -> Value Document)
-> ((a -> Document (Either RuntimeError (Value Document)))
    -> Either RuntimeError (Value Document))
-> (a -> Document (Either RuntimeError (Value Document)))
-> Value Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    Document (Either RuntimeError (Value Document))
-> Either RuntimeError (Value Document)
forall a. Document a -> a
runDocument (Document (Either RuntimeError (Value Document))
 -> Either RuntimeError (Value Document))
-> ((a -> Document (Either RuntimeError (Value Document)))
    -> Document (Either RuntimeError (Value Document)))
-> (a -> Document (Either RuntimeError (Value Document)))
-> Either RuntimeError (Value Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    ((a -> Document (Either RuntimeError (Value Document)))
-> a -> Document (Either RuntimeError (Value Document))
forall a b. (a -> b) -> a -> b
$ a
dummy)
  )

builtinsAutodoc :: DecsQ
builtinsAutodoc :: DecsQ
builtinsAutodoc = do
  doc <- String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
"" (Maybe String -> String) -> Q (Maybe String) -> Q String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DocLoc -> Q (Maybe String)
getDoc DocLoc
ModuleDoc
  putDoc ModuleDoc $
    doc ++
    "\n\n== __List Of Builtin Globals__\n" ++
    "\nThese are available in Jinja, and work (mostly) the same in Ginger.\n" ++
    unlines (map (goItem Nothing "globals_jinja_") (Map.toAscList $ builtinGlobals evalE)) ++

    "\n\n== __List Of Extension Globals__\n" ++
    "\nThese are not available in Jinja\n" ++
    unlines (map (goItem Nothing "globals_ginger_") (Map.toAscList $ builtinGlobalsNonJinja evalE)) ++

    "\n\n== __List Of Builtin Attributes__\n" ++
    "\n\n=== Bool\n" ++
    unlines
      (map
        (goItem (Just "bool") "globals_bool_")
        (extractAttribsWith False builtinBoolAttribs)) ++
    "\n\n=== Int\n" ++
    unlines
      (map
        (goItem (Just "int") "globals_int_")
        (extractAttribsWith 0 builtinIntAttribs)) ++
    "\n\n=== Float\n" ++
    unlines
      (map
        (goItem (Just "float") "globals_float_")
        (extractAttribsWith 0 builtinFloatAttribs)) ++
    "\n\n=== String\n" ++
    unlines
      (map
        (goItem (Just "string") "globals_string_")
        (extractAttribs builtinStringAttribs)) ++
    "\n\n=== List\n" ++
    unlines
      (map
        (goItem (Just "list") "globals_list_")
        (extractAttribs builtinListAttribs)) ++
    "\n\n=== Dict\n" ++
    unlines
      (map
        (goItem (Just "dict") "globals_dict_")
        (extractAttribs builtinDictAttribs)) ++

    "\n\n== __List Of Builtin Filters__\n" ++
    "\nThese will only work in a filter context, not via procedure call syntax.\n" ++
    unlines (map (goItem Nothing "filters_") (Map.toAscList $ builtinFilters)) ++

    "\n\n== __List Of Builtin Tests__\n" ++
    "\nThese will only work in a test context (e.g., an @is@-expression).\n\n" ++
    "\nSome of these tests shadow globals of the same name but different functionality.\n\n" ++
    unlines (map (goItem Nothing "tests_") (Map.toAscList $ builtinTests))
  pure []
  where
    goTy :: TypeDoc -> Text
    goTy :: TypeDoc -> Text
goTy TypeDoc
TypeDocAny = Text
"any"
    goTy TypeDoc
TypeDocNone = Text
"none"
    goTy (TypeDocSingle Text
t) = Text
t
    goTy (TypeDocAlternatives Vector Text
ts) =
      Text
"[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
Text.intercalate Text
" | " (Vector Text -> [Text]
forall a. Vector a -> [a]
Vector.toList (Vector Text -> [Text]) -> Vector Text -> [Text]
forall a b. (a -> b) -> a -> b
$ Vector Text
ts) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]"

    goItemHeading :: Maybe Text -> Text -> Text -> [Text]
    goItemHeading :: Maybe Text -> Text -> Text -> [Text]
goItemHeading Maybe Text
namespaceMay Text
prefix Text
name =
        [ Text
""
        , Text
"#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".") Maybe Text
namespaceMay Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"#"
        , Text
""
        , Text
"=== " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".") Maybe Text
namespaceMay Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name
        ]

    goArgSig :: ArgumentDoc -> Text
    goArgSig :: ArgumentDoc -> Text
goArgSig ArgumentDoc
arg =
      ArgumentDoc -> Text
argumentDocName ArgumentDoc
arg Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
      Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text
"=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (ArgumentDoc -> Maybe Text
argumentDocDefault ArgumentDoc
arg) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
      Text -> (TypeDoc -> Text) -> Maybe TypeDoc -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" ((Text
" : " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (TypeDoc -> Text) -> TypeDoc -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeDoc -> Text
goTy) (ArgumentDoc -> Maybe TypeDoc
argumentDocType ArgumentDoc
arg)

    goArgDesc :: ArgumentDoc -> [Text]
    goArgDesc :: ArgumentDoc -> [Text]
goArgDesc ArgumentDoc
arg =
      [ Text
"[@" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ArgumentDoc -> Text
argumentDocName ArgumentDoc
arg Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"@]:" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ArgumentDoc -> Text
argumentDocDescription ArgumentDoc
arg ]

    goDocumentedItem :: Maybe Text -> Text -> (Identifier, ProcedureDoc) -> String
    goDocumentedItem :: Maybe Text -> Text -> (Identifier, ProcedureDoc) -> String
goDocumentedItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureDoc
d) =
      let qualifiedName :: Text
qualifiedName = Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".") Maybe Text
namespaceMay Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Identifier -> Text
identifierName Identifier
name
      in
        Text -> String
Text.unpack (Text -> String) -> ([Text] -> Text) -> [Text] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
Text.unlines ([Text] -> String) -> [Text] -> String
forall a b. (a -> b) -> a -> b
$
          Maybe Text -> Text -> Text -> [Text]
goItemHeading Maybe Text
namespaceMay Text
prefix
            (Identifier -> Text
identifierName Identifier
name)
            [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
          [ Text
""
          , Text
"@" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Identifier -> Text
identifierName Identifier
name
                Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Text -> [Text] -> Text
Text.intercalate Text
", " ([Text] -> Text)
-> (Vector ArgumentDoc -> [Text]) -> Vector ArgumentDoc -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ArgumentDoc -> Text) -> [ArgumentDoc] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ArgumentDoc -> Text
goArgSig ([ArgumentDoc] -> [Text])
-> (Vector ArgumentDoc -> [ArgumentDoc])
-> Vector ArgumentDoc
-> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector ArgumentDoc -> [ArgumentDoc]
forall a. Vector a -> [a]
Vector.toList (Vector ArgumentDoc -> Text) -> Vector ArgumentDoc -> Text
forall a b. (a -> b) -> a -> b
$ ProcedureDoc -> Vector ArgumentDoc
procedureDocArgs ProcedureDoc
d) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
                Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> (TypeDoc -> Text) -> Maybe TypeDoc -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" ((Text
" → " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> (TypeDoc -> Text) -> TypeDoc -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeDoc -> Text
goTy) (ProcedureDoc -> Maybe TypeDoc
procedureDocReturnType ProcedureDoc
d)
                Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"@"
          , Text
""
          ]
            [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
          ( if Text
qualifiedName Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= ProcedureDoc -> Text
procedureDocName ProcedureDoc
d Bool -> Bool -> Bool
&&
               Identifier -> Text
identifierName Identifier
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= ProcedureDoc -> Text
procedureDocName ProcedureDoc
d then
              [ Text
"Alias for [" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ProcedureDoc -> Text
procedureDocName ProcedureDoc
d Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"](#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ProcedureDoc -> Text
procedureDocName ProcedureDoc
d Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
              ]
            else
              ( if Vector ArgumentDoc -> Bool
forall a. Vector a -> Bool
Vector.null (ProcedureDoc -> Vector ArgumentDoc
procedureDocArgs ProcedureDoc
d) then
                  [ ]
                else
                  [ Text
""
                  , Text
"==== Arguments"
                  , Text
""
                  ] [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
                  ((ArgumentDoc -> [Text]) -> [ArgumentDoc] -> [Text]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ArgumentDoc -> [Text]
goArgDesc ([ArgumentDoc] -> [Text])
-> (Vector ArgumentDoc -> [ArgumentDoc])
-> Vector ArgumentDoc
-> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector ArgumentDoc -> [ArgumentDoc]
forall a. Vector a -> [a]
Vector.toList (Vector ArgumentDoc -> [Text]) -> Vector ArgumentDoc -> [Text]
forall a b. (a -> b) -> a -> b
$ ProcedureDoc -> Vector ArgumentDoc
procedureDocArgs ProcedureDoc
d) [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
                  [ Text
"" ]
              ) [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
              [ Text
""
              , Text -> Text
markdownToHaddock (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ ProcedureDoc -> Text
procedureDocDescription ProcedureDoc
d
              ]
          )

    goItem :: Maybe Text -> Text -> (Identifier, Value Document) -> String
    goItem :: Maybe Text -> Text -> (Identifier, Value Document) -> String
goItem Maybe Text
namespaceMay Text
prefix (Identifier
name, DictV Map Scalar (Value Document)
subitems) =
      let qualifiedName :: Text
qualifiedName = Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".") Maybe Text
namespaceMay Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Identifier -> Text
identifierName Identifier
name
          heading :: String
heading = Text -> String
Text.unpack (Text -> String) -> ([Text] -> Text) -> [Text] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
Text.unlines ([Text] -> String) -> [Text] -> String
forall a b. (a -> b) -> a -> b
$
                      [ Text
""
                      , Text
"=== Module \\'" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
qualifiedName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\\'"
                      ]
      in
        String
heading String -> String -> String
forall a. [a] -> [a] -> [a]
++
        [String] -> String
unlines
          [ Maybe Text -> Text -> (Identifier, Value Document) -> String
goItem (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
qualifiedName) Text
prefix (Text -> Identifier
Identifier Text
k, Value Document
v)
          | (StringScalar Text
k, Value Document
v) <- Map Scalar (Value Document) -> [(Scalar, Value Document)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map Scalar (Value Document)
subitems
          ]

    goItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureV (NativeProcedure ObjectID
_ (Just ProcedureDoc
d) [(Maybe Identifier, Value Document)]
-> Context Document
-> Document (Either RuntimeError (Value Document))
_)) =
      Maybe Text -> Text -> (Identifier, ProcedureDoc) -> String
goDocumentedItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureDoc
d)
    goItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureV Procedure Document
NamespaceProcedure) =
      Maybe Text -> Text -> (Identifier, ProcedureDoc) -> String
goDocumentedItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureDoc
namespaceProcedureDoc)
    goItem Maybe Text
namespaceMay Text
prefix (Identifier
name, FilterV (NativeFilter (Just ProcedureDoc
d) FilterFunc Document
_)) =
      Maybe Text -> Text -> (Identifier, ProcedureDoc) -> String
goDocumentedItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureDoc
d)
    goItem Maybe Text
namespaceMay Text
prefix (Identifier
name, TestV (NativeTest (Just ProcedureDoc
d) TestFunc Document
_)) =
      Maybe Text -> Text -> (Identifier, ProcedureDoc) -> String
goDocumentedItem Maybe Text
namespaceMay Text
prefix (Identifier
name, ProcedureDoc
d)
    goItem Maybe Text
namespaceMay Text
prefix (Identifier
name, Value Document
_) =
      Text -> String
Text.unpack (Text -> String) -> ([Text] -> Text) -> [Text] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
Text.unlines ([Text] -> String) -> [Text] -> String
forall a b. (a -> b) -> a -> b
$
        Maybe Text -> Text -> Text -> [Text]
goItemHeading Maybe Text
namespaceMay Text
prefix (Identifier -> Text
identifierName Identifier
name)