    {-# LANGUAGE LambdaCase        #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RankNTypes        #-}
    {- |
       Module      : Text.Pandoc.Lua.Documentation
       Copyright   : Copyright © 2026 Albert Krewinkel
       License     : GPL-2.0-or-later
       Maintainer  : Albert Krewinkel <albert+pandoc@tarleb.com>

    Render Lua documentation
    -}
    module Text.Pandoc.Lua.Documentation
      ( renderDocumentation
      ) where

    import Data.Default (def)
    import Data.List (intersperse)
    import Data.Sequence (Seq ((:|>)))
    import Data.Version (showVersion)
    import HsLua as Lua
    import Text.Pandoc.Class (runPure)
    import Text.Pandoc.Definition (Pandoc (Pandoc))
    import Text.Pandoc.Extensions (extensionsFromList, Extension (..))
    import Text.Pandoc.Options (ReaderOptions (readerExtensions))
    import Text.Pandoc.Readers (readCommonMark)
    import Text.Pandoc.Shared (compactify)
    import Text.Pandoc.Walk (walk)

    import qualified Data.Text as T
    import qualified Text.Pandoc.Builder as B
    import qualified Text.Pandoc.UTF8 as UTF8

    -- | Render the documentation object as pandoc Blocks
    renderDocumentation :: DocumentationObject -> B.Blocks
    renderDocumentation :: DocumentationObject -> Blocks
    renderDocumentation = \case
      DocObjectFunction FunctionDoc
    fn -> Maybe Text -> FunctionDoc -> Blocks
    renderFunctionDoc Maybe Text
    forall a. Maybe a
    Nothing FunctionDoc
    fn
      DocObjectModule ModuleDoc
    mdl  -> ModuleDoc -> Blocks
    renderModuleDoc ModuleDoc
    mdl
      DocObjectType TypeDoc
    tp     -> Maybe Text -> TypeDoc -> Blocks
    renderTypeDoc Maybe Text
    forall a. Maybe a
    Nothing TypeDoc
    tp

    renderTypeDoc :: Maybe T.Text -> TypeDoc -> B.Blocks
    renderTypeDoc :: Maybe Text -> TypeDoc -> Blocks
    renderTypeDoc Maybe Text
    mbmodname TypeDoc
    td = [Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat
      [ Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    ident, [], []) Int
    1 (Text -> Inlines
    B.str (Text -> Inlines) -> Text -> Inlines
    forall a b. (a -> b) -> a -> b
    $ TypeDoc -> Text
    typeDocName TypeDoc
    td)
      , Text -> Blocks
    parseCommonMark (Text -> Blocks) -> Text -> Blocks
    forall a b. (a -> b) -> a -> b
    $ TypeDoc -> Text
    typeDocDescription TypeDoc
    td
      , if [FunctionDoc] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([FunctionDoc] -> Bool) -> [FunctionDoc] -> Bool
    forall a b. (a -> b) -> a -> b
    $ TypeDoc -> [FunctionDoc]
    typeDocMethods TypeDoc
    td
        then Blocks
    forall a. Monoid a => a
    mempty
        else
          Int -> Inlines -> Blocks
    B.header Int
    2 Inlines
    "Methods" Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <>
          (Int -> Blocks -> Blocks
    shiftHeadings Int
    2 (Blocks -> Blocks)
    -> ([FunctionDoc] -> Blocks) -> [FunctionDoc] -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat ([Blocks] -> Blocks)
    -> ([FunctionDoc] -> [Blocks]) -> [FunctionDoc] -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FunctionDoc -> Blocks) -> [FunctionDoc] -> [Blocks]
    forall a b. (a -> b) -> [a] -> [b]
    map (Maybe Text -> FunctionDoc -> Blocks
    renderFunctionDoc Maybe Text
    forall a. Maybe a
    Nothing) ([FunctionDoc] -> Blocks) -> [FunctionDoc] -> Blocks
    forall a b. (a -> b) -> a -> b
    $
           TypeDoc -> [FunctionDoc]
    typeDocMethods TypeDoc
    td)
      ]
     where
      ident :: Text
    ident = case Maybe Text
    mbmodname of
        Just Text
    modname  -> [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat [ Text
    "type-", Text
    modname, Text
    ".", TypeDoc -> Text
    typeDocName TypeDoc
    td ]
        Maybe Text
    Nothing       -> [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat [ Text
    "type-", TypeDoc -> Text
    typeDocName TypeDoc
    td ]

    -- Shift headings
    shiftHeadings :: Int -> B.Blocks -> B.Blocks
    shiftHeadings :: Int -> Blocks -> Blocks
    shiftHeadings Int
    incr Blocks
    blks = ((Block -> Block) -> Blocks -> Blocks)
    -> Blocks -> (Block -> Block) -> Blocks
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (Block -> Block) -> Blocks -> Blocks
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Blocks
    blks ((Block -> Block) -> Blocks) -> (Block -> Block) -> Blocks
    forall a b. (a -> b) -> a -> b
    $ \case
      B.Header Int
    level Attr
    attr [Inline]
    inner -> Int -> Attr -> [Inline] -> Block
    B.Header (Int
    level Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    incr) Attr
    attr [Inline]
    inner
      Block
    x -> Block
    x

    renderModuleDoc :: ModuleDoc -> B.Blocks
    renderModuleDoc :: ModuleDoc -> Blocks
    renderModuleDoc ModuleDoc
    moddoc =
      let modname :: Text
    modname = ModuleDoc -> Text
    moduleDocName ModuleDoc
    moddoc
      in [Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat
      [ Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    "module-" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    modname, [], []) Int
    1
          (Text -> Inlines
    B.str (Text -> Inlines) -> Text -> Inlines
    forall a b. (a -> b) -> a -> b
    $ Text
    "Module " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    modname)
      , Text -> Blocks
    parseCommonMark (ModuleDoc -> Text
    moduleDocDescription ModuleDoc
    moddoc)
      , if [FieldDoc] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ModuleDoc -> [FieldDoc]
    moduleDocFields ModuleDoc
    moddoc)
        then Blocks
    forall a. Monoid a => a
    mempty
        else
          let ident :: Text
    ident = Text
    modname Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "-fields"
          in Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    ident, [], []) Int
    2 (Text -> Inlines
    B.str Text
    "Fields") Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <>
             Int -> Blocks -> Blocks
    shiftHeadings Int
    0 ([Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat ((FieldDoc -> Blocks) -> [FieldDoc] -> [Blocks]
    forall a b. (a -> b) -> [a] -> [b]
    map (Text -> FieldDoc -> Blocks
    renderFieldDoc Text
    modname)
                                       (ModuleDoc -> [FieldDoc]
    moduleDocFields ModuleDoc
    moddoc)))
      , if [FunctionDoc] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ModuleDoc -> [FunctionDoc]
    moduleDocFunctions ModuleDoc
    moddoc)
        then Blocks
    forall a. Monoid a => a
    mempty
        else
          let ident :: Text
    ident = Text
    modname Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "-functions"
          in Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    ident, [], []) Int
    2 (Text -> Inlines
    B.str Text
    "Functions") Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <>
             (Int -> Blocks -> Blocks
    shiftHeadings Int
    2 (Blocks -> Blocks)
    -> ([FunctionDoc] -> Blocks) -> [FunctionDoc] -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat ([Blocks] -> Blocks)
    -> ([FunctionDoc] -> [Blocks]) -> [FunctionDoc] -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FunctionDoc -> Blocks) -> [FunctionDoc] -> [Blocks]
    forall a b. (a -> b) -> [a] -> [b]
    map (Maybe Text -> FunctionDoc -> Blocks
    renderFunctionDoc (Maybe Text -> FunctionDoc -> Blocks)
    -> Maybe Text -> FunctionDoc -> Blocks
    forall a b. (a -> b) -> a -> b
    $ Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    modname) ([FunctionDoc] -> Blocks) -> [FunctionDoc] -> Blocks
    forall a b. (a -> b) -> a -> b
    $
              ModuleDoc -> [FunctionDoc]
    moduleDocFunctions ModuleDoc
    moddoc)
      , if [TypeDoc] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (ModuleDoc -> [TypeDoc]
    moduleDocTypes ModuleDoc
    moddoc)
        then Blocks
    forall a. Monoid a => a
    mempty
        else
          let ident :: Text
    ident = Text
    modname Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "-types"
          in Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    ident, [], []) Int
    2 (Text -> Inlines
    B.str Text
    "Types") Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <>
             (Int -> Blocks -> Blocks
    shiftHeadings Int
    2 (Blocks -> Blocks) -> ([TypeDoc] -> Blocks) -> [TypeDoc] -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat ([Blocks] -> Blocks)
    -> ([TypeDoc] -> [Blocks]) -> [TypeDoc] -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (TypeDoc -> Blocks) -> [TypeDoc] -> [Blocks]
    forall a b. (a -> b) -> [a] -> [b]
    map (Maybe Text -> TypeDoc -> Blocks
    renderTypeDoc (Maybe Text -> TypeDoc -> Blocks)
    -> Maybe Text -> TypeDoc -> Blocks
    forall a b. (a -> b) -> a -> b
    $ Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    modname) ([TypeDoc] -> [Blocks])
    -> ([TypeDoc] -> [TypeDoc]) -> [TypeDoc] -> [Blocks]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
              [TypeDoc] -> [TypeDoc]
    forall a. [a] -> [a]
    reverse ([TypeDoc] -> Blocks) -> [TypeDoc] -> Blocks
    forall a b. (a -> b) -> a -> b
    $ ModuleDoc -> [TypeDoc]
    moduleDocTypes ModuleDoc
    moddoc)
      ]

    parseCommonMark :: T.Text -> B.Blocks
    parseCommonMark :: Text -> Blocks
    parseCommonMark Text
    txt =
      let exts :: Extensions
    exts = [Extension] -> Extensions
    extensionsFromList
            [ Extension
    Ext_wikilinks_title_after_pipe
            , Extension
    Ext_smart
            ]
          result :: Either PandocError Blocks
    result = PandocPure Blocks -> Either PandocError Blocks
    forall a. PandocPure a -> Either PandocError a
    runPure (PandocPure Blocks -> Either PandocError Blocks)
    -> PandocPure Blocks -> Either PandocError Blocks
    forall a b. (a -> b) -> a -> b
    $ do
            Pandoc _ blks <- ReaderOptions -> Text -> PandocPure Pandoc
    forall (m :: * -> *) a.
    (PandocMonad m, ToSources a) =>
    ReaderOptions -> a -> m Pandoc
    readCommonMark (ReaderOptions
    forall a. Default a => a
    def {readerExtensions = exts}) Text
    txt
            return $ B.fromList blks
      in (PandocError -> Blocks)
    -> (Blocks -> Blocks) -> Either PandocError Blocks -> Blocks
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either PandocError -> Blocks
    forall a. Monoid a => a
    mempty Blocks -> Blocks
    forall a. a -> a
    id Either PandocError Blocks
    result

    appendInlines :: B.Blocks -> B.Inlines -> B.Blocks
    appendInlines :: Blocks -> Inlines -> Blocks
    appendInlines Blocks
    blks Inlines
    inlns = case Blocks -> Seq Block
    forall a. Many a -> Seq a
    B.unMany Blocks
    blks of
      Seq Block
    front :|> (B.Para [Inline]
    xs) -> Seq Block -> Blocks
    forall a. Seq a -> Many a
    B.Many Seq Block
    front Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <> Inlines -> Blocks
    B.para ([Inline] -> Inlines
    addTo [Inline]
    xs)
      Seq Block
    front :|> (B.Plain [Inline]
    xs) -> Seq Block -> Blocks
    forall a. Seq a -> Many a
    B.Many Seq Block
    front Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <> Inlines -> Blocks
    B.plain ([Inline] -> Inlines
    addTo [Inline]
    xs)
      Seq Block
    _ -> Blocks
    blks Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <> Inlines -> Blocks
    B.para Inlines
    inlns
     where addTo :: [Inline] -> Inlines
    addTo [Inline]
    xs = [Inline] -> Inlines
    forall a. [a] -> Many a
    B.fromList [Inline]
    xs Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> Inlines
    B.space Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> Inlines
    inlns

    appendType :: B.Blocks -> TypeSpec -> B.Blocks
    appendType :: Blocks -> TypeSpec -> Blocks
    appendType Blocks
    blks TypeSpec
    typespec =
      Blocks -> Inlines -> Blocks
    appendInlines Blocks
    blks (Text -> Inlines
    B.str Text
    "(" Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> TypeSpec -> Inlines
    typeToInlines TypeSpec
    typespec Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> Text -> Inlines
    B.str Text
    ")")

    typeToInlines :: TypeSpec -> B.Inlines
    typeToInlines :: TypeSpec -> Inlines
    typeToInlines = \case
      bt :: TypeSpec
    bt@BasicType{}   -> Inlines -> Inlines
    builtin (Inlines -> Inlines) -> Inlines -> Inlines
    forall a b. (a -> b) -> a -> b
    $ TypeSpec -> Inlines
    tystr TypeSpec
    bt
      NamedType Name
    "integer" -> Inlines -> Inlines
    builtin Inlines
    "integer"
      NamedType Name
    name   -> Attr -> Text -> Text -> Inlines -> Inlines
    B.linkWith (Text
    "", [Text
    "documented-type"], [])
                            (Text
    "#" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Name -> Text
    n2t Name
    name) Text
    forall a. Monoid a => a
    mempty (Inlines -> Inlines) -> Inlines -> Inlines
    forall a b. (a -> b) -> a -> b
    $ Text -> Inlines
    B.str (Name -> Text
    n2t Name
    name)
      SeqType TypeSpec
    itemtype -> Inlines
    "{" Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> TypeSpec -> Inlines
    typeToInlines TypeSpec
    itemtype Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> Inlines
    ",...}"
      SumType [TypeSpec]
    summands -> [Inlines] -> Inlines
    forall a. Monoid a => [a] -> a
    mconcat ([Inlines] -> Inlines)
    -> ([Inlines] -> [Inlines]) -> [Inlines] -> Inlines
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Inlines -> [Inlines] -> [Inlines]
    forall a. a -> [a] -> [a]
    intersperse (Text -> Inlines
    B.str Text
    "|") ([Inlines] -> Inlines) -> [Inlines] -> Inlines
    forall a b. (a -> b) -> a -> b
    $ (TypeSpec -> Inlines) -> [TypeSpec] -> [Inlines]
    forall a b. (a -> b) -> [a] -> [b]
    map TypeSpec -> Inlines
    typeToInlines [TypeSpec]
    summands
      TypeSpec
    AnyType          -> Inlines
    "any"
      TypeSpec
    x                -> TypeSpec -> Inlines
    tystr TypeSpec
    x
     where
      tystr :: TypeSpec -> Inlines
    tystr = Text -> Inlines
    B.str (Text -> Inlines) -> (TypeSpec -> Text) -> TypeSpec -> Inlines
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack (String -> Text) -> (TypeSpec -> String) -> TypeSpec -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TypeSpec -> String
    typeSpecToString
      n2t :: Name -> Text
    n2t = ByteString -> Text
    UTF8.toText (ByteString -> Text) -> (Name -> ByteString) -> Name -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> ByteString
    fromName
      builtin :: Inlines -> Inlines
    builtin = Attr -> Inlines -> Inlines
    B.spanWith (Text
    "", [Text
    "builtin-lua-type"], [])

    renderFunctionDoc :: Maybe T.Text -> FunctionDoc -> B.Blocks
    renderFunctionDoc :: Maybe Text -> FunctionDoc -> Blocks
    renderFunctionDoc Maybe Text
    mbmodule FunctionDoc
    fndoc =
      let name :: Text
    name = case Maybe Text
    mbmodule of
            Just Text
    _   ->  (Char -> Bool) -> Text -> Text
    T.takeWhileEnd (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    '.') (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ FunctionDoc -> Text
    funDocName FunctionDoc
    fndoc
            Maybe Text
    Nothing  -> FunctionDoc -> Text
    funDocName FunctionDoc
    fndoc
          ident :: Text
    ident = FunctionDoc -> Text
    funDocName FunctionDoc
    fndoc
          level :: Int
    level = Int
    1
          argsString :: Text
    argsString = [ParameterDoc] -> Text
    argslist (FunctionDoc -> [ParameterDoc]
    funDocParameters FunctionDoc
    fndoc)
          paramToDefItem :: ParameterDoc -> (Inlines, [Blocks])
    paramToDefItem ParameterDoc
    p = ( Text -> Inlines
    B.code (Text -> Inlines) -> Text -> Inlines
    forall a b. (a -> b) -> a -> b
    $ ParameterDoc -> Text
    parameterName ParameterDoc
    p
                             , [Blocks] -> [Blocks]
    compactify
                               [ Blocks -> TypeSpec -> Blocks
    appendType
                                   (Text -> Blocks
    parseCommonMark (Text -> Blocks) -> Text -> Blocks
    forall a b. (a -> b) -> a -> b
    $ ParameterDoc -> Text
    parameterDescription ParameterDoc
    p)
                                   (ParameterDoc -> TypeSpec
    parameterType ParameterDoc
    p)
                               ]
                             )
          paramlist :: Blocks
    paramlist = [(Inlines, [Blocks])] -> Blocks
    B.definitionList ([(Inlines, [Blocks])] -> Blocks)
    -> ([ParameterDoc] -> [(Inlines, [Blocks])])
    -> [ParameterDoc]
    -> Blocks
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ParameterDoc -> (Inlines, [Blocks]))
    -> [ParameterDoc] -> [(Inlines, [Blocks])]
    forall a b. (a -> b) -> [a] -> [b]
    map ParameterDoc -> (Inlines, [Blocks])
    paramToDefItem ([ParameterDoc] -> Blocks) -> [ParameterDoc] -> Blocks
    forall a b. (a -> b) -> a -> b
    $
                      FunctionDoc -> [ParameterDoc]
    funDocParameters FunctionDoc
    fndoc
      in [Blocks] -> Blocks
    forall a. Monoid a => [a] -> a
    mconcat
         [ Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    ident, [], []) Int
    level (Text -> Inlines
    B.str Text
    name)
         , Inlines -> Blocks
    B.plain (Text -> Inlines
    B.code (Text -> Inlines) -> Text -> Inlines
    forall a b. (a -> b) -> a -> b
    $ Text
    name Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " (" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    argsString Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ")")
         , Text -> Blocks
    parseCommonMark (FunctionDoc -> Text
    funDocDescription FunctionDoc
    fndoc)
         , if [ParameterDoc] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (FunctionDoc -> [ParameterDoc]
    funDocParameters FunctionDoc
    fndoc)
           then Blocks
    forall a. Monoid a => a
    mempty
           else Inlines -> Blocks
    B.para Inlines
    "Parameters:" Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <> Blocks
    paramlist
         , if FunctionDoc -> ResultsDoc
    funDocResults FunctionDoc
    fndoc ResultsDoc -> ResultsDoc -> Bool
    forall a. Eq a => a -> a -> Bool
    == [ResultValueDoc] -> ResultsDoc
    ResultsDocList []
           then Blocks
    forall a. Monoid a => a
    mempty
           else Inlines -> Blocks
    B.para Inlines
    "Returns:" Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <> ResultsDoc -> Blocks
    renderResults (FunctionDoc -> ResultsDoc
    funDocResults FunctionDoc
    fndoc)
         , case FunctionDoc -> Maybe Version
    funDocSince FunctionDoc
    fndoc of
             Maybe Version
    Nothing -> Blocks
    forall a. Monoid a => a
    mempty
             Just Version
    version ->
               Inlines -> Blocks
    B.para (Inlines -> Blocks) -> Inlines -> Blocks
    forall a b. (a -> b) -> a -> b
    $ Inlines -> Inlines
    B.emph (Inlines -> Inlines) -> Inlines -> Inlines
    forall a b. (a -> b) -> a -> b
    $ Inlines
    "Since: " Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> (Text -> Inlines
    B.str (Text -> Inlines) -> (String -> Text) -> String -> Inlines
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack (String -> Inlines) -> String -> Inlines
    forall a b. (a -> b) -> a -> b
    $ Version -> String
    showVersion Version
    version)
         ]

    renderResults :: ResultsDoc -> B.Blocks
    renderResults :: ResultsDoc -> Blocks
    renderResults (ResultsDocMult Text
    descr) = Text -> Blocks
    parseCommonMark Text
    descr
    renderResults (ResultsDocList [ResultValueDoc]
    rvd) = [Blocks] -> Blocks
    B.bulletList ([Blocks] -> Blocks) -> [Blocks] -> Blocks
    forall a b. (a -> b) -> a -> b
    $ (ResultValueDoc -> Blocks) -> [ResultValueDoc] -> [Blocks]
    forall a b. (a -> b) -> [a] -> [b]
    map ResultValueDoc -> Blocks
    renderResultVal [ResultValueDoc]
    rvd
     where
       renderResultVal :: ResultValueDoc -> Blocks
    renderResultVal (ResultValueDoc TypeSpec
    typespec Text
    descr) =
         Text -> Blocks
    parseCommonMark Text
    descr Blocks -> TypeSpec -> Blocks
    `appendType` TypeSpec
    typespec

    argslist :: [ParameterDoc] -> T.Text
    argslist :: [ParameterDoc] -> Text
    argslist [ParameterDoc]
    params =
      -- Expect optional values to come after required values.
      let ([ParameterDoc]
    required, [ParameterDoc]
    optional') = (ParameterDoc -> Bool)
    -> [ParameterDoc] -> ([ParameterDoc], [ParameterDoc])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break ParameterDoc -> Bool
    parameterIsOptional [ParameterDoc]
    params
          reqs :: [Text]
    reqs = (ParameterDoc -> Text) -> [ParameterDoc] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map ParameterDoc -> Text
    parameterName [ParameterDoc]
    required
          opts :: [Text]
    opts = (ParameterDoc -> Text) -> [ParameterDoc] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map ParameterDoc -> Text
    parameterName [ParameterDoc]
    optional'
      in if [Text] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    opts
         then Text -> [Text] -> Text
    T.intercalate Text
    ", " [Text]
    reqs
         else Text -> [Text] -> Text
    T.intercalate Text
    ", " [Text]
    reqs Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
              (if [ParameterDoc] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [ParameterDoc]
    required then Text
    "[" else Text
    "[, ") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
              Text -> [Text] -> Text
    T.intercalate Text
    "[, " [Text]
    opts Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text -> Text
    T.replicate ([Text] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Text]
    opts) Text
    "]"

    renderFieldDoc :: T.Text -> FieldDoc -> B.Blocks
    renderFieldDoc :: Text -> FieldDoc -> Blocks
    renderFieldDoc Text
    _modname FieldDoc
    fd =
      Attr -> Int -> Inlines -> Blocks
    B.headerWith (Text
    ident, [], []) Int
    3 (Text -> Inlines
    B.str Text
    name) Blocks -> Blocks -> Blocks
    forall a. Semigroup a => a -> a -> a
    <>
      Blocks -> TypeSpec -> Blocks
    appendType (Text -> Blocks
    parseCommonMark (Text -> Blocks) -> Text -> Blocks
    forall a b. (a -> b) -> a -> b
    $ FieldDoc -> Text
    fieldDocDescription FieldDoc
    fd) (FieldDoc -> TypeSpec
    fieldDocType FieldDoc
    fd)
     where
      ident :: Text
    ident = FieldDoc -> Text
    fieldDocName FieldDoc
    fd
      name :: Text
    name = (Char -> Bool) -> Text -> Text
    T.takeWhileEnd (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    '.') (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ FieldDoc -> Text
    fieldDocName FieldDoc
    fd