mdoc-0.1.0.0: src/Mdoc/Input.hs
-- |
--
-- Module : Mdoc.Input
-- Copyright : (c) 2026 Patrick Brisbin
-- License : AGPL-3
-- Maintainer : pbrisbin@gmail.com
-- Stability : experimental
-- Portability : POSIX
module Mdoc.Input
( Input (..)
, Parsed (..)
, forInputs_
, parseMdocBytes
) where
import Mdoc.Prelude
import Codec.Compression.GZip qualified as GZip
import Data.ByteString.Lazy (LazyByteString)
import Data.ByteString.Lazy qualified as BSL
import Data.Text.Encoding (decodeUtf8With)
import Data.Text.Encoding.Error (lenientDecode)
import Mdoc
import Mdoc.Detect
import Mdoc.Parse
import System.FilePath (takeExtension)
data Input = Input
{ name :: String
, source :: Text
, parsed :: Parsed
}
data Parsed
= SkipParse Unparsable
| ParseError ParseError
| Parsed Mdoc
forInputs_ :: MonadIO m => [FilePath] -> (Input -> m a) -> m ()
forInputs_ inputs f = case inputs of
[] -> void . f . mkInput "<stdin>" =<< liftIO BSL.getContents
paths -> for_ paths $ \path -> do
f . mkInput path =<< liftIO (BSL.readFile path)
mkInput :: String -> LazyByteString -> Input
mkInput name bytes =
let
source = decodeUtf8With lenientDecode $ BSL.toStrict bytes
parsed = either ParseError Parsed $ parseMdocBytes name bytes
input p = Input {name, source, parsed = p}
in
input $ maybe parsed SkipParse $ detectParsable name source
parseMdocBytes
:: FilePath
-- ^ Path used for parse errors and detecting gzip
-> LazyByteString
-> Either ParseError Mdoc
parseMdocBytes path =
runParser parseMdoc path
. decodeUtf8With lenientDecode
. BSL.toStrict
. decompress
where
decompress
| takeExtension path == ".gz" = GZip.decompress
| otherwise = id