@@ -2,14 +2,20 @@
3module Hakyll.Core.UnixFilter
3module Hakyll.Core.UnixFilter
4 ( unixFilter
4 ( unixFilter
7import Control.Concurrent (forkIO)
8import Control.Concurrent (forkIO)
8−import System.IO (hPutStr, hClose, hGetContents)
9import System.Posix.Process (executeFile, forkProcess)
9import System.Posix.Process (executeFile, forkProcess)
10import System.Posix.IO ( dupTo, createPipe, stdInput
10import System.Posix.IO ( dupTo, createPipe, stdInput
11 , stdOutput, closeFd, fdToHandle
11 , stdOutput, closeFd, fdToHandle
13+import System.IO ( Handle, hPutStr, hClose, hGetContents
14+ , hSetEncoding, localeEncoding
17+import Data.ByteString.Lazy (ByteString)
18+import qualified Data.ByteString.Lazy as LB
14import Hakyll.Core.Compiler
20import Hakyll.Core.Compiler
@@ -26,25 +32,54 @@ import Hakyll.Core.Compiler
27-- The code is fairly straightforward, given that we use @.scss@ for sass:
33-- The code is fairly straightforward, given that we use @.scss@ for sass:
35+-- > match "style.scss" $ do
29−-- > route "style.scss" $ setExtension "css"
36+-- > route $ setExtension "css"
30−-- > compile "style.scss" $
31−-- > getResourceString >>> unixFilter "sass" ["-s", "--scss"]
37+-- > compile $ getResourceString >>> unixFilter "sass" ["-s", "--scss"]
32−-- > >>> arr compressCss
38+-- > >>> arr compressCss
34unixFilter :: String -- ^ Program name
40unixFilter :: String -- ^ Program name
35 -> [String] -- ^ Program args
41 -> [String] -- ^ Program args
36 -> Compiler String String -- ^ Resulting compiler
42 -> Compiler String String -- ^ Resulting compiler
43+unixFilter = unixFilterWith writer reader
45+ writer handle input = do
46+ hSetEncoding handle localeEncoding
49+ hSetEncoding handle localeEncoding
52+-- | Variant of 'unixFilter' that should be used for binary files
54+-- > match "music.wav" $ do
55+-- > route $ setExtension "ogg"
56+-- > compile $ getResourceLBS >>> unixFilter "oggenc" ["-"]
58+unixFilterLBS :: String -- ^ Program name
59+ -> [String] -- ^ Program args
60+ -> Compiler ByteString ByteString -- ^ Resulting compiler
61+unixFilterLBS = unixFilterWith LB.hPutStr LB.hGetContents
63+-- | Overloaded compiler
65+unixFilterWith :: (Handle -> i -> IO ()) -- ^ Writer
66+ -> (Handle -> IO o) -- ^ Reader
67+ -> String -- ^ Program name
68+ -> [String] -- ^ Program args
69+ -> Compiler i o -- ^ Resulting compiler
37−unixFilter programName args =
70+unixFilterWith writer reader programName args =
38 timedCompiler ("Executing external program " ++ programName) $
71 timedCompiler ("Executing external program " ++ programName) $
39− unsafeCompiler $ \input -> unixFilterIO programName args input
72+ unsafeCompiler $ unixFilterIO writer reader programName args
41-- | Internally used function
74-- | Internally used function
43−unixFilterIO :: String
76+unixFilterIO :: (Handle -> i -> IO ())
44− -> [String]
77+ -> (Handle -> IO o)
46− -> IO String
79+ -> [String]
47−unixFilterIO programName args input = do
82+unixFilterIO writer reader programName args input = do
48 -- Create pipes
83 -- Create pipes
49 (stdinRead, stdinWrite) <- createPipe
84 (stdinRead, stdinWrite) <- createPipe
50 (stdoutRead, stdoutWrite) <- createPipe
85 (stdoutRead, stdoutWrite) <- createPipe
@@ -68,9 +103,9 @@ unixFilterIO programName args input = do
68 -- Write the input to the child pipe
103 -- Write the input to the child pipe
69 _ <- forkIO $ do
104 _ <- forkIO $ do
70 stdinWriteHandle <- fdToHandle stdinWrite
105 stdinWriteHandle <- fdToHandle stdinWrite
71− hPutStr stdinWriteHandle input
106+ writer stdinWriteHandle input
72 hClose stdinWriteHandle
107 hClose stdinWriteHandle
74 -- Receive the output from the child
109 -- Receive the output from the child
75 stdoutReadHandle <- fdToHandle stdoutRead
110 stdoutReadHandle <- fdToHandle stdoutRead
76− hGetContents stdoutReadHandle
111+ reader stdoutReadHandle