{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

module OptEnvConf.Doc
  ( renderVersionPage,
    parserDocs,
    commandParserDocs,
    renderHelpPage,
    renderCommandHelpPage,
    renderManPage,
    renderReferenceDocumentation,
    parserOptDocs,
    docsToOptDocs,
    renderLongOptDocs,
    renderShortOptDocs,
    parserEnvDocs,
    docsToEnvDocs,
    renderEnvDocs,
    parserConfDocs,
    docsToConfDocs,
    renderConfDocs,

    -- * Internal
    AnyDocs (..),
    SetDoc (..),
    OptDoc (..),
    EnvDoc (..),
    ConfDoc (..),
    CommandDoc (..),
    settingSetDoc,
    renderSetDoc,
    settingOptDoc,
    renderOptDocLong,
    settingEnvDoc,
    renderEnvDoc,
    settingConfDoc,
    renderConfDoc,
    helpLines,
  )
where

import Autodocodec.Schema
import Autodocodec.Yaml.Schema
import Control.Monad
import Data.List (intercalate, intersperse)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Data.Maybe
import qualified Data.Text as T
import Data.Version
import OptEnvConf.Args (Dashed (..))
import OptEnvConf.Output
import OptEnvConf.Parser
import OptEnvConf.Setting
import Text.Colour
import Text.Colour.Layout

data SetDoc = SetDoc
  { SetDoc -> Bool
setDocTryArgument :: !Bool,
    SetDoc -> Bool
setDocTrySwitch :: !Bool,
    SetDoc -> Bool
setDocTryOption :: !Bool,
    SetDoc -> [Dashed]
setDocDasheds :: ![Dashed],
    SetDoc -> Maybe (NonEmpty String)
setDocEnvVars :: !(Maybe (NonEmpty String)),
    SetDoc -> Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocConfKeys :: !(Maybe (NonEmpty (NonEmpty String, JSONSchema))),
    SetDoc -> Maybe String
setDocDefault :: !(Maybe String),
    SetDoc -> [String]
setDocExamples :: ![String],
    SetDoc -> Maybe String
setDocMetavar :: !(Maybe Metavar),
    SetDoc -> Maybe String
setDocHelp :: !(Maybe String)
  }
  deriving (Int -> SetDoc -> ShowS
[SetDoc] -> ShowS
SetDoc -> String
(Int -> SetDoc -> ShowS)
-> (SetDoc -> String) -> ([SetDoc] -> ShowS) -> Show SetDoc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SetDoc -> ShowS
showsPrec :: Int -> SetDoc -> ShowS
$cshow :: SetDoc -> String
show :: SetDoc -> String
$cshowList :: [SetDoc] -> ShowS
showList :: [SetDoc] -> ShowS
Show)

data OptDoc = OptDoc
  { OptDoc -> Bool
optDocTryArgument :: !Bool,
    OptDoc -> Bool
optDocTrySwitch :: !Bool,
    OptDoc -> Bool
optDocTryOption :: !Bool,
    OptDoc -> [Dashed]
optDocDasheds :: ![Dashed],
    OptDoc -> Maybe String
optDocDefault :: !(Maybe String),
    OptDoc -> [String]
optDocExamples :: ![String],
    OptDoc -> Maybe String
optDocMetavar :: !(Maybe Metavar),
    OptDoc -> Maybe String
optDocHelp :: !(Maybe String)
  }
  deriving (Int -> OptDoc -> ShowS
[OptDoc] -> ShowS
OptDoc -> String
(Int -> OptDoc -> ShowS)
-> (OptDoc -> String) -> ([OptDoc] -> ShowS) -> Show OptDoc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OptDoc -> ShowS
showsPrec :: Int -> OptDoc -> ShowS
$cshow :: OptDoc -> String
show :: OptDoc -> String
$cshowList :: [OptDoc] -> ShowS
showList :: [OptDoc] -> ShowS
Show)

data EnvDoc = EnvDoc
  { EnvDoc -> NonEmpty String
envDocVars :: !(NonEmpty String),
    EnvDoc -> Maybe String
envDocDefault :: !(Maybe String),
    EnvDoc -> [String]
envDocExamples :: ![String],
    EnvDoc -> Maybe String
envDocMetavar :: !(Maybe Metavar),
    EnvDoc -> Maybe String
envDocHelp :: !(Maybe String)
  }
  deriving (Int -> EnvDoc -> ShowS
[EnvDoc] -> ShowS
EnvDoc -> String
(Int -> EnvDoc -> ShowS)
-> (EnvDoc -> String) -> ([EnvDoc] -> ShowS) -> Show EnvDoc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EnvDoc -> ShowS
showsPrec :: Int -> EnvDoc -> ShowS
$cshow :: EnvDoc -> String
show :: EnvDoc -> String
$cshowList :: [EnvDoc] -> ShowS
showList :: [EnvDoc] -> ShowS
Show)

data ConfDoc = ConfDoc
  { ConfDoc -> NonEmpty (NonEmpty String, JSONSchema)
confDocKeys :: !(NonEmpty (NonEmpty String, JSONSchema)),
    ConfDoc -> Maybe String
confDocDefault :: !(Maybe String),
    ConfDoc -> [String]
confDocExamples :: ![String],
    ConfDoc -> Maybe String
confDocHelp :: !(Maybe String)
  }
  deriving (Int -> ConfDoc -> ShowS
[ConfDoc] -> ShowS
ConfDoc -> String
(Int -> ConfDoc -> ShowS)
-> (ConfDoc -> String) -> ([ConfDoc] -> ShowS) -> Show ConfDoc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ConfDoc -> ShowS
showsPrec :: Int -> ConfDoc -> ShowS
$cshow :: ConfDoc -> String
show :: ConfDoc -> String
$cshowList :: [ConfDoc] -> ShowS
showList :: [ConfDoc] -> ShowS
Show)

data AnyDocs a
  = AnyDocsCommands !(Maybe String) [CommandDoc a]
  | AnyDocsAnd ![AnyDocs a]
  | AnyDocsOr ![AnyDocs a]
  | AnyDocsSingle !a
  deriving (Int -> AnyDocs a -> ShowS
[AnyDocs a] -> ShowS
AnyDocs a -> String
(Int -> AnyDocs a -> ShowS)
-> (AnyDocs a -> String)
-> ([AnyDocs a] -> ShowS)
-> Show (AnyDocs a)
forall a. Show a => Int -> AnyDocs a -> ShowS
forall a. Show a => [AnyDocs a] -> ShowS
forall a. Show a => AnyDocs a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> AnyDocs a -> ShowS
showsPrec :: Int -> AnyDocs a -> ShowS
$cshow :: forall a. Show a => AnyDocs a -> String
show :: AnyDocs a -> String
$cshowList :: forall a. Show a => [AnyDocs a] -> ShowS
showList :: [AnyDocs a] -> ShowS
Show, (forall a b. (a -> b) -> AnyDocs a -> AnyDocs b)
-> (forall a b. a -> AnyDocs b -> AnyDocs a) -> Functor AnyDocs
forall a b. a -> AnyDocs b -> AnyDocs a
forall a b. (a -> b) -> AnyDocs a -> AnyDocs 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) -> AnyDocs a -> AnyDocs b
fmap :: forall a b. (a -> b) -> AnyDocs a -> AnyDocs b
$c<$ :: forall a b. a -> AnyDocs b -> AnyDocs a
<$ :: forall a b. a -> AnyDocs b -> AnyDocs a
Functor)

data CommandDoc a = CommandDoc
  { forall a. CommandDoc a -> String
commandDocArgument :: String,
    forall a. CommandDoc a -> String
commandDocHelp :: Help,
    forall a. CommandDoc a -> AnyDocs a
commandDocs :: AnyDocs a
  }
  deriving (Int -> CommandDoc a -> ShowS
[CommandDoc a] -> ShowS
CommandDoc a -> String
(Int -> CommandDoc a -> ShowS)
-> (CommandDoc a -> String)
-> ([CommandDoc a] -> ShowS)
-> Show (CommandDoc a)
forall a. Show a => Int -> CommandDoc a -> ShowS
forall a. Show a => [CommandDoc a] -> ShowS
forall a. Show a => CommandDoc a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> CommandDoc a -> ShowS
showsPrec :: Int -> CommandDoc a -> ShowS
$cshow :: forall a. Show a => CommandDoc a -> String
show :: CommandDoc a -> String
$cshowList :: forall a. Show a => [CommandDoc a] -> ShowS
showList :: [CommandDoc a] -> ShowS
Show, (forall a b. (a -> b) -> CommandDoc a -> CommandDoc b)
-> (forall a b. a -> CommandDoc b -> CommandDoc a)
-> Functor CommandDoc
forall a b. a -> CommandDoc b -> CommandDoc a
forall a b. (a -> b) -> CommandDoc a -> CommandDoc 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) -> CommandDoc a -> CommandDoc b
fmap :: forall a b. (a -> b) -> CommandDoc a -> CommandDoc b
$c<$ :: forall a b. a -> CommandDoc b -> CommandDoc a
<$ :: forall a b. a -> CommandDoc b -> CommandDoc a
Functor)

mapMaybeDocs :: (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs :: forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs a -> Maybe b
func = AnyDocs b -> AnyDocs b
forall a. AnyDocs a -> AnyDocs a
simplifyAnyDocs (AnyDocs b -> AnyDocs b)
-> (AnyDocs a -> AnyDocs b) -> AnyDocs a -> AnyDocs b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs' a -> Maybe b
func

-- Like mapMaybeDocs but without simplifying
mapMaybeDocs' :: (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs' :: forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs' a -> Maybe b
func = AnyDocs a -> AnyDocs b
go
  where
    go :: AnyDocs a -> AnyDocs b
go = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc a]
cs -> Maybe String -> [CommandDoc b] -> AnyDocs b
forall a. Maybe String -> [CommandDoc a] -> AnyDocs a
AnyDocsCommands Maybe String
mDefault ([CommandDoc b] -> AnyDocs b) -> [CommandDoc b] -> AnyDocs b
forall a b. (a -> b) -> a -> b
$ (CommandDoc a -> CommandDoc b) -> [CommandDoc a] -> [CommandDoc b]
forall a b. (a -> b) -> [a] -> [b]
map CommandDoc a -> CommandDoc b
goCommandDoc [CommandDoc a]
cs
      AnyDocsAnd [AnyDocs a]
ds -> [AnyDocs b] -> AnyDocs b
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd ([AnyDocs b] -> AnyDocs b) -> [AnyDocs b] -> AnyDocs b
forall a b. (a -> b) -> a -> b
$ (AnyDocs a -> AnyDocs b) -> [AnyDocs a] -> [AnyDocs b]
forall a b. (a -> b) -> [a] -> [b]
map AnyDocs a -> AnyDocs b
go [AnyDocs a]
ds
      AnyDocsOr [AnyDocs a]
ds -> [AnyDocs b] -> AnyDocs b
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr ([AnyDocs b] -> AnyDocs b) -> [AnyDocs b] -> AnyDocs b
forall a b. (a -> b) -> a -> b
$ (AnyDocs a -> AnyDocs b) -> [AnyDocs a] -> [AnyDocs b]
forall a b. (a -> b) -> [a] -> [b]
map AnyDocs a -> AnyDocs b
go [AnyDocs a]
ds
      AnyDocsSingle a
d -> AnyDocs b -> (b -> AnyDocs b) -> Maybe b -> AnyDocs b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([AnyDocs b] -> AnyDocs b
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd []) b -> AnyDocs b
forall a. a -> AnyDocs a
AnyDocsSingle (Maybe b -> AnyDocs b) -> Maybe b -> AnyDocs b
forall a b. (a -> b) -> a -> b
$ a -> Maybe b
func a
d

    goCommandDoc :: CommandDoc a -> CommandDoc b
goCommandDoc CommandDoc a
cd = CommandDoc a
cd {commandDocs = go (commandDocs cd)}

simplifyAnyDocs :: AnyDocs a -> AnyDocs a
simplifyAnyDocs :: forall a. AnyDocs a -> AnyDocs a
simplifyAnyDocs = AnyDocs a -> AnyDocs a
forall a. AnyDocs a -> AnyDocs a
go
  where
    go :: AnyDocs a -> AnyDocs a
go = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc a]
cs -> Maybe String -> [CommandDoc a] -> AnyDocs a
forall a. Maybe String -> [CommandDoc a] -> AnyDocs a
AnyDocsCommands Maybe String
mDefault ([CommandDoc a] -> AnyDocs a) -> [CommandDoc a] -> AnyDocs a
forall a b. (a -> b) -> a -> b
$ (CommandDoc a -> CommandDoc a) -> [CommandDoc a] -> [CommandDoc a]
forall a b. (a -> b) -> [a] -> [b]
map CommandDoc a -> CommandDoc a
goDoc [CommandDoc a]
cs
      AnyDocsAnd [AnyDocs a]
ds -> case (AnyDocs a -> [AnyDocs a]) -> [AnyDocs a] -> [AnyDocs a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs a -> [AnyDocs a]
goAnd [AnyDocs a]
ds of
        [AnyDocs a
a] -> AnyDocs a
a
        [AnyDocs a]
as -> [AnyDocs a] -> AnyDocs a
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd [AnyDocs a]
as
      AnyDocsOr [AnyDocs a]
ds -> [AnyDocs a] -> AnyDocs a
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr ([AnyDocs a] -> AnyDocs a) -> [AnyDocs a] -> AnyDocs a
forall a b. (a -> b) -> a -> b
$ (AnyDocs a -> [AnyDocs a]) -> [AnyDocs a] -> [AnyDocs a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs a -> [AnyDocs a]
goOr [AnyDocs a]
ds
      AnyDocsSingle a
v -> a -> AnyDocs a
forall a. a -> AnyDocs a
AnyDocsSingle a
v

    goDoc :: CommandDoc a -> CommandDoc a
goDoc CommandDoc a
cd = CommandDoc a
cd {commandDocs = go (commandDocs cd)}

    goAnd :: AnyDocs a -> [AnyDocs a]
goAnd = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc a]
c -> [Maybe String -> [CommandDoc a] -> AnyDocs a
forall a. Maybe String -> [CommandDoc a] -> AnyDocs a
AnyDocsCommands Maybe String
mDefault ([CommandDoc a] -> AnyDocs a) -> [CommandDoc a] -> AnyDocs a
forall a b. (a -> b) -> a -> b
$ (CommandDoc a -> CommandDoc a) -> [CommandDoc a] -> [CommandDoc a]
forall a b. (a -> b) -> [a] -> [b]
map CommandDoc a -> CommandDoc a
goDoc [CommandDoc a]
c]
      AnyDocsAnd [AnyDocs a]
ds -> (AnyDocs a -> [AnyDocs a]) -> [AnyDocs a] -> [AnyDocs a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (AnyDocs a -> [AnyDocs a]
goAnd (AnyDocs a -> [AnyDocs a])
-> (AnyDocs a -> AnyDocs a) -> AnyDocs a -> [AnyDocs a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs a -> AnyDocs a
go) [AnyDocs a]
ds
      AnyDocsOr [] -> []
      AnyDocs a
ds -> [AnyDocs a -> AnyDocs a
go AnyDocs a
ds]

    goOr :: AnyDocs a -> [AnyDocs a]
goOr = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc a]
c -> [Maybe String -> [CommandDoc a] -> AnyDocs a
forall a. Maybe String -> [CommandDoc a] -> AnyDocs a
AnyDocsCommands Maybe String
mDefault ([CommandDoc a] -> AnyDocs a) -> [CommandDoc a] -> AnyDocs a
forall a b. (a -> b) -> a -> b
$ (CommandDoc a -> CommandDoc a) -> [CommandDoc a] -> [CommandDoc a]
forall a b. (a -> b) -> [a] -> [b]
map CommandDoc a -> CommandDoc a
goDoc [CommandDoc a]
c]
      AnyDocsOr [AnyDocs a]
ds -> (AnyDocs a -> [AnyDocs a]) -> [AnyDocs a] -> [AnyDocs a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (AnyDocs a -> [AnyDocs a]
goOr (AnyDocs a -> [AnyDocs a])
-> (AnyDocs a -> AnyDocs a) -> AnyDocs a -> [AnyDocs a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs a -> AnyDocs a
go) [AnyDocs a]
ds
      AnyDocsAnd [] -> []
      AnyDocs a
ds -> [AnyDocs a -> AnyDocs a
go AnyDocs a
ds]

-- | Derive parser documentation
--
-- API Note: We return a Maybe inside the AnyDocs so that we can keep track of hidden settings and use this information to know whether settings are optional or not.
parserDocs :: Parser a -> AnyDocs (Maybe SetDoc)
parserDocs :: forall a. Parser a -> AnyDocs (Maybe SetDoc)
parserDocs = AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
forall a. AnyDocs a -> AnyDocs a
simplifyAnyDocs (AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc))
-> (Parser a -> AnyDocs (Maybe SetDoc))
-> Parser a
-> AnyDocs (Maybe SetDoc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go
  where
    go :: Parser a -> AnyDocs (Maybe SetDoc)
    go :: forall a. Parser a -> AnyDocs (Maybe SetDoc)
go = \case
      ParserPure a
_ -> Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle Maybe SetDoc
forall a. Maybe a
Nothing
      ParserAp Parser (a1 -> a)
pf Parser a1
pa -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd [Parser (a1 -> a) -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser (a1 -> a)
pf, Parser a1 -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a1
pa]
      ParserSelect Parser (Either a1 a)
p1 Parser (a1 -> a)
p2 -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd [Parser (Either a1 a) -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser (Either a1 a)
p1, Parser (a1 -> a) -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser (a1 -> a)
p2]
      ParserEmpty Maybe SrcLoc
_ -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr []
      ParserAlt Parser a
p1 Parser a
p2 -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr [Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a
p1, Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a
p2]
      ParserMany Parser a1
p -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr [Parser a1 -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a1
p, Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle Maybe SetDoc
forall a. Maybe a
Nothing]
      ParserSome Parser a1
p -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd [Parser a1 -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a1
p, Parser [a1] -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go (Parser a1 -> Parser [a1]
forall a1. Parser a1 -> Parser [a1]
ParserMany Parser a1
p)] -- TODO: is this right?
      ParserAllOrNothing Maybe SrcLoc
_ Parser a
p -> Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a
p
      ParserCheck Maybe SrcLoc
_ Bool
_ a1 -> IO (Either String a)
_ Parser a1
p -> Parser a1 -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a1
p
      ParserCommands Maybe SrcLoc
_ Maybe String
mDefault [Command a]
cs -> Maybe String
-> [CommandDoc (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. Maybe String -> [CommandDoc a] -> AnyDocs a
AnyDocsCommands Maybe String
mDefault ([CommandDoc (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc))
-> [CommandDoc (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a b. (a -> b) -> a -> b
$ (Command a -> CommandDoc (Maybe SetDoc))
-> [Command a] -> [CommandDoc (Maybe SetDoc)]
forall a b. (a -> b) -> [a] -> [b]
map Command a -> CommandDoc (Maybe SetDoc)
forall a. Command a -> CommandDoc (Maybe SetDoc)
commandParserDocs [Command a]
cs
      ParserWithConfig Maybe SrcLoc
_ Parser (Maybe Object)
p1 Parser a
p2 -> [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd [Parser (Maybe Object) -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser (Maybe Object)
p1, Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
go Parser a
p2] -- TODO: is this right? Maybe we want to document that it's not a pure parser?
      ParserSetting Maybe SrcLoc
_ Setting a
set -> Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle (Maybe SetDoc -> AnyDocs (Maybe SetDoc))
-> Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a b. (a -> b) -> a -> b
$ Setting a -> Maybe SetDoc
forall a. Setting a -> Maybe SetDoc
settingSetDoc Setting a
set

commandParserDocs :: Command a -> CommandDoc (Maybe SetDoc)
commandParserDocs :: forall a. Command a -> CommandDoc (Maybe SetDoc)
commandParserDocs Command {String
Maybe SrcLoc
Parser a
commandSrcLoc :: Maybe SrcLoc
commandArg :: String
commandHelp :: String
commandParser :: Parser a
commandSrcLoc :: forall a. Command a -> Maybe SrcLoc
commandArg :: forall a. Command a -> String
commandHelp :: forall a. Command a -> String
commandParser :: forall a. Command a -> Parser a
..} =
  CommandDoc
    { commandDocArgument :: String
commandDocArgument = String
commandArg,
      commandDocHelp :: String
commandDocHelp = String
commandHelp,
      commandDocs :: AnyDocs (Maybe SetDoc)
commandDocs = Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
parserDocs Parser a
commandParser
    }

withoutHiddenDocs :: AnyDocs (Maybe a) -> AnyDocs a
withoutHiddenDocs :: forall a. AnyDocs (Maybe a) -> AnyDocs a
withoutHiddenDocs = (Maybe a -> Maybe a) -> AnyDocs (Maybe a) -> AnyDocs a
forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs Maybe a -> Maybe a
forall a. a -> a
id

settingSetDoc :: Setting a -> Maybe SetDoc
settingSetDoc :: forall a. Setting a -> Maybe SetDoc
settingSetDoc Setting {Bool
[String]
[Dashed]
[Reader a]
Maybe a
Maybe String
Maybe (NonEmpty String)
Maybe (NonEmpty (ConfigValSetting a))
Maybe (a, String)
settingDasheds :: [Dashed]
settingReaders :: [Reader a]
settingTryArgument :: Bool
settingSwitchValue :: Maybe a
settingTryOption :: Bool
settingEnvVars :: Maybe (NonEmpty String)
settingConfigVals :: Maybe (NonEmpty (ConfigValSetting a))
settingDefaultValue :: Maybe (a, String)
settingExamples :: [String]
settingHidden :: Bool
settingMetavar :: Maybe String
settingHelp :: Maybe String
settingDasheds :: forall a. Setting a -> [Dashed]
settingReaders :: forall a. Setting a -> [Reader a]
settingTryArgument :: forall a. Setting a -> Bool
settingSwitchValue :: forall a. Setting a -> Maybe a
settingTryOption :: forall a. Setting a -> Bool
settingEnvVars :: forall a. Setting a -> Maybe (NonEmpty String)
settingConfigVals :: forall a. Setting a -> Maybe (NonEmpty (ConfigValSetting a))
settingDefaultValue :: forall a. Setting a -> Maybe (a, String)
settingExamples :: forall a. Setting a -> [String]
settingHidden :: forall a. Setting a -> Bool
settingMetavar :: forall a. Setting a -> Maybe String
settingHelp :: forall a. Setting a -> Maybe String
..} = do
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not Bool
settingHidden
  let setDocDasheds :: [Dashed]
setDocDasheds = [Dashed]
settingDasheds
  let setDocTryArgument :: Bool
setDocTryArgument = Bool
settingTryArgument
  let setDocTrySwitch :: Bool
setDocTrySwitch = Maybe a -> Bool
forall a. Maybe a -> Bool
isJust Maybe a
settingSwitchValue
  let setDocTryOption :: Bool
setDocTryOption = Bool
settingTryOption
  let setDocEnvVars :: Maybe (NonEmpty String)
setDocEnvVars = Maybe (NonEmpty String)
settingEnvVars
  let setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocConfKeys =
        (ConfigValSetting a -> (NonEmpty String, JSONSchema))
-> NonEmpty (ConfigValSetting a)
-> NonEmpty (NonEmpty String, JSONSchema)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
NE.map
          ( \ConfigValSetting {NonEmpty String
ValueCodec void (Maybe a)
configValSettingPath :: NonEmpty String
configValSettingCodec :: ValueCodec void (Maybe a)
configValSettingPath :: forall a. ConfigValSetting a -> NonEmpty String
configValSettingCodec :: ()
..} ->
              (NonEmpty String
configValSettingPath, ValueCodec void (Maybe a) -> JSONSchema
forall input output. ValueCodec input output -> JSONSchema
jsonSchemaVia ValueCodec void (Maybe a)
configValSettingCodec)
          )
          (NonEmpty (ConfigValSetting a)
 -> NonEmpty (NonEmpty String, JSONSchema))
-> Maybe (NonEmpty (ConfigValSetting a))
-> Maybe (NonEmpty (NonEmpty String, JSONSchema))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty (ConfigValSetting a))
settingConfigVals
  let setDocDefault :: Maybe String
setDocDefault = (a, String) -> String
forall a b. (a, b) -> b
snd ((a, String) -> String) -> Maybe (a, String) -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (a, String)
settingDefaultValue
  let setDocExamples :: [String]
setDocExamples = [String]
settingExamples
  let setDocMetavar :: Maybe String
setDocMetavar = Maybe String
settingMetavar
  let setDocHelp :: Maybe String
setDocHelp = Maybe String
settingHelp
  pure SetDoc {Bool
[String]
[Dashed]
Maybe String
Maybe (NonEmpty String)
Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocTryArgument :: Bool
setDocTrySwitch :: Bool
setDocTryOption :: Bool
setDocDasheds :: [Dashed]
setDocEnvVars :: Maybe (NonEmpty String)
setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: Maybe String
setDocExamples :: [String]
setDocMetavar :: Maybe String
setDocHelp :: Maybe String
setDocDasheds :: [Dashed]
setDocTryArgument :: Bool
setDocTrySwitch :: Bool
setDocTryOption :: Bool
setDocEnvVars :: Maybe (NonEmpty String)
setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: Maybe String
setDocExamples :: [String]
setDocMetavar :: Maybe String
setDocHelp :: Maybe String
..}

settingOptDoc :: Setting a -> Maybe OptDoc
settingOptDoc :: forall a. Setting a -> Maybe OptDoc
settingOptDoc = Setting a -> Maybe SetDoc
forall a. Setting a -> Maybe SetDoc
settingSetDoc (Setting a -> Maybe SetDoc)
-> (SetDoc -> Maybe OptDoc) -> Setting a -> Maybe OptDoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> SetDoc -> Maybe OptDoc
setDocOptDoc

renderSetDoc :: SetDoc -> [[Chunk]]
renderSetDoc :: SetDoc -> [[Chunk]]
renderSetDoc SetDoc
setDoc =
  [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ Maybe String -> [[Chunk]]
renderSetDocHeader (SetDoc -> Maybe String
setDocHelp SetDoc
setDoc),
      SetDoc -> [[Chunk]]
renderSetDocWithoutHeader SetDoc
setDoc,
      [[]]
    ]

renderSetDocHeader :: Maybe Help -> [[Chunk]]
renderSetDocHeader :: Maybe String -> [[Chunk]]
renderSetDocHeader = [[Chunk]] -> (String -> [[Chunk]]) -> Maybe String -> [[Chunk]]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [[Colour -> Chunk -> Chunk
fore Colour
red Chunk
"undocumented"]] String -> [[Chunk]]
helpLines

renderSetDocWithoutHeader :: SetDoc -> [[Chunk]]
renderSetDocWithoutHeader :: SetDoc -> [[Chunk]]
renderSetDocWithoutHeader SetDoc {Bool
[String]
[Dashed]
Maybe String
Maybe (NonEmpty String)
Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocTryArgument :: SetDoc -> Bool
setDocTrySwitch :: SetDoc -> Bool
setDocTryOption :: SetDoc -> Bool
setDocDasheds :: SetDoc -> [Dashed]
setDocEnvVars :: SetDoc -> Maybe (NonEmpty String)
setDocConfKeys :: SetDoc -> Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: SetDoc -> Maybe String
setDocExamples :: SetDoc -> [String]
setDocMetavar :: SetDoc -> Maybe String
setDocHelp :: SetDoc -> Maybe String
setDocTryArgument :: Bool
setDocTrySwitch :: Bool
setDocTryOption :: Bool
setDocDasheds :: [Dashed]
setDocEnvVars :: Maybe (NonEmpty String)
setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: Maybe String
setDocExamples :: [String]
setDocMetavar :: Maybe String
setDocHelp :: Maybe String
..} =
  [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ [ [[Chunk]] -> [Chunk]
unwordsChunks
          [ [Chunk
"argument:"],
            [Maybe String -> Chunk
mMetavarChunk Maybe String
setDocMetavar]
          ]
        | Bool
setDocTryArgument
      ],
      [ [[Chunk]] -> [Chunk]
unwordsChunks
          [ [Chunk
"switch:"],
            NonEmpty Dashed -> [Chunk]
dashedChunksNE NonEmpty Dashed
dasheds
          ]
        | Bool
setDocTrySwitch,
          NonEmpty Dashed
dasheds <- Maybe (NonEmpty Dashed) -> [NonEmpty Dashed]
forall a. Maybe a -> [a]
maybeToList ([Dashed] -> Maybe (NonEmpty Dashed)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [Dashed]
setDocDasheds)
      ],
      [ [[Chunk]] -> [Chunk]
unwordsChunks
          [ [Chunk
"option:"],
            NonEmpty Dashed -> [Chunk]
dashedChunksNE NonEmpty Dashed
dasheds
              [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Chunk
" ", Maybe String -> Chunk
mMetavarChunk Maybe String
setDocMetavar]
          ]
        | Bool
setDocTryOption,
          NonEmpty Dashed
dasheds <- Maybe (NonEmpty Dashed) -> [NonEmpty Dashed]
forall a. Maybe a -> [a]
maybeToList ([Dashed] -> Maybe (NonEmpty Dashed)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [Dashed]
setDocDasheds)
      ],
      [ [[Chunk]] -> [Chunk]
unwordsChunks
          [ [Chunk
"env:"],
            NonEmpty String -> [Chunk]
envVarChunksNE NonEmpty String
vars
              [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Chunk
" ", Maybe String -> Chunk
mMetavarChunk Maybe String
setDocMetavar]
          ]
        | NonEmpty String
vars <- Maybe (NonEmpty String) -> [NonEmpty String]
forall a. Maybe a -> [a]
maybeToList Maybe (NonEmpty String)
setDocEnvVars
      ],
      [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ ((NonEmpty String, JSONSchema) -> [[Chunk]])
-> [(NonEmpty String, JSONSchema)] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
            ( \(NonEmpty String
key, JSONSchema
schema) ->
                case JSONSchema -> [[Chunk]]
jsonSchemaChunkLines JSONSchema
schema of
                  [[Chunk]
line] ->
                    [[Chunk
"config: ", NonEmpty String -> Chunk
confValChunk NonEmpty String
key, Chunk
": "] [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Chunk]
line]
                  [[Chunk]]
ls ->
                    [Chunk
"config:"]
                      [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
: [[Chunk]] -> [[Chunk]]
indent
                        ( case [[Chunk]]
ls of
                            [] -> [[Chunk
"TODO"]]
                            ([Chunk]
l : [[Chunk]]
ll) ->
                              ([NonEmpty String -> Chunk
confValChunk NonEmpty String
key, Chunk
": "] [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Chunk]
l)
                                [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
: [[Chunk]] -> [[Chunk]]
indent [[Chunk]]
ll
                        )
            )
            (NonEmpty (NonEmpty String, JSONSchema)
-> [(NonEmpty String, JSONSchema)]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (NonEmpty String, JSONSchema)
confs)
          | NonEmpty (NonEmpty String, JSONSchema)
confs <- Maybe (NonEmpty (NonEmpty String, JSONSchema))
-> [NonEmpty (NonEmpty String, JSONSchema)]
forall a. Maybe a -> [a]
maybeToList Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocConfKeys
        ],
      [ String -> [Chunk]
defaultValueChunks String
dv
        | String
dv <- Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList Maybe String
setDocDefault
      ],
      [ [String] -> [Chunk]
exampleValuesChunks [String]
setDocExamples
        | Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
setDocExamples)
      ]
    ]

helpLines :: Help -> [[Chunk]]
helpLines :: String -> [[Chunk]]
helpLines = ([Chunk] -> [Chunk]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> [a] -> [b]
map ((Chunk -> Chunk) -> [Chunk] -> [Chunk]
forall a b. (a -> b) -> [a] -> [b]
map (Colour -> Chunk -> Chunk
fore Colour
blue)) ([[Chunk]] -> [[Chunk]])
-> (String -> [[Chunk]]) -> String -> [[Chunk]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[Chunk]]
stringLines

progDescLines :: String -> [[Chunk]]
progDescLines :: String -> [[Chunk]]
progDescLines = String -> [[Chunk]]
stringLines

-- | Render the output of `--render-man-page` for reading with @man@
renderManPage ::
  String ->
  Version ->
  String ->
  AnyDocs (Maybe SetDoc) ->
  [Chunk]
renderManPage :: String -> Version -> String -> AnyDocs (Maybe SetDoc) -> [Chunk]
renderManPage String
progname Version
version String
progDesc AnyDocs (Maybe SetDoc)
docs' =
  let docs :: AnyDocs (Maybe SetDoc)
docs = Maybe Version -> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpAndVersionDocs (Version -> Maybe Version
forall a. a -> Maybe a
Just Version
version) AnyDocs (Maybe SetDoc)
docs'
      optDocs :: AnyDocs (Maybe OptDoc)
optDocs = AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs AnyDocs (Maybe SetDoc)
docs
      envDocs :: AnyDocs EnvDoc
envDocs = AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc
docsToEnvDocs AnyDocs (Maybe SetDoc)
docs
      confDocs :: AnyDocs ConfDoc
confDocs = AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc
docsToConfDocs AnyDocs (Maybe SetDoc)
docs
      commandDocs :: [CommandDoc (Maybe SetDoc)]
commandDocs = AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs AnyDocs (Maybe SetDoc)
docs
   in [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$
        -- See https://man.openbsd.org/mdoc#MACRO_OVERVIEW
        [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
          [ [ -- Document date
              [Chunk
".Dd $Mdocdate$"],
              -- Document title
              [Chunk
".Dt ", String -> Chunk
progNameChunk String
progname, Chunk
" 1"],
              -- Operating system footer
              [Chunk
".Os"],
              -- Section header
              [Chunk
".Sh ", Chunk
"NAME"],
              [Chunk
".Nm ", String -> Chunk
progNameChunk String
progname],
              [Chunk
".Nd ", Text -> Chunk
chunk (Text -> Chunk) -> Text -> Chunk
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
progDesc],
              [Chunk
".Sh ", Chunk
"VERSION"],
              [Version -> Chunk
versionChunk Version
version],
              [Chunk
".Sh ", Chunk
"SYNOPSIS"],
              String -> AnyDocs (Maybe OptDoc) -> [Chunk]
renderShortOptDocs String
progname (AnyDocs (Maybe OptDoc) -> [Chunk])
-> AnyDocs (Maybe OptDoc) -> [Chunk]
forall a b. (a -> b) -> a -> b
$ AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs AnyDocs (Maybe SetDoc)
docs',
              [Chunk
".Sh ", Chunk
"SETTINGS"],
              AnyDocs (Maybe SetDoc) -> [Chunk]
renderSetDocs AnyDocs (Maybe SetDoc)
docs
            ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ [Chunk
".Sh ", Chunk
"COMMANDS"],
                  AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocs AnyDocs (Maybe SetDoc)
docs
                ]
                | Bool -> Bool
not ([CommandDoc (Maybe SetDoc)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CommandDoc (Maybe SetDoc)]
commandDocs)
              ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ [Chunk
".Sh ", Chunk
"OPTIONS"],
                  AnyDocs (Maybe OptDoc) -> [Chunk]
renderLongOptDocs AnyDocs (Maybe OptDoc)
optDocs
                ]
                | Bool -> Bool
not (AnyDocs (Maybe OptDoc) -> Bool
forall a. AnyDocs a -> Bool
nullDocs AnyDocs (Maybe OptDoc)
optDocs)
              ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ [Chunk
".Sh ", Chunk
"ENVIRONMENT VARIABLES"],
                  AnyDocs EnvDoc -> [Chunk]
renderEnvDocs AnyDocs EnvDoc
envDocs
                ]
                | Bool -> Bool
not (AnyDocs EnvDoc -> Bool
forall a. AnyDocs a -> Bool
nullDocs AnyDocs EnvDoc
envDocs)
              ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ [Chunk
".Sh ", Chunk
"CONFIGURATION VALUES"],
                  AnyDocs ConfDoc -> [Chunk]
renderConfDocs AnyDocs ConfDoc
confDocs
                ]
                | Bool -> Bool
not (AnyDocs ConfDoc -> Bool
forall a. AnyDocs a -> Bool
nullDocs AnyDocs ConfDoc
confDocs)
              ]
          ]

-- | Render reference documentation
renderReferenceDocumentation :: String -> AnyDocs (Maybe SetDoc) -> [Chunk]
renderReferenceDocumentation :: String -> AnyDocs (Maybe SetDoc) -> [Chunk]
renderReferenceDocumentation String
progname AnyDocs (Maybe SetDoc)
docs' =
  let docs :: AnyDocs (Maybe SetDoc)
docs = Maybe Version -> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpAndVersionDocs Maybe Version
forall a. Maybe a
Nothing AnyDocs (Maybe SetDoc)
docs'
      optDocs :: AnyDocs (Maybe OptDoc)
optDocs = AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs AnyDocs (Maybe SetDoc)
docs
      envDocs :: AnyDocs EnvDoc
envDocs = AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc
docsToEnvDocs AnyDocs (Maybe SetDoc)
docs
      confDocs :: AnyDocs ConfDoc
confDocs = AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc
docsToConfDocs AnyDocs (Maybe SetDoc)
docs
      commandDocs :: [CommandDoc (Maybe SetDoc)]
commandDocs = AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs AnyDocs (Maybe SetDoc)
docs
   in [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$
        [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
          [ [ Chunk
usageChunk Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
: String -> AnyDocs (Maybe OptDoc) -> [Chunk]
renderShortOptDocs String
progname (AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs AnyDocs (Maybe SetDoc)
docs'),
              [],
              Text -> [Chunk]
headerChunks Text
"All settings",
              AnyDocs (Maybe SetDoc) -> [Chunk]
renderSetDocs AnyDocs (Maybe SetDoc)
docs
            ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ Text -> [Chunk]
headerChunks Text
"All commands",
                  AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocs AnyDocs (Maybe SetDoc)
docs
                ]
                | Bool -> Bool
not ([CommandDoc (Maybe SetDoc)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CommandDoc (Maybe SetDoc)]
commandDocs)
              ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ Text -> [Chunk]
headerChunks Text
"Options",
                  AnyDocs (Maybe OptDoc) -> [Chunk]
renderLongOptDocs AnyDocs (Maybe OptDoc)
optDocs
                ]
                | Bool -> Bool
not (AnyDocs (Maybe OptDoc) -> Bool
forall a. AnyDocs a -> Bool
nullDocs AnyDocs (Maybe OptDoc)
optDocs)
              ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ Text -> [Chunk]
headerChunks Text
"Environment Variables",
                  AnyDocs EnvDoc -> [Chunk]
renderEnvDocs AnyDocs EnvDoc
envDocs
                ]
                | Bool -> Bool
not (AnyDocs EnvDoc -> Bool
forall a. AnyDocs a -> Bool
nullDocs AnyDocs EnvDoc
envDocs)
              ],
            [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [ [ Text -> [Chunk]
headerChunks Text
"Configuration Values",
                  AnyDocs ConfDoc -> [Chunk]
renderConfDocs AnyDocs ConfDoc
confDocs
                ]
                | Bool -> Bool
not (AnyDocs ConfDoc -> Bool
forall a. AnyDocs a -> Bool
nullDocs AnyDocs ConfDoc
confDocs)
              ]
          ]

nullDocs :: AnyDocs a -> Bool
nullDocs :: forall a. AnyDocs a -> Bool
nullDocs = \case
  AnyDocsCommands Maybe String
_ [CommandDoc a]
cs -> (CommandDoc a -> Bool) -> [CommandDoc a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all CommandDoc a -> Bool
forall a. CommandDoc a -> Bool
nullCommandDoc [CommandDoc a]
cs
  AnyDocsOr [] -> Bool
True
  AnyDocsOr [AnyDocs a]
_ -> Bool
False
  AnyDocsAnd [] -> Bool
True
  AnyDocsAnd [AnyDocs a]
_ -> Bool
False
  AnyDocsSingle a
_ -> Bool
False
  where
    nullCommandDoc :: CommandDoc a -> Bool
    nullCommandDoc :: forall a. CommandDoc a -> Bool
nullCommandDoc = AnyDocs a -> Bool
forall a. AnyDocs a -> Bool
nullDocs (AnyDocs a -> Bool)
-> (CommandDoc a -> AnyDocs a) -> CommandDoc a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandDoc a -> AnyDocs a
forall a. CommandDoc a -> AnyDocs a
commandDocs

-- | Render the output of @--version@
renderVersionPage :: String -> Version -> [Chunk]
renderVersionPage :: String -> Version -> [Chunk]
renderVersionPage String
progname Version
version =
  [[Chunk]] -> [Chunk]
unwordsChunks
    [ [String -> Chunk
progNameChunk String
progname],
      [Version -> Chunk
versionChunk Version
version],
      [Chunk
"\n"]
    ]

-- | Render the output of top-level @--help@
renderHelpPage :: String -> Version -> String -> AnyDocs (Maybe SetDoc) -> [Chunk]
renderHelpPage :: String -> Version -> String -> AnyDocs (Maybe SetDoc) -> [Chunk]
renderHelpPage String
progname Version
version =
  String
-> [String]
-> Maybe Version
-> String
-> AnyDocs (Maybe SetDoc)
-> [Chunk]
renderHelpPageHelper String
progname [] (Version -> Maybe Version
forall a. a -> Maybe a
Just Version
version)

-- | Render the output of a @--help@ with at least one command
renderCommandHelpPage :: String -> [String] -> CommandDoc (Maybe SetDoc) -> [Chunk]
renderCommandHelpPage :: String -> [String] -> CommandDoc (Maybe SetDoc) -> [Chunk]
renderCommandHelpPage String
progname [String]
commandPath CommandDoc {String
AnyDocs (Maybe SetDoc)
commandDocArgument :: forall a. CommandDoc a -> String
commandDocHelp :: forall a. CommandDoc a -> String
commandDocs :: forall a. CommandDoc a -> AnyDocs a
commandDocArgument :: String
commandDocHelp :: String
commandDocs :: AnyDocs (Maybe SetDoc)
..} =
  String
-> [String]
-> Maybe Version
-> String
-> AnyDocs (Maybe SetDoc)
-> [Chunk]
renderHelpPageHelper
    String
progname
    ([String]
commandPath [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
commandDocArgument])
    Maybe Version
forall a. Maybe a
Nothing
    String
commandDocHelp
    AnyDocs (Maybe SetDoc)
commandDocs

renderHelpPageHelper :: String -> [String] -> Maybe Version -> String -> AnyDocs (Maybe SetDoc) -> [Chunk]
renderHelpPageHelper :: String
-> [String]
-> Maybe Version
-> String
-> AnyDocs (Maybe SetDoc)
-> [Chunk]
renderHelpPageHelper String
progname' [String]
commandPath Maybe Version
mVersion String
progDesc AnyDocs (Maybe SetDoc)
docs =
  [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$
    [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
      [ [ let progname :: String
progname = [String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ String
progname' String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
commandPath
           in Chunk
usageChunk Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
: String -> AnyDocs (Maybe OptDoc) -> [Chunk]
renderShortOptDocs String
progname (AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs AnyDocs (Maybe SetDoc)
docs),
          [],
          [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ String -> [[Chunk]]
progDescLines String
progDesc
        ],
        [ Text -> [Chunk]
headerChunks Text
"Available settings",
          AnyDocs (Maybe SetDoc) -> [Chunk]
renderSetDocs (AnyDocs (Maybe SetDoc) -> [Chunk])
-> AnyDocs (Maybe SetDoc) -> [Chunk]
forall a b. (a -> b) -> a -> b
$
            if [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
commandPath
              then Maybe Version -> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpAndVersionDocs Maybe Version
mVersion AnyDocs (Maybe SetDoc)
docs
              else AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpDocs AnyDocs (Maybe SetDoc)
docs
        ],
        [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
          [ [ Text -> [Chunk]
headerChunks Text
"Available commands",
              AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocsShort AnyDocs (Maybe SetDoc)
docs
            ]
            | Bool -> Bool
not ([CommandDoc (Maybe SetDoc)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs AnyDocs (Maybe SetDoc)
docs))
          ]
      ]

withHelpAndVersionDocs :: Maybe Version -> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpAndVersionDocs :: Maybe Version -> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpAndVersionDocs Maybe Version
mVersion AnyDocs (Maybe SetDoc)
sd = AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
forall a. AnyDocs a -> AnyDocs a
simplifyAnyDocs (AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc))
-> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
forall a b. (a -> b) -> a -> b
$ [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr [AnyDocs (Maybe SetDoc)
helpDocs, Maybe Version -> AnyDocs (Maybe SetDoc)
versionDocs Maybe Version
mVersion, AnyDocs (Maybe SetDoc)
sd]

withHelpDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
withHelpDocs AnyDocs (Maybe SetDoc)
sd = AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
forall a. AnyDocs a -> AnyDocs a
simplifyAnyDocs (AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc))
-> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe SetDoc)
forall a b. (a -> b) -> a -> b
$ [AnyDocs (Maybe SetDoc)] -> AnyDocs (Maybe SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr [AnyDocs (Maybe SetDoc)
helpDocs, AnyDocs (Maybe SetDoc)
sd]

helpDocs :: AnyDocs (Maybe SetDoc)
helpDocs :: AnyDocs (Maybe SetDoc)
helpDocs =
  Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle (Maybe SetDoc -> AnyDocs (Maybe SetDoc))
-> Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a b. (a -> b) -> a -> b
$
    SetDoc -> Maybe SetDoc
forall a. a -> Maybe a
Just
      SetDoc
        { setDocTryArgument :: Bool
setDocTryArgument = Bool
False,
          setDocTrySwitch :: Bool
setDocTrySwitch = Bool
True,
          setDocTryOption :: Bool
setDocTryOption = Bool
False,
          setDocDasheds :: [Dashed]
setDocDasheds = [Dashed
"-h", Dashed
"--help"],
          setDocEnvVars :: Maybe (NonEmpty String)
setDocEnvVars = Maybe (NonEmpty String)
forall a. Maybe a
Nothing,
          setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocConfKeys = Maybe (NonEmpty (NonEmpty String, JSONSchema))
forall a. Maybe a
Nothing,
          setDocDefault :: Maybe String
setDocDefault = Maybe String
forall a. Maybe a
Nothing,
          setDocExamples :: [String]
setDocExamples = [],
          setDocMetavar :: Maybe String
setDocMetavar = Maybe String
forall a. Maybe a
Nothing,
          setDocHelp :: Maybe String
setDocHelp = String -> Maybe String
forall a. a -> Maybe a
Just String
"Show this help text"
        }

versionDocs :: Maybe Version -> AnyDocs (Maybe SetDoc)
versionDocs :: Maybe Version -> AnyDocs (Maybe SetDoc)
versionDocs Maybe Version
mVersion =
  Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle (Maybe SetDoc -> AnyDocs (Maybe SetDoc))
-> Maybe SetDoc -> AnyDocs (Maybe SetDoc)
forall a b. (a -> b) -> a -> b
$
    SetDoc -> Maybe SetDoc
forall a. a -> Maybe a
Just
      SetDoc
        { setDocTryArgument :: Bool
setDocTryArgument = Bool
False,
          setDocTrySwitch :: Bool
setDocTrySwitch = Bool
True,
          setDocTryOption :: Bool
setDocTryOption = Bool
False,
          setDocDasheds :: [Dashed]
setDocDasheds = [Dashed
"--version"],
          setDocEnvVars :: Maybe (NonEmpty String)
setDocEnvVars = Maybe (NonEmpty String)
forall a. Maybe a
Nothing,
          setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocConfKeys = Maybe (NonEmpty (NonEmpty String, JSONSchema))
forall a. Maybe a
Nothing,
          setDocDefault :: Maybe String
setDocDefault = Maybe String
forall a. Maybe a
Nothing,
          setDocExamples :: [String]
setDocExamples = [],
          setDocMetavar :: Maybe String
setDocMetavar = Maybe String
forall a. Maybe a
Nothing,
          setDocHelp :: Maybe String
setDocHelp = String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ case Maybe Version
mVersion of
            Maybe Version
Nothing -> String
"Output version information"
            Just Version
version -> String
"Output version information: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Version -> String
showVersion Version
version
        }

renderSetDocs :: AnyDocs (Maybe SetDoc) -> [Chunk]
renderSetDocs :: AnyDocs (Maybe SetDoc) -> [Chunk]
renderSetDocs = [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk])
-> (AnyDocs (Maybe SetDoc) -> [[Chunk]])
-> AnyDocs (Maybe SetDoc)
-> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Chunk]] -> [[[Chunk]]] -> [[Chunk]]
forall a. [a] -> [[a]] -> [a]
intercalate [[]] ([[[Chunk]]] -> [[Chunk]])
-> (AnyDocs (Maybe SetDoc) -> [[[Chunk]]])
-> AnyDocs (Maybe SetDoc)
-> [[Chunk]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]]
go (AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]])
-> (AnyDocs (Maybe SetDoc) -> AnyDocs (NonEmpty SetDoc))
-> AnyDocs (Maybe SetDoc)
-> [[[Chunk]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
combineSetDocs (AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc))
-> (AnyDocs (Maybe SetDoc) -> AnyDocs SetDoc)
-> AnyDocs (Maybe SetDoc)
-> AnyDocs (NonEmpty SetDoc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs (Maybe SetDoc) -> AnyDocs SetDoc
forall a. AnyDocs (Maybe a) -> AnyDocs a
withoutHiddenDocs
  where
    -- One section each, so we can add empty lines inbetween
    go :: AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]]
    go :: AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]]
go = \case
      AnyDocsCommands Maybe String
_ [CommandDoc (NonEmpty SetDoc)]
_ -> []
      AnyDocsAnd [AnyDocs (NonEmpty SetDoc)]
ds -> (AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]])
-> [AnyDocs (NonEmpty SetDoc)] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]]
go [AnyDocs (NonEmpty SetDoc)]
ds
      AnyDocsOr [AnyDocs (NonEmpty SetDoc)]
ds -> (AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]])
-> [AnyDocs (NonEmpty SetDoc)] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs (NonEmpty SetDoc) -> [[[Chunk]]]
go [AnyDocs (NonEmpty SetDoc)]
ds
      AnyDocsSingle (SetDoc
d :| [SetDoc]
ds) ->
        [ [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
            [ [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ Maybe String -> [[Chunk]]
renderSetDocHeader (SetDoc -> Maybe String
setDocHelp SetDoc
d),
              [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ (SetDoc -> [[Chunk]]) -> [SetDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap SetDoc -> [[Chunk]]
renderSetDocWithoutHeader (SetDoc
d SetDoc -> [SetDoc] -> [SetDoc]
forall a. a -> [a] -> [a]
: [SetDoc]
ds)
            ]
        ]

    goSameHelp :: Help -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
    goSameHelp :: String -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
goSameHelp String
h = \case
      [] -> ([], [])
      (AnyDocsSingle SetDoc
d : [AnyDocs SetDoc]
ds) ->
        if SetDoc -> Maybe String
setDocHelp SetDoc
d Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just String
h
          then
            let ([SetDoc]
sds, [AnyDocs SetDoc]
rest) = String -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
goSameHelp String
h [AnyDocs SetDoc]
ds
             in (SetDoc
d SetDoc -> [SetDoc] -> [SetDoc]
forall a. a -> [a] -> [a]
: [SetDoc]
sds, [AnyDocs SetDoc]
rest)
          else ([], SetDoc -> AnyDocs SetDoc
forall a. a -> AnyDocs a
AnyDocsSingle SetDoc
d AnyDocs SetDoc -> [AnyDocs SetDoc] -> [AnyDocs SetDoc]
forall a. a -> [a] -> [a]
: [AnyDocs SetDoc]
ds)
      [AnyDocs SetDoc]
ds -> ([], [AnyDocs SetDoc]
ds)

    -- Group together settings with the same help (produced by combinators like enableDisableSwitch)
    combineSetDocs :: AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
    combineSetDocs :: AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
combineSetDocs = AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
go'
      where
        go' :: AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
        go' :: AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
go' = \case
          AnyDocsCommands Maybe String
_ [CommandDoc SetDoc]
_ -> Maybe String
-> [CommandDoc (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc)
forall a. Maybe String -> [CommandDoc a] -> AnyDocs a
AnyDocsCommands Maybe String
forall a. Maybe a
Nothing [] -- Don't care about commands here
          AnyDocsOr [AnyDocs SetDoc]
ds -> [AnyDocs (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr ([AnyDocs (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc))
-> [AnyDocs (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc)
forall a b. (a -> b) -> a -> b
$ [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
goOr' [AnyDocs SetDoc]
ds
          AnyDocsAnd [AnyDocs SetDoc]
ds -> [AnyDocs (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc)
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd ([AnyDocs (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc))
-> [AnyDocs (NonEmpty SetDoc)] -> AnyDocs (NonEmpty SetDoc)
forall a b. (a -> b) -> a -> b
$ (AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc))
-> [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
forall a b. (a -> b) -> [a] -> [b]
map AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
go' [AnyDocs SetDoc]
ds
          AnyDocsSingle SetDoc
d -> NonEmpty SetDoc -> AnyDocs (NonEmpty SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle (SetDoc
d SetDoc -> [SetDoc] -> NonEmpty SetDoc
forall a. a -> [a] -> NonEmpty a
:| [])
        goOr' :: [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
        goOr' :: [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
goOr' = \case
          [] -> []
          [AnyDocs SetDoc
d] -> [AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
go' AnyDocs SetDoc
d]
          (AnyDocsSingle SetDoc
d : [AnyDocs SetDoc]
ds) ->
            case SetDoc -> Maybe String
setDocHelp SetDoc
d of
              Maybe String
Nothing -> AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
go' (SetDoc -> AnyDocs SetDoc
forall a. a -> AnyDocs a
AnyDocsSingle SetDoc
d) AnyDocs (NonEmpty SetDoc)
-> [AnyDocs (NonEmpty SetDoc)] -> [AnyDocs (NonEmpty SetDoc)]
forall a. a -> [a] -> [a]
: [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
goOr' [AnyDocs SetDoc]
ds
              Just String
h ->
                let ([SetDoc]
sds, [AnyDocs SetDoc]
rest) = String -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
goSameHelp String
h [AnyDocs SetDoc]
ds
                    ne :: NonEmpty SetDoc
ne = SetDoc
d SetDoc -> [SetDoc] -> NonEmpty SetDoc
forall a. a -> [a] -> NonEmpty a
:| [SetDoc]
sds
                 in NonEmpty SetDoc -> AnyDocs (NonEmpty SetDoc)
forall a. a -> AnyDocs a
AnyDocsSingle NonEmpty SetDoc
ne AnyDocs (NonEmpty SetDoc)
-> [AnyDocs (NonEmpty SetDoc)] -> [AnyDocs (NonEmpty SetDoc)]
forall a. a -> [a] -> [a]
: [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
goOr' [AnyDocs SetDoc]
rest
          (AnyDocs SetDoc
d : [AnyDocs SetDoc]
ds) -> AnyDocs SetDoc -> AnyDocs (NonEmpty SetDoc)
go' AnyDocs SetDoc
d AnyDocs (NonEmpty SetDoc)
-> [AnyDocs (NonEmpty SetDoc)] -> [AnyDocs (NonEmpty SetDoc)]
forall a. a -> [a] -> [a]
: [AnyDocs SetDoc] -> [AnyDocs (NonEmpty SetDoc)]
goOr' [AnyDocs SetDoc]
ds

renderCommandDocs :: AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocs :: AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocs = [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk])
-> (AnyDocs (Maybe SetDoc) -> [[Chunk]])
-> AnyDocs (Maybe SetDoc)
-> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
True (AnyDocs SetDoc -> [[Chunk]])
-> (AnyDocs (Maybe SetDoc) -> AnyDocs SetDoc)
-> AnyDocs (Maybe SetDoc)
-> [[Chunk]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs (Maybe SetDoc) -> AnyDocs SetDoc
forall a. AnyDocs (Maybe a) -> AnyDocs a
withoutHiddenDocs
  where
    go :: Bool -> AnyDocs SetDoc -> [[Chunk]]
    go :: Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
isTopLevel = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc SetDoc]
cs -> (CommandDoc SetDoc -> [[Chunk]])
-> [CommandDoc SetDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Maybe String -> CommandDoc SetDoc -> [[Chunk]]
goCommand Maybe String
mDefault) [CommandDoc SetDoc]
cs
      AnyDocsAnd [AnyDocs SetDoc]
ds -> (AnyDocs SetDoc -> [[Chunk]]) -> [AnyDocs SetDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
isTopLevel) [AnyDocs SetDoc]
ds
      AnyDocsOr [AnyDocs SetDoc]
ds -> Bool -> [AnyDocs SetDoc] -> [[Chunk]]
goOr Bool
isTopLevel [AnyDocs SetDoc]
ds
      AnyDocsSingle SetDoc
d
        | Bool
isTopLevel -> []
        | Bool
otherwise -> [[Chunk]] -> [[Chunk]]
indent (SetDoc -> [[Chunk]]
renderSetDoc SetDoc
d)

    goCommand :: Maybe String -> CommandDoc SetDoc -> [[Chunk]]
    goCommand :: Maybe String -> CommandDoc SetDoc -> [[Chunk]]
goCommand Maybe String
mDefault CommandDoc {String
AnyDocs SetDoc
commandDocArgument :: forall a. CommandDoc a -> String
commandDocHelp :: forall a. CommandDoc a -> String
commandDocs :: forall a. CommandDoc a -> AnyDocs a
commandDocArgument :: String
commandDocHelp :: String
commandDocs :: AnyDocs SetDoc
..} =
      [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$
        let isDefault :: Bool
isDefault = Maybe String
mDefault Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just String
commandDocArgument
            suffix :: Chunk
suffix = if Bool
isDefault then Chunk
" (default)" else Chunk
""
         in [String -> Chunk
helpChunk String
commandDocHelp]
              [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
: [Chunk
"command: ", String -> Chunk
commandChunk String
commandDocArgument, Chunk
suffix]
              [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
: Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
False AnyDocs SetDoc
commandDocs
              [[Chunk]] -> [[Chunk]] -> [[Chunk]]
forall a. [a] -> [a] -> [a]
++ [[]]

    -- Group together settings with the same help (produced by combinators like enableDisableSwitch)
    goOr :: Bool -> [AnyDocs SetDoc] -> [[Chunk]]
    goOr :: Bool -> [AnyDocs SetDoc] -> [[Chunk]]
goOr Bool
isTopLevel = \case
      [] -> []
      [AnyDocs SetDoc
d] -> Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
isTopLevel AnyDocs SetDoc
d
      (AnyDocsSingle SetDoc
d : [AnyDocs SetDoc]
ds) ->
        case SetDoc -> Maybe String
setDocHelp SetDoc
d of
          Maybe String
Nothing -> Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
isTopLevel (SetDoc -> AnyDocs SetDoc
forall a. a -> AnyDocs a
AnyDocsSingle SetDoc
d) [[Chunk]] -> [[Chunk]] -> [[Chunk]]
forall a. [a] -> [a] -> [a]
++ Bool -> [AnyDocs SetDoc] -> [[Chunk]]
goOr Bool
isTopLevel [AnyDocs SetDoc]
ds
          Just String
h ->
            let ([SetDoc]
sds, [AnyDocs SetDoc]
rest) = String -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
goSameHelp String
h [AnyDocs SetDoc]
ds
             in [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                  [ [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                      [ [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                          [ [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ Maybe String -> [[Chunk]]
renderSetDocHeader (String -> Maybe String
forall a. a -> Maybe a
Just String
h),
                            [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ (SetDoc -> [[Chunk]]) -> [SetDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap SetDoc -> [[Chunk]]
renderSetDocWithoutHeader ([SetDoc] -> [[Chunk]]) -> [SetDoc] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ SetDoc
d SetDoc -> [SetDoc] -> [SetDoc]
forall a. a -> [a] -> [a]
: [SetDoc]
sds,
                            [[]]
                          ]
                        | Bool -> Bool
not Bool
isTopLevel
                      ],
                    Bool -> [AnyDocs SetDoc] -> [[Chunk]]
goOr Bool
isTopLevel [AnyDocs SetDoc]
rest
                  ]
      (AnyDocs SetDoc
d : [AnyDocs SetDoc]
ds) -> Bool -> AnyDocs SetDoc -> [[Chunk]]
go Bool
isTopLevel AnyDocs SetDoc
d [[Chunk]] -> [[Chunk]] -> [[Chunk]]
forall a. [a] -> [a] -> [a]
++ Bool -> [AnyDocs SetDoc] -> [[Chunk]]
goOr Bool
isTopLevel [AnyDocs SetDoc]
ds
    goSameHelp :: Help -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
    goSameHelp :: String -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
goSameHelp String
h = \case
      [] -> ([], [])
      (AnyDocsSingle SetDoc
d : [AnyDocs SetDoc]
ds) ->
        if SetDoc -> Maybe String
setDocHelp SetDoc
d Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just String
h
          then
            let ([SetDoc]
sds, [AnyDocs SetDoc]
rest) = String -> [AnyDocs SetDoc] -> ([SetDoc], [AnyDocs SetDoc])
goSameHelp String
h [AnyDocs SetDoc]
ds
             in (SetDoc
d SetDoc -> [SetDoc] -> [SetDoc]
forall a. a -> [a] -> [a]
: [SetDoc]
sds, [AnyDocs SetDoc]
rest)
          else ([], SetDoc -> AnyDocs SetDoc
forall a. a -> AnyDocs a
AnyDocsSingle SetDoc
d AnyDocs SetDoc -> [AnyDocs SetDoc] -> [AnyDocs SetDoc]
forall a. a -> [a] -> [a]
: [AnyDocs SetDoc]
ds)
      [AnyDocs SetDoc]
ds -> ([], [AnyDocs SetDoc]
ds)

renderCommandDocsShort :: AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocsShort :: AnyDocs (Maybe SetDoc) -> [Chunk]
renderCommandDocsShort = [[[Chunk]]] -> [Chunk]
layoutAsTable ([[[Chunk]]] -> [Chunk])
-> (AnyDocs (Maybe SetDoc) -> [[[Chunk]]])
-> AnyDocs (Maybe SetDoc)
-> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs SetDoc -> [[[Chunk]]]
go (AnyDocs SetDoc -> [[[Chunk]]])
-> (AnyDocs (Maybe SetDoc) -> AnyDocs SetDoc)
-> AnyDocs (Maybe SetDoc)
-> [[[Chunk]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs (Maybe SetDoc) -> AnyDocs SetDoc
forall a. AnyDocs (Maybe a) -> AnyDocs a
withoutHiddenDocs
  where
    go :: AnyDocs SetDoc -> [[[Chunk]]]
    go :: AnyDocs SetDoc -> [[[Chunk]]]
go = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc SetDoc]
cs -> (CommandDoc SetDoc -> [[[Chunk]]])
-> [CommandDoc SetDoc] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Maybe String -> CommandDoc SetDoc -> [[[Chunk]]]
goCommand Maybe String
mDefault) [CommandDoc SetDoc]
cs
      AnyDocsAnd [AnyDocs SetDoc]
ds -> (AnyDocs SetDoc -> [[[Chunk]]]) -> [AnyDocs SetDoc] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs SetDoc -> [[[Chunk]]]
go [AnyDocs SetDoc]
ds
      AnyDocsOr [AnyDocs SetDoc]
ds -> (AnyDocs SetDoc -> [[[Chunk]]]) -> [AnyDocs SetDoc] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs SetDoc -> [[[Chunk]]]
go [AnyDocs SetDoc]
ds
      AnyDocsSingle SetDoc
_ -> []

    goCommand :: Maybe String -> CommandDoc SetDoc -> [[[Chunk]]]
    goCommand :: Maybe String -> CommandDoc SetDoc -> [[[Chunk]]]
goCommand Maybe String
mDefault CommandDoc {String
AnyDocs SetDoc
commandDocArgument :: forall a. CommandDoc a -> String
commandDocHelp :: forall a. CommandDoc a -> String
commandDocs :: forall a. CommandDoc a -> AnyDocs a
commandDocArgument :: String
commandDocHelp :: String
commandDocs :: AnyDocs SetDoc
..} =
      let isDefault :: Bool
isDefault = Maybe String
mDefault Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just String
commandDocArgument
          suffix :: Chunk
suffix = if Bool
isDefault then Chunk
" (default)" else Chunk
""
       in [[[Chunk]] -> [[Chunk]]
indent [[String -> Chunk
commandChunk String
commandDocArgument, Chunk
suffix], [String -> Chunk
helpChunk String
commandDocHelp]]]

parserOptDocs :: Parser a -> AnyDocs (Maybe OptDoc)
parserOptDocs :: forall a. Parser a -> AnyDocs (Maybe OptDoc)
parserOptDocs = AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs (AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc))
-> (Parser a -> AnyDocs (Maybe SetDoc))
-> Parser a
-> AnyDocs (Maybe OptDoc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
parserDocs

docsToOptDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
docsToOptDocs = (Maybe SetDoc -> Maybe (Maybe OptDoc))
-> AnyDocs (Maybe SetDoc) -> AnyDocs (Maybe OptDoc)
forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs (Maybe SetDoc
-> (SetDoc -> Maybe (Maybe OptDoc)) -> Maybe (Maybe OptDoc)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe OptDoc -> Maybe (Maybe OptDoc)
forall a. a -> Maybe a
Just (Maybe OptDoc -> Maybe (Maybe OptDoc))
-> (SetDoc -> Maybe OptDoc) -> SetDoc -> Maybe (Maybe OptDoc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SetDoc -> Maybe OptDoc
setDocOptDoc)

setDocOptDoc :: SetDoc -> Maybe OptDoc
setDocOptDoc :: SetDoc -> Maybe OptDoc
setDocOptDoc SetDoc {Bool
[String]
[Dashed]
Maybe String
Maybe (NonEmpty String)
Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocTryArgument :: SetDoc -> Bool
setDocTrySwitch :: SetDoc -> Bool
setDocTryOption :: SetDoc -> Bool
setDocDasheds :: SetDoc -> [Dashed]
setDocEnvVars :: SetDoc -> Maybe (NonEmpty String)
setDocConfKeys :: SetDoc -> Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: SetDoc -> Maybe String
setDocExamples :: SetDoc -> [String]
setDocMetavar :: SetDoc -> Maybe String
setDocHelp :: SetDoc -> Maybe String
setDocTryArgument :: Bool
setDocTrySwitch :: Bool
setDocTryOption :: Bool
setDocDasheds :: [Dashed]
setDocEnvVars :: Maybe (NonEmpty String)
setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: Maybe String
setDocExamples :: [String]
setDocMetavar :: Maybe String
setDocHelp :: Maybe String
..} = do
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Bool
setDocTryArgument Bool -> Bool -> Bool
|| Bool
setDocTrySwitch Bool -> Bool -> Bool
|| Bool
setDocTryOption
  let optDocTryArgument :: Bool
optDocTryArgument = Bool
setDocTryArgument
      optDocTrySwitch :: Bool
optDocTrySwitch = Bool
setDocTrySwitch
      optDocTryOption :: Bool
optDocTryOption = Bool
setDocTryOption
      optDocDasheds :: [Dashed]
optDocDasheds = [Dashed]
setDocDasheds
      optDocDefault :: Maybe String
optDocDefault = Maybe String
setDocDefault
      optDocExamples :: [String]
optDocExamples = [String]
setDocExamples
      optDocMetavar :: Maybe String
optDocMetavar = Maybe String
setDocMetavar
      optDocHelp :: Maybe String
optDocHelp = Maybe String
setDocHelp
  pure OptDoc {Bool
[String]
[Dashed]
Maybe String
optDocTryArgument :: Bool
optDocTrySwitch :: Bool
optDocTryOption :: Bool
optDocDasheds :: [Dashed]
optDocDefault :: Maybe String
optDocExamples :: [String]
optDocMetavar :: Maybe String
optDocHelp :: Maybe String
optDocTryArgument :: Bool
optDocTrySwitch :: Bool
optDocTryOption :: Bool
optDocDasheds :: [Dashed]
optDocDefault :: Maybe String
optDocExamples :: [String]
optDocMetavar :: Maybe String
optDocHelp :: Maybe String
..}

-- | Render short-form documentation of options
renderShortOptDocs :: String -> AnyDocs (Maybe OptDoc) -> [Chunk]
renderShortOptDocs :: String -> AnyDocs (Maybe OptDoc) -> [Chunk]
renderShortOptDocs String
progname = [[Chunk]] -> [Chunk]
unwordsChunks ([[Chunk]] -> [Chunk])
-> (AnyDocs (Maybe OptDoc) -> [[Chunk]])
-> AnyDocs (Maybe OptDoc)
-> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\[Chunk]
cs -> [[String -> Chunk
progNameChunk String
progname], [Chunk]
cs]) ([Chunk] -> [[Chunk]])
-> (AnyDocs (Maybe OptDoc) -> [Chunk])
-> AnyDocs (Maybe OptDoc)
-> [[Chunk]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Chunk] -> Maybe [Chunk] -> [Chunk]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [Chunk] -> [Chunk])
-> (AnyDocs (Maybe OptDoc) -> Maybe [Chunk])
-> AnyDocs (Maybe OptDoc)
-> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> AnyDocs (Maybe OptDoc) -> Maybe [Chunk]
go Bool
False
  where
    withoutNothings :: [AnyDocs (Maybe a)] -> [AnyDocs (Maybe a)]
withoutNothings =
      (AnyDocs (Maybe a) -> Bool)
-> [AnyDocs (Maybe a)] -> [AnyDocs (Maybe a)]
forall a. (a -> Bool) -> [a] -> [a]
filter
        ( \case
            AnyDocsSingle Maybe a
Nothing -> Bool
False
            AnyDocsAnd [] -> Bool
False
            AnyDocsOr [] -> Bool
False
            AnyDocs (Maybe a)
_ -> Bool
True
        )
    go ::
      -- Need parens
      Bool ->
      AnyDocs (Maybe OptDoc) ->
      Maybe [Chunk]
    go :: Bool -> AnyDocs (Maybe OptDoc) -> Maybe [Chunk]
go Bool
b =
      \case
        AnyDocsCommands Maybe String
mDefault [CommandDoc (Maybe OptDoc)]
_ -> case Maybe String
mDefault of
          Maybe String
Nothing -> [Chunk] -> Maybe [Chunk]
forall a. a -> Maybe a
Just [Chunk
"COMMAND"]
          Just String
_ -> [Chunk] -> Maybe [Chunk]
forall a. a -> Maybe a
Just [Chunk
"[COMMAND]"]
        AnyDocsAnd [AnyDocs (Maybe OptDoc)]
ds ->
          case (AnyDocs (Maybe OptDoc) -> Maybe [Chunk])
-> [AnyDocs (Maybe OptDoc)] -> [[Chunk]]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Bool -> AnyDocs (Maybe OptDoc) -> Maybe [Chunk]
go Bool
False) ([AnyDocs (Maybe OptDoc)] -> [AnyDocs (Maybe OptDoc)]
forall {a}. [AnyDocs (Maybe a)] -> [AnyDocs (Maybe a)]
withoutNothings [AnyDocs (Maybe OptDoc)]
ds) of
            [] -> Maybe [Chunk]
forall a. Maybe a
Nothing
            [[Chunk]
c] -> [Chunk] -> Maybe [Chunk]
forall a. a -> Maybe a
Just [Chunk]
c
            [[Chunk]]
cs -> [Chunk] -> Maybe [Chunk]
forall a. a -> Maybe a
Just ([Chunk] -> Maybe [Chunk]) -> [Chunk] -> Maybe [Chunk]
forall a b. (a -> b) -> a -> b
$ (if Bool
b then [Chunk] -> [Chunk]
parenthesise else [Chunk] -> [Chunk]
forall a. a -> a
id) ([Chunk] -> [Chunk]) -> [Chunk] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ [[Chunk]] -> [Chunk]
unwordsChunks [[Chunk]]
cs
        AnyDocsOr [AnyDocs (Maybe OptDoc)]
ds ->
          case (AnyDocs (Maybe OptDoc) -> Maybe [Chunk])
-> [AnyDocs (Maybe OptDoc)] -> [[Chunk]]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Bool -> AnyDocs (Maybe OptDoc) -> Maybe [Chunk]
go Bool
False) ([AnyDocs (Maybe OptDoc)] -> [AnyDocs (Maybe OptDoc)]
forall {a}. [AnyDocs (Maybe a)] -> [AnyDocs (Maybe a)]
withoutNothings [AnyDocs (Maybe OptDoc)]
ds) of
            [] -> Maybe [Chunk]
forall a. Maybe a
Nothing
            [[Chunk]]
cs -> [Chunk] -> Maybe [Chunk]
forall a. a -> Maybe a
Just ([Chunk] -> Maybe [Chunk]) -> [Chunk] -> Maybe [Chunk]
forall a b. (a -> b) -> a -> b
$ [Chunk] -> [Chunk]
bracketise ([Chunk] -> [Chunk]) -> [Chunk] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ [[Chunk]] -> [Chunk]
unwordsChunks ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
intersperse [Chunk
orChunk] [[Chunk]]
cs
        AnyDocsSingle Maybe OptDoc
mOd -> case Maybe OptDoc
mOd of
          Maybe OptDoc
Nothing -> Maybe [Chunk]
forall a. Maybe a
Nothing
          Just OptDoc {Bool
[String]
[Dashed]
Maybe String
optDocTryArgument :: OptDoc -> Bool
optDocTrySwitch :: OptDoc -> Bool
optDocTryOption :: OptDoc -> Bool
optDocDasheds :: OptDoc -> [Dashed]
optDocDefault :: OptDoc -> Maybe String
optDocExamples :: OptDoc -> [String]
optDocMetavar :: OptDoc -> Maybe String
optDocHelp :: OptDoc -> Maybe String
optDocTryArgument :: Bool
optDocTrySwitch :: Bool
optDocTryOption :: Bool
optDocDasheds :: [Dashed]
optDocDefault :: Maybe String
optDocExamples :: [String]
optDocMetavar :: Maybe String
optDocHelp :: Maybe String
..} ->
            [Chunk] -> Maybe [Chunk]
forall a. a -> Maybe a
Just
              ([Chunk] -> Maybe [Chunk]) -> [Chunk] -> Maybe [Chunk]
forall a b. (a -> b) -> a -> b
$ ( if Maybe String -> Bool
forall a. Maybe a -> Bool
isJust Maybe String
optDocDefault
                    then [Chunk] -> [Chunk]
bracketise
                    else [Chunk] -> [Chunk]
forall a. a -> a
id
                )
              ([Chunk] -> [Chunk]) -> [Chunk] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ [[Chunk]] -> [Chunk]
unwordsChunks
              ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                [ [ [Maybe String -> Chunk
mMetavarChunk Maybe String
optDocMetavar]
                    | Bool
optDocTryArgument
                  ],
                  [ [[Chunk]] -> [Chunk]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ Maybe [Chunk] -> [[Chunk]]
forall a. Maybe a -> [a]
maybeToList (Maybe [Chunk] -> [[Chunk]]) -> Maybe [Chunk] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ [Dashed] -> Maybe [Chunk]
dashedChunks [Dashed]
optDocDasheds
                    | Bool
optDocTrySwitch
                  ],
                  [ [[Chunk]] -> [Chunk]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                      [ [[Chunk]] -> [Chunk]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$ Maybe [Chunk] -> [[Chunk]]
forall a. Maybe a -> [a]
maybeToList (Maybe [Chunk] -> [[Chunk]]) -> Maybe [Chunk] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ [Dashed] -> Maybe [Chunk]
dashedChunks [Dashed]
optDocDasheds,
                        [Chunk
" ", Maybe String -> Chunk
mMetavarChunk Maybe String
optDocMetavar]
                      ]
                    | Bool
optDocTryOption
                  ]
                ]

orChunk :: Chunk
orChunk :: Chunk
orChunk = Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"|"

-- | Render long-form documentation of options
renderLongOptDocs :: AnyDocs (Maybe OptDoc) -> [Chunk]
renderLongOptDocs :: AnyDocs (Maybe OptDoc) -> [Chunk]
renderLongOptDocs = [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk])
-> (AnyDocs (Maybe OptDoc) -> [[Chunk]])
-> AnyDocs (Maybe OptDoc)
-> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs OptDoc -> [[Chunk]]
go (AnyDocs OptDoc -> [[Chunk]])
-> (AnyDocs (Maybe OptDoc) -> AnyDocs OptDoc)
-> AnyDocs (Maybe OptDoc)
-> [[Chunk]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs (Maybe OptDoc) -> AnyDocs OptDoc
forall a. AnyDocs (Maybe a) -> AnyDocs a
withoutHiddenDocs
  where
    go :: AnyDocs OptDoc -> [[Chunk]]
    go :: AnyDocs OptDoc -> [[Chunk]]
go = \case
      AnyDocsCommands Maybe String
mDefault [CommandDoc OptDoc]
cs ->
        (CommandDoc OptDoc -> [[Chunk]])
-> [CommandDoc OptDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
          ( \CommandDoc {String
AnyDocs OptDoc
commandDocArgument :: forall a. CommandDoc a -> String
commandDocHelp :: forall a. CommandDoc a -> String
commandDocs :: forall a. CommandDoc a -> AnyDocs a
commandDocArgument :: String
commandDocHelp :: String
commandDocs :: AnyDocs OptDoc
..} ->
              let isDefault :: Bool
isDefault = Maybe String
mDefault Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just String
commandDocArgument
                  suffix :: Chunk
suffix = if Bool
isDefault then Chunk
" (default)" else Chunk
""
               in [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$
                    [[Chunk]] -> [Chunk]
unwordsChunks [[String -> Chunk
commandChunk String
commandDocArgument, Chunk
suffix], [String -> Chunk
helpChunk String
commandDocHelp]]
                      [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
: [[Chunk]] -> [[Chunk]]
indent (AnyDocs OptDoc -> [[Chunk]]
go AnyDocs OptDoc
commandDocs)
          )
          [CommandDoc OptDoc]
cs
      AnyDocsAnd [AnyDocs OptDoc]
ds -> case AnyDocs OptDoc -> Maybe [[[Chunk]]]
goTable ([AnyDocs OptDoc] -> AnyDocs OptDoc
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsAnd [AnyDocs OptDoc]
ds) of
        Maybe [[[Chunk]]]
Nothing -> (AnyDocs OptDoc -> [[Chunk]]) -> [AnyDocs OptDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs OptDoc -> [[Chunk]]
go [AnyDocs OptDoc]
ds
        Just [[[Chunk]]]
csss -> [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ [[[Chunk]]] -> [[Chunk]]
layoutAsTableLines [[[Chunk]]]
csss
      AnyDocsOr [AnyDocs OptDoc]
ds -> case AnyDocs OptDoc -> Maybe [[[Chunk]]]
goTable ([AnyDocs OptDoc] -> AnyDocs OptDoc
forall a. [AnyDocs a] -> AnyDocs a
AnyDocsOr [AnyDocs OptDoc]
ds) of
        Maybe [[[Chunk]]]
Nothing -> (AnyDocs OptDoc -> [[Chunk]]) -> [AnyDocs OptDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs OptDoc -> [[Chunk]]
go [AnyDocs OptDoc]
ds
        Just [[[Chunk]]]
csss -> [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ [[[Chunk]]] -> [[Chunk]]
layoutAsTableLines [[[Chunk]]]
csss
      AnyDocsSingle OptDoc
vs -> [[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ [[[Chunk]]] -> [[Chunk]]
layoutAsTableLines [OptDoc -> [[Chunk]]
renderOptDocLong OptDoc
vs]

    goTable :: AnyDocs OptDoc -> Maybe [[[Chunk]]]
    goTable :: AnyDocs OptDoc -> Maybe [[[Chunk]]]
goTable = \case
      AnyDocsCommands Maybe String
_ [CommandDoc OptDoc]
_ -> Maybe [[[Chunk]]]
forall a. Maybe a
Nothing
      AnyDocsAnd [AnyDocs OptDoc]
ds -> [[[[Chunk]]]] -> [[[Chunk]]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[[[Chunk]]]] -> [[[Chunk]]])
-> Maybe [[[[Chunk]]]] -> Maybe [[[Chunk]]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (AnyDocs OptDoc -> Maybe [[[Chunk]]])
-> [AnyDocs OptDoc] -> Maybe [[[[Chunk]]]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM AnyDocs OptDoc -> Maybe [[[Chunk]]]
goTable [AnyDocs OptDoc]
ds
      AnyDocsOr [AnyDocs OptDoc]
ds -> [[[[Chunk]]]] -> [[[Chunk]]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[[[Chunk]]]] -> [[[Chunk]]])
-> Maybe [[[[Chunk]]]] -> Maybe [[[Chunk]]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (AnyDocs OptDoc -> Maybe [[[Chunk]]])
-> [AnyDocs OptDoc] -> Maybe [[[[Chunk]]]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM AnyDocs OptDoc -> Maybe [[[Chunk]]]
goTable [AnyDocs OptDoc]
ds
      AnyDocsSingle OptDoc
od -> [[[Chunk]]] -> Maybe [[[Chunk]]]
forall a. a -> Maybe a
Just [OptDoc -> [[Chunk]]
renderOptDocLong OptDoc
od]

renderOptDocLong :: OptDoc -> [[Chunk]]
renderOptDocLong :: OptDoc -> [[Chunk]]
renderOptDocLong OptDoc {Bool
[String]
[Dashed]
Maybe String
optDocTryArgument :: OptDoc -> Bool
optDocTrySwitch :: OptDoc -> Bool
optDocTryOption :: OptDoc -> Bool
optDocDasheds :: OptDoc -> [Dashed]
optDocDefault :: OptDoc -> Maybe String
optDocExamples :: OptDoc -> [String]
optDocMetavar :: OptDoc -> Maybe String
optDocHelp :: OptDoc -> Maybe String
optDocTryArgument :: Bool
optDocTrySwitch :: Bool
optDocTryOption :: Bool
optDocDasheds :: [Dashed]
optDocDefault :: Maybe String
optDocExamples :: [String]
optDocMetavar :: Maybe String
optDocHelp :: Maybe String
..} =
  [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ [ [[Chunk]] -> [Chunk]
unwordsChunks ([[Chunk]] -> [Chunk]) -> [[Chunk]] -> [Chunk]
forall a b. (a -> b) -> a -> b
$
          [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
            [ Maybe [Chunk] -> [[Chunk]]
forall a. Maybe a -> [a]
maybeToList (Maybe [Chunk] -> [[Chunk]]) -> Maybe [Chunk] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ [Dashed] -> Maybe [Chunk]
dashedChunks [Dashed]
optDocDasheds,
              [ [ Maybe String -> Chunk
mMetavarChunk Maybe String
optDocMetavar
                ]
                | Bool
optDocTryArgument
              ]
            ],
        [Maybe String -> Chunk
mHelpChunk Maybe String
optDocHelp]
      ],
      [String -> [Chunk]
defaultValueChunks String
d | String
d <- Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList Maybe String
optDocDefault],
      [[String] -> [Chunk]
exampleValuesChunks [String]
optDocExamples | Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
optDocExamples)]
    ]

parserEnvDocs :: Parser a -> AnyDocs EnvDoc
parserEnvDocs :: forall a. Parser a -> AnyDocs EnvDoc
parserEnvDocs = AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc
docsToEnvDocs (AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc)
-> (Parser a -> AnyDocs (Maybe SetDoc))
-> Parser a
-> AnyDocs EnvDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
parserDocs

docsToEnvDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc
docsToEnvDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc
docsToEnvDocs = (Maybe SetDoc -> Maybe EnvDoc)
-> AnyDocs (Maybe SetDoc) -> AnyDocs EnvDoc
forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs (Maybe SetDoc -> (SetDoc -> Maybe EnvDoc) -> Maybe EnvDoc
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SetDoc -> Maybe EnvDoc
setDocEnvDoc)

setDocEnvDoc :: SetDoc -> Maybe EnvDoc
setDocEnvDoc :: SetDoc -> Maybe EnvDoc
setDocEnvDoc SetDoc {Bool
[String]
[Dashed]
Maybe String
Maybe (NonEmpty String)
Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocTryArgument :: SetDoc -> Bool
setDocTrySwitch :: SetDoc -> Bool
setDocTryOption :: SetDoc -> Bool
setDocDasheds :: SetDoc -> [Dashed]
setDocEnvVars :: SetDoc -> Maybe (NonEmpty String)
setDocConfKeys :: SetDoc -> Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: SetDoc -> Maybe String
setDocExamples :: SetDoc -> [String]
setDocMetavar :: SetDoc -> Maybe String
setDocHelp :: SetDoc -> Maybe String
setDocTryArgument :: Bool
setDocTrySwitch :: Bool
setDocTryOption :: Bool
setDocDasheds :: [Dashed]
setDocEnvVars :: Maybe (NonEmpty String)
setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: Maybe String
setDocExamples :: [String]
setDocMetavar :: Maybe String
setDocHelp :: Maybe String
..} = do
  NonEmpty String
envDocVars <- Maybe (NonEmpty String)
setDocEnvVars
  let envDocDefault :: Maybe String
envDocDefault = Maybe String
setDocDefault
  let envDocExamples :: [String]
envDocExamples = [String]
setDocExamples
  let envDocMetavar :: Maybe String
envDocMetavar = Maybe String
setDocMetavar
  let envDocHelp :: Maybe String
envDocHelp = Maybe String
setDocHelp
  pure EnvDoc {[String]
Maybe String
NonEmpty String
envDocVars :: NonEmpty String
envDocDefault :: Maybe String
envDocExamples :: [String]
envDocMetavar :: Maybe String
envDocHelp :: Maybe String
envDocVars :: NonEmpty String
envDocDefault :: Maybe String
envDocExamples :: [String]
envDocMetavar :: Maybe String
envDocHelp :: Maybe String
..}

settingEnvDoc :: Setting a -> Maybe EnvDoc
settingEnvDoc :: forall a. Setting a -> Maybe EnvDoc
settingEnvDoc = Setting a -> Maybe SetDoc
forall a. Setting a -> Maybe SetDoc
settingSetDoc (Setting a -> Maybe SetDoc)
-> (SetDoc -> Maybe EnvDoc) -> Setting a -> Maybe EnvDoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> SetDoc -> Maybe EnvDoc
setDocEnvDoc

-- | Render documentation of envionment variables
renderEnvDocs :: AnyDocs EnvDoc -> [Chunk]
renderEnvDocs :: AnyDocs EnvDoc -> [Chunk]
renderEnvDocs = [[[Chunk]]] -> [Chunk]
layoutAsTable ([[[Chunk]]] -> [Chunk])
-> (AnyDocs EnvDoc -> [[[Chunk]]]) -> AnyDocs EnvDoc -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs EnvDoc -> [[[Chunk]]]
go
  where
    go :: AnyDocs EnvDoc -> [[[Chunk]]]
    go :: AnyDocs EnvDoc -> [[[Chunk]]]
go = \case
      AnyDocsCommands Maybe String
_ [CommandDoc EnvDoc]
cs -> (CommandDoc EnvDoc -> [[[Chunk]]])
-> [CommandDoc EnvDoc] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (AnyDocs EnvDoc -> [[[Chunk]]]
go (AnyDocs EnvDoc -> [[[Chunk]]])
-> (CommandDoc EnvDoc -> AnyDocs EnvDoc)
-> CommandDoc EnvDoc
-> [[[Chunk]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandDoc EnvDoc -> AnyDocs EnvDoc
forall a. CommandDoc a -> AnyDocs a
commandDocs) [CommandDoc EnvDoc]
cs
      AnyDocsAnd [AnyDocs EnvDoc]
ds -> (AnyDocs EnvDoc -> [[[Chunk]]]) -> [AnyDocs EnvDoc] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs EnvDoc -> [[[Chunk]]]
go [AnyDocs EnvDoc]
ds
      AnyDocsOr [AnyDocs EnvDoc]
ds -> (AnyDocs EnvDoc -> [[[Chunk]]]) -> [AnyDocs EnvDoc] -> [[[Chunk]]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs EnvDoc -> [[[Chunk]]]
go [AnyDocs EnvDoc]
ds
      AnyDocsSingle EnvDoc
ed -> [[[Chunk]] -> [[Chunk]]
indent ([[Chunk]] -> [[Chunk]]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> a -> b
$ EnvDoc -> [[Chunk]]
renderEnvDoc EnvDoc
ed]

renderEnvDoc :: EnvDoc -> [[Chunk]]
renderEnvDoc :: EnvDoc -> [[Chunk]]
renderEnvDoc EnvDoc {[String]
Maybe String
NonEmpty String
envDocVars :: EnvDoc -> NonEmpty String
envDocDefault :: EnvDoc -> Maybe String
envDocExamples :: EnvDoc -> [String]
envDocMetavar :: EnvDoc -> Maybe String
envDocHelp :: EnvDoc -> Maybe String
envDocVars :: NonEmpty String
envDocDefault :: Maybe String
envDocExamples :: [String]
envDocMetavar :: Maybe String
envDocHelp :: Maybe String
..} =
  [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ [ [[Chunk]] -> [Chunk]
unwordsChunks
          [ NonEmpty String -> [Chunk]
envVarChunksNE NonEmpty String
envDocVars,
            [ Maybe String -> Chunk
mMetavarChunk Maybe String
envDocMetavar
            ]
          ],
        [Maybe String -> Chunk
mHelpChunk Maybe String
envDocHelp]
      ],
      [String -> [Chunk]
defaultValueChunks String
d | String
d <- Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList Maybe String
envDocDefault],
      [[String] -> [Chunk]
exampleValuesChunks [String]
envDocExamples | Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
envDocExamples)]
    ]

parserConfDocs :: Parser a -> AnyDocs ConfDoc
parserConfDocs :: forall a. Parser a -> AnyDocs ConfDoc
parserConfDocs = AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc
docsToConfDocs (AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc)
-> (Parser a -> AnyDocs (Maybe SetDoc))
-> Parser a
-> AnyDocs ConfDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser a -> AnyDocs (Maybe SetDoc)
forall a. Parser a -> AnyDocs (Maybe SetDoc)
parserDocs

docsToConfDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc
docsToConfDocs :: AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc
docsToConfDocs = (Maybe SetDoc -> Maybe ConfDoc)
-> AnyDocs (Maybe SetDoc) -> AnyDocs ConfDoc
forall a b. (a -> Maybe b) -> AnyDocs a -> AnyDocs b
mapMaybeDocs (Maybe SetDoc -> (SetDoc -> Maybe ConfDoc) -> Maybe ConfDoc
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SetDoc -> Maybe ConfDoc
setDocConfDoc)

setDocConfDoc :: SetDoc -> Maybe ConfDoc
setDocConfDoc :: SetDoc -> Maybe ConfDoc
setDocConfDoc SetDoc {Bool
[String]
[Dashed]
Maybe String
Maybe (NonEmpty String)
Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocTryArgument :: SetDoc -> Bool
setDocTrySwitch :: SetDoc -> Bool
setDocTryOption :: SetDoc -> Bool
setDocDasheds :: SetDoc -> [Dashed]
setDocEnvVars :: SetDoc -> Maybe (NonEmpty String)
setDocConfKeys :: SetDoc -> Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: SetDoc -> Maybe String
setDocExamples :: SetDoc -> [String]
setDocMetavar :: SetDoc -> Maybe String
setDocHelp :: SetDoc -> Maybe String
setDocTryArgument :: Bool
setDocTrySwitch :: Bool
setDocTryOption :: Bool
setDocDasheds :: [Dashed]
setDocEnvVars :: Maybe (NonEmpty String)
setDocConfKeys :: Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocDefault :: Maybe String
setDocExamples :: [String]
setDocMetavar :: Maybe String
setDocHelp :: Maybe String
..} = do
  NonEmpty (NonEmpty String, JSONSchema)
confDocKeys <- Maybe (NonEmpty (NonEmpty String, JSONSchema))
setDocConfKeys
  let confDocDefault :: Maybe String
confDocDefault = Maybe String
setDocDefault
  let confDocExamples :: [String]
confDocExamples = [String]
setDocExamples
  let confDocHelp :: Maybe String
confDocHelp = Maybe String
setDocHelp
  pure ConfDoc {[String]
Maybe String
NonEmpty (NonEmpty String, JSONSchema)
confDocKeys :: NonEmpty (NonEmpty String, JSONSchema)
confDocDefault :: Maybe String
confDocExamples :: [String]
confDocHelp :: Maybe String
confDocKeys :: NonEmpty (NonEmpty String, JSONSchema)
confDocDefault :: Maybe String
confDocExamples :: [String]
confDocHelp :: Maybe String
..}

settingConfDoc :: Setting a -> Maybe ConfDoc
settingConfDoc :: forall a. Setting a -> Maybe ConfDoc
settingConfDoc = Setting a -> Maybe SetDoc
forall a. Setting a -> Maybe SetDoc
settingSetDoc (Setting a -> Maybe SetDoc)
-> (SetDoc -> Maybe ConfDoc) -> Setting a -> Maybe ConfDoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> SetDoc -> Maybe ConfDoc
setDocConfDoc

docsToCommandDocs :: AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs :: AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs = \case
  AnyDocsCommands Maybe String
_ [CommandDoc (Maybe SetDoc)]
cs -> [CommandDoc (Maybe SetDoc)]
cs
  AnyDocsAnd [AnyDocs (Maybe SetDoc)]
ds -> (AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)])
-> [AnyDocs (Maybe SetDoc)] -> [CommandDoc (Maybe SetDoc)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs [AnyDocs (Maybe SetDoc)]
ds
  AnyDocsOr [AnyDocs (Maybe SetDoc)]
ds -> (AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)])
-> [AnyDocs (Maybe SetDoc)] -> [CommandDoc (Maybe SetDoc)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs (Maybe SetDoc) -> [CommandDoc (Maybe SetDoc)]
docsToCommandDocs [AnyDocs (Maybe SetDoc)]
ds
  AnyDocsSingle Maybe SetDoc
_ -> []

-- | Render documentation of configuration values
renderConfDocs :: AnyDocs ConfDoc -> [Chunk]
renderConfDocs :: AnyDocs ConfDoc -> [Chunk]
renderConfDocs = [[Chunk]] -> [Chunk]
unlinesChunks ([[Chunk]] -> [Chunk])
-> (AnyDocs ConfDoc -> [[Chunk]]) -> AnyDocs ConfDoc -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyDocs ConfDoc -> [[Chunk]]
go
  where
    go :: AnyDocs ConfDoc -> [[Chunk]]
    go :: AnyDocs ConfDoc -> [[Chunk]]
go = \case
      AnyDocsCommands Maybe String
_ [CommandDoc ConfDoc]
cs -> (CommandDoc ConfDoc -> [[Chunk]])
-> [CommandDoc ConfDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (AnyDocs ConfDoc -> [[Chunk]]
go (AnyDocs ConfDoc -> [[Chunk]])
-> (CommandDoc ConfDoc -> AnyDocs ConfDoc)
-> CommandDoc ConfDoc
-> [[Chunk]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandDoc ConfDoc -> AnyDocs ConfDoc
forall a. CommandDoc a -> AnyDocs a
commandDocs) [CommandDoc ConfDoc]
cs
      AnyDocsAnd [AnyDocs ConfDoc]
ds -> (AnyDocs ConfDoc -> [[Chunk]]) -> [AnyDocs ConfDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs ConfDoc -> [[Chunk]]
go [AnyDocs ConfDoc]
ds
      AnyDocsOr [AnyDocs ConfDoc]
ds -> (AnyDocs ConfDoc -> [[Chunk]]) -> [AnyDocs ConfDoc] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs ConfDoc -> [[Chunk]]
go [AnyDocs ConfDoc]
ds
      AnyDocsSingle ConfDoc
ed -> [[Chunk]] -> [[Chunk]]
indent (ConfDoc -> [[Chunk]]
renderConfDoc ConfDoc
ed)

renderConfDoc :: ConfDoc -> [[Chunk]]
renderConfDoc :: ConfDoc -> [[Chunk]]
renderConfDoc ConfDoc {[String]
Maybe String
NonEmpty (NonEmpty String, JSONSchema)
confDocKeys :: ConfDoc -> NonEmpty (NonEmpty String, JSONSchema)
confDocDefault :: ConfDoc -> Maybe String
confDocExamples :: ConfDoc -> [String]
confDocHelp :: ConfDoc -> Maybe String
confDocKeys :: NonEmpty (NonEmpty String, JSONSchema)
confDocDefault :: Maybe String
confDocExamples :: [String]
confDocHelp :: Maybe String
..} =
  [[[Chunk]]] -> [[Chunk]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ [[Maybe String -> Chunk
mHelpChunk Maybe String
confDocHelp]],
      [String -> [Chunk]
defaultValueChunks String
d | String
d <- Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList Maybe String
confDocDefault],
      [[String] -> [Chunk]
exampleValuesChunks [String]
confDocExamples | Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
confDocExamples)],
      ((NonEmpty String, JSONSchema) -> [[Chunk]])
-> [(NonEmpty String, JSONSchema)] -> [[Chunk]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
        ( \(NonEmpty String
key, JSONSchema
schema) ->
            case JSONSchema -> [[Chunk]]
jsonSchemaChunkLines JSONSchema
schema of
              [[Chunk]
line] ->
                [[NonEmpty String -> Chunk
confValChunk NonEmpty String
key, Chunk
": "] [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Chunk]
line]
              [[Chunk]]
ls ->
                [NonEmpty String -> Chunk
confValChunk NonEmpty String
key, Chunk
":"] [Chunk] -> [[Chunk]] -> [[Chunk]]
forall a. a -> [a] -> [a]
: [[Chunk]] -> [[Chunk]]
indent [[Chunk]]
ls
        )
        (NonEmpty (NonEmpty String, JSONSchema)
-> [(NonEmpty String, JSONSchema)]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (NonEmpty String, JSONSchema)
confDocKeys)
    ]