packages feed

mdoc-0.1.0.0: src/Mdoc/Gen/Flag.hs

-- |
--
-- Module      : Mdoc.Gen.Flag
-- Copyright   : (c) 2026 Patrick Brisbin
-- License     : AGPL-3
-- Maintainer  : pbrisbin@gmail.com
-- Stability   : experimental
-- Portability : POSIX
module Mdoc.Gen.Flag
  ( Flag (..)
  , FlagOrder
  , flagOrder
  , renderFlag
  , renderShort
  , renderLong
  ) where

import Mdoc.Prelude

import Data.Char (isLower, toLower)
import Data.List (intercalate)
import Data.Text qualified as T
import Mdoc.Gen.Argument
import Mdoc.MacroArg
import Mdoc.MacroName

data Flag
  = Flag Char [Flag]
  | GNUFlag String [Flag]
  deriving stock (Eq, Show)

data FlagOrder = FlagOrder
  { _byType :: Int
  , _byNameLower :: String
  , _byUpperThenLower :: Bool
  }
  deriving stock (Eq, Ord)

-- | Shorts before longs, capital then lower together
flagOrder :: Flag -> FlagOrder
flagOrder = \case
  Flag c _ -> FlagOrder 1 [toLower c] $ isLower c
  GNUFlag s _ -> FlagOrder 2 (map toLower s) False

renderFlag :: Flag -> Maybe Argument -> [MacroArg]
renderFlag flag margument =
  intercalate [Bare ","]
    $ map ([Callable Fl] <>)
    $ go flag
 where
  go :: Flag -> [[MacroArg]]
  go = \case
    Flag c as -> renderShort c margument : concatMap go as
    GNUFlag s as -> renderLong s margument : concatMap go as

renderShort :: Char -> Maybe Argument -> [MacroArg]
renderShort c = \case
  Nothing -> [Bare $ esc $ T.singleton c]
  Just argument -> renderArgumentForShort c argument

renderLong :: String -> Maybe Argument -> [MacroArg]
renderLong s = \case
  Nothing -> [Callable Fl, Bare $ esc $ pack s]
  Just argument -> [Callable Fl] <> renderArgumentForLong s argument