module Hakyll.Core.UnixFilter
( unixFilter
, unixFilterLBS
) where
import Control.Concurrent (forkIO)
import System.Process
import System.IO ( Handle, hPutStr, hClose, hGetContents
, hSetEncoding, localeEncoding
)
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as LB
import Hakyll.Core.Compiler
unixFilter :: String
-> [String]
-> Compiler String String
unixFilter = unixFilterWith writer reader
where
writer handle input = do
hSetEncoding handle localeEncoding
hPutStr handle input
reader handle = do
hSetEncoding handle localeEncoding
hGetContents handle
unixFilterLBS :: String
-> [String]
-> Compiler ByteString ByteString
unixFilterLBS = unixFilterWith LB.hPutStr LB.hGetContents
unixFilterWith :: (Handle -> i -> IO ())
-> (Handle -> IO o)
-> String
-> [String]
-> Compiler i o
unixFilterWith writer reader programName args =
timedCompiler ("Executing external program " ++ programName) $
unsafeCompiler $ unixFilterIO writer reader programName args
unixFilterIO :: (Handle -> i -> IO ())
-> (Handle -> IO o)
-> String
-> [String]
-> i
-> IO o
unixFilterIO writer reader programName args input = do
let process = (proc programName args)
{ std_in = CreatePipe
, std_out = CreatePipe
, close_fds = True
}
(Just stdinWriteHandle, Just stdoutReadHandle, _, _) <-
createProcess process
_ <- forkIO $ do
writer stdinWriteHandle input
hClose stdinWriteHandle
reader stdoutReadHandle