packages feed

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

-- |
--
-- Module      : Mdoc.Gen.File
-- Copyright   : (c) 2026 Patrick Brisbin
-- License     : AGPL-3
-- Maintainer  : pbrisbin@gmail.com
-- Stability   : experimental
-- Portability : POSIX
module Mdoc.Gen.File
  ( File (..)
  , renderFiles
  , renderFilesCompact
  ) where

import Mdoc.Prelude

import Data.List.NonEmpty qualified as NE
import Mdoc.MacroArg
import Mdoc.MacroName
import Mdoc.MdocLine

data File = File
  { path :: FilePath
  , description :: Maybe String
  }
  deriving stock (Eq, Generic, Ord, Show)

instance IsString File where
  fromString path = File {path, description = Nothing}

-- | Render a list of 'File' with descriptions, e.g. for @FILES@
renderFiles :: NonEmpty File -> NonEmpty MdocLine
renderFiles ne =
  MacroLine Bl ["-tag", "-width", Bare $ esc $ pack longestName, "-compact"]
    :| concat
      [ concatMap renderFileItem (toList $ NE.sort ne)
      , [MacroLine El []]
      ]
 where
  longestName :: String
  longestName = maximumBy (comparing length) $ (.path) <$> ne

renderFileItem :: File -> [MdocLine]
renderFileItem File {path, description} =
  [MacroLine It [Callable Pa, Bare $ esc $ pack path]]
    <> maybe [] (pure . TextLine . esc . pack) description

-- | Render a list of 'File' compactly, e.g. for synopsis
renderFilesCompact :: NonEmpty File -> NonEmpty MdocLine
renderFilesCompact = go . NE.sort
 where
  go ne =
    MacroLine Bl ["-tag", "-width", "indent", "-compact"]
      :| concat
        [ map pa_ (init ne) <> [pa $ last ne]
        , [MacroLine El []]
        ]

pa :: File -> MdocLine
pa File {path} = MacroLine It [Callable Pa, Bare $ esc $ pack path]

pa_ :: File -> MdocLine
pa_ File {path} = MacroLine It [Callable Pa, Bare $ esc $ pack path, ","]