packages feed

mdoc-0.1.0.0: src/Mdoc/Interpolated.hs

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

import Mdoc.Prelude

import Mdoc
import Mdoc.Interpolation
import Mdoc.MacroArg
import Mdoc.MacroName
import Mdoc.MdocLine

data InterpolationValues = InterpolationValues
  { docTitle :: Text
  , docSection :: Int
  -- ^ TODO: ManSection enum
  , name :: NonEmpty MdocLine
  , synopsis :: NonEmpty MdocLine
  , description :: NonEmpty MdocLine
  , environment :: Maybe (NonEmpty MdocLine)
  , files :: Maybe (NonEmpty MdocLine)
  , exitStatus :: Maybe (NonEmpty MdocLine)
  , seeAlso :: Maybe (NonEmpty MdocLine)
  }

class Interpolated a where
  interpolate :: InterpolationValues -> a -> a

instance Interpolated [MacroArg] where
  interpolate v = concatMap go
   where
    go = \case
      InterpolatedArg DocTitle -> [Bare $ esc v.docTitle]
      InterpolatedArg DocSection -> [Bare $ esc $ pack $ show v.docSection]
      arg -> [arg]

instance Interpolated [MdocLine] where
  interpolate v = concatMap go
   where
    go = \case
      MacroLine m args -> [MacroLine m $ interpolate v args]
      InterpolatedLine Name -> toList v.name
      InterpolatedLine Synopsis -> toList v.synopsis
      InterpolatedLine Description -> toList v.description
      InterpolatedLine Environment -> case v.environment of
        Nothing -> []
        Just es -> MacroLine Sh ["ENVIRONMENT"] : toList es
      InterpolatedLine Files -> case v.files of
        Nothing -> []
        Just fs -> MacroLine Sh ["FILES"] : toList fs
      InterpolatedLine ExitStatus ->
        maybe [MacroLine Ex ["-std"]] toList v.exitStatus
      InterpolatedLine SeeAlso -> case v.seeAlso of
        Nothing -> []
        Just crs -> MacroLine Sh ["SEE", "ALSO"] : toList crs
      line -> [line]

instance Interpolated Mdoc where
  interpolate v mdoc = mdoc {lines = interpolate v mdoc.lines}