packages feed

mdoc-0.1.0.2: 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 (..)
  , 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)

instance Ord Flag where
  compare = comparing @(Int, String, Bool) $ \case
    --           1. short before long
    --           |  2. case-insensitive alphabetically
    --           |  |            3. upper before lower
    --           |  |            |
    Flag c _ -> (1, [toLower c], isLower c)
    GNUFlag s _ -> (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