packages feed

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

{-# OPTIONS_GHC -Wno-ambiguous-fields #-}

-- | <https://mandoc.bsd.lv/mdoc/style/options.html>
module Mdoc.Gen.Synopsis
  ( man1Synopsis
  , man5Synopsis
  ) where

import Mdoc.Prelude

import Data.Char (toLower)
import Data.List (sortOn)
import Mdoc.Gen.Argument
import Mdoc.Gen.Described
import Mdoc.Gen.File
import Mdoc.Gen.Flag
import Mdoc.Gen.Man1
import Mdoc.Gen.Man5
import Mdoc.Gen.Name
import Mdoc.Gen.Option
import Mdoc.Gen.Optionality
import Mdoc.MacroArg
import Mdoc.MacroName
import Mdoc.MdocLine

man1Synopsis :: Man1 -> NonEmpty MdocLine
man1Synopsis m =
  MacroLine Nm [Bare $ esc $ pack $ m.name.primary]
    :| concat
      [ [MacroLine Bk ["-words"]]
      , maybe [] (\cs -> [MacroLine Op [Callable Fl, Bare $ esc $ pack $ toList cs]])
          $ shortSwitchChars m.switches
      , mapMaybe shortOptionLine m.options
      , map snd
          $ sortOn fst
          $ mapMaybe longSwitchLine m.switches
          <> mapMaybe longOptionLine m.options
      , map argLine m.arguments
      , [MacroLine Ek []]
      ]

man5Synopsis :: Man5 -> NonEmpty MdocLine
man5Synopsis m = renderFilesCompact m.files

shortSwitchChars :: [Described Flag] -> Maybe (NonEmpty Char)
shortSwitchChars = nonEmpty . sortOn toLower . mapMaybe (\d -> withShort d.item id)

shortOptionLine :: Described Option -> Maybe MdocLine
shortOptionLine d = withShort d.item.flag $ \c ->
  let margs = renderShort c $ Just d.item.argument
  in  case d.optionality of
        Required -> MacroLine Fl margs
        _ -> MacroLine Op $ Callable Fl : margs

longSwitchLine :: Described Flag -> Maybe (String, MdocLine)
longSwitchLine d = withLong d.item $ \s ->
  let
    margs = renderLong s Nothing
    mline = case d.optionality of
      Required -> MacroLine Fl margs
      _ -> MacroLine Op $ Callable Fl : margs
  in
    (s, mline)

longOptionLine :: Described Option -> Maybe (String, MdocLine)
longOptionLine d = withLong d.item.flag $ \s ->
  let
    margs = renderLong s $ Just d.item.argument
    mline = case d.optionality of
      Required -> MacroLine Fl margs
      _ -> MacroLine Op $ Callable Fl : margs
  in
    (s, mline)

argLine :: Described Argument -> MdocLine
argLine d =
  case d.optionality of
    Required -> MacroLine Ar margs
    Optional -> MacroLine Op $ Callable Ar : margs
    Defaulted {} -> MacroLine Op $ Callable Ar : margs
 where
  margs
    | d.multiple = [Bare $ esc $ pack d.item.schema, "..."]
    | otherwise = [Bare $ esc $ pack d.item.schema]

withShort :: Flag -> (Char -> a) -> Maybe a
withShort flag f = case flag of
  Flag c _ -> Just $ f c
  _ -> Nothing

withLong :: Flag -> (String -> a) -> Maybe a
withLong flag f = case flag of
  GNUFlag s _ -> Just $ f s
  _ -> Nothing