mdoc-0.5.0.0: src/Mdoc/Data/Page.hs
{-# OPTIONS_GHC -Wno-ambiguous-fields #-}
-- |
--
-- Module : Mdoc.Data.Page
-- Copyright : (c) 2026 Patrick Brisbin
-- License : AGPL-3
-- Maintainer : pbrisbin@gmail.com
-- Stability : experimental
-- Portability : POSIX
module Mdoc.Data.Page
( Page
-- * Adding to @SYNOPSIS@ / @DESCRIPTION@
, addSwitch
, addOption
, addArgument
, addAlternation
, addCommands
, addConfig
-- * @ENVIRONMENT@
, addEnvVar
-- * Access necessary for building 'Command's
, getSynopsis
, getPositionals
) where
import Mdoc.Prelude
import Mdoc.Data.Argument
import Mdoc.Data.Command
import Mdoc.Data.Config
import Mdoc.Data.Described
import Mdoc.Data.EnvVar
import Mdoc.Data.List (ByItem, Indent, List)
import Mdoc.Data.List qualified as List
import Mdoc.Data.Optionality
import Mdoc.Data.Positional
import Mdoc.Data.Synopsis (Synopsis)
import Mdoc.Data.Synopsis qualified as Synopsis
import Mdoc.Optics
data Page = Page
{ synopsis :: Maybe Synopsis
, options :: Maybe (List Indent (Described Positional))
, commands :: Maybe (List Indent Command)
, configs :: Maybe (List Indent (Described Config))
, environment :: Maybe (List ByItem (Described EnvVar))
}
deriving stock (Eq, Generic, Show)
deriving anyclass (ToJSON)
deriving (Monoid, Semigroup) via Generically Page
addSwitch :: Described Flag -> Page -> Page
addSwitch = addPositional . fmap PositionalSwitch
addOption :: Described Option -> Page -> Page
addOption = addPositional . fmap PositionalOption
addArgument :: Described Argument -> Page -> Page
addArgument = addPositional . fmap PositionalArgument
addAlternation :: Optionality -> [Described Positional] -> Page -> Page
addAlternation o ps =
appEndo
$ mconcat
$ Endo (field @"synopsis" <?>~ Synopsis.alternation o ps)
: map (Endo . addPositionalOption) ps
addPositional :: Described Positional -> Page -> Page
addPositional p =
(field @"synopsis" <?>~ Synopsis.singleton (fixPositional p))
. addPositionalOption p
addPositionalOption :: Described Positional -> Page -> Page
addPositionalOption p = field @"options" <?>~ List.singleton (fixPositional p)
-- Avoid showing a bunch of (default: False) for switches
fixPositional :: Described Positional -> Described Positional
fixPositional described = case (described.item, described.optionality) of
(PositionalSwitch {}, Defaulted {}) -> described {optionality = Optional}
_ -> described
addCommands :: [Command] -> Page -> Page
addCommands cs =
appEndo
$ Endo (field @"synopsis" <?>~ Synopsis.command)
<> foldMap addCommand cs
where
addCommand :: Command -> Endo Page
addCommand c = Endo $ field @"commands" <?>~ List.singleton c
addConfig :: Described Config -> Page -> Page
addConfig described =
field @"configs" <?>~ List.singleton described
addEnvVar :: Described EnvVar -> Page -> Page
addEnvVar described =
field @"environment" <?>~ List.singleton described
getSynopsis :: Page -> Synopsis
getSynopsis p = fromMaybe mempty p.synopsis
getPositionals :: Page -> [Described Positional]
getPositionals p = maybe [] (toList . (.items)) p.options