on master help sign in
Fix encoding errors with unixFilter
commit97d81872c529893db22eb5ea68eb76c5df278e2d authorJasper Van der Jeugt <jaspervdj@gmail.com> dateFri 6 May 2011, 10:28 (15 years ago) parent64caea9
4 files changed+73−21
src/Hakyll/Core/Compiler.hs+16−3 src/Hakyll/Core/Resource/Provider.hs+5−5 src/Hakyll/Core/UnixFilter.hs+48−13 src/Hakyll/Core/Writable.hs+4
src/Hakyll/Core/Compiler.hs+16−3
@@ -92,6 +92,7 @@ module Hakyll.Core.Compiler
9292 , getRoute
9393 , getRouteFor
9494 , getResourceString
95+ , getResourceLBS
9596 , fromDependency
9697 , require_
9798 , require
@@ -119,6 +120,7 @@ import System.FilePath (takeExtension)
119120
120121import Data.Binary (Binary)
121122import Data.Typeable (Typeable)
123+import Data.ByteString.Lazy (ByteString)
122124
123125import Hakyll.Core.Identifier
124126import Hakyll.Core.Identifier.Pattern
@@ -182,14 +184,25 @@ getRouteFor = fromJob $ \identifier -> CompilerM $ do
182184-- | Get the resource we are compiling as a string
183185--
184186getResourceString :: Compiler Resource String
185−getResourceString = fromJob $ \resource -> CompilerM $ do
187+getResourceString = getResourceWith resourceString
188+
189+-- | Get the resource we are compiling as a lazy bytestring
190+--
191+getResourceLBS :: Compiler Resource ByteString
192+getResourceLBS = getResourceWith resourceLBS
193+
194+-- | Overloadable function for 'getResourceString' and 'getResourceLBS'
195+--
196+getResourceWith :: (ResourceProvider -> Resource -> IO a)
197+ -> Compiler Resource a
198+getResourceWith reader = fromJob $ \resource -> CompilerM $ do
186199 let identifier = unResource resource
187200 provider <- compilerResourceProvider <$> ask
188201 if resourceExists provider resource
189− then liftIO $ resourceString provider resource
202+ then liftIO $ reader provider resource
190203 else throwError $ error' identifier
191204 where
192− error' id' = "Hakyll.Core.Compiler.getResourceString: resource "
205+ error' id' = "Hakyll.Core.Compiler.getResourceWith: resource "
193206 ++ show id' ++ " not found"
194207
195208-- | Auxiliary: get a dependency
src/Hakyll/Core/Resource/Provider.hs+5−5
@@ -36,13 +36,13 @@ import Hakyll.Core.Resource
3636--
3737data ResourceProvider = ResourceProvider
3838 { -- | A list of all resources this provider is able to provide
39− resourceList :: [Resource]
39+ resourceList :: [Resource]
4040 , -- | Retrieve a certain resource as string
41− resourceString :: Resource -> IO String
41+ resourceString :: Resource -> IO String
4242 , -- | Retrieve a certain resource as lazy bytestring
43− resourceLazyByteString :: Resource -> IO LB.ByteString
43+ resourceLBS :: Resource -> IO LB.ByteString
4444 , -- | Cache keeping track of modified items
45− resourceModifiedCache :: MVar (Map Resource Bool)
45+ resourceModifiedCache :: MVar (Map Resource Bool)
4646 }
4747
4848-- | Create a resource provider
@@ -61,7 +61,7 @@ resourceExists provider = flip elem $ resourceList provider
6161-- | Retrieve a digest for a given resource
6262--
6363resourceDigest :: ResourceProvider -> Resource -> IO [Word8]
64−resourceDigest provider = digest MD5 <=< resourceLazyByteString provider
64+resourceDigest provider = digest MD5 <=< resourceLBS provider
6565
6666-- | Check if a resource was modified
6767--
src/Hakyll/Core/UnixFilter.hs+48−13
@@ -2,14 +2,20 @@
22--
33module Hakyll.Core.UnixFilter
44 ( unixFilter
5+ , unixFilterLBS
56 ) where
67
78import Control.Concurrent (forkIO)
8−import System.IO (hPutStr, hClose, hGetContents)
99import System.Posix.Process (executeFile, forkProcess)
1010import System.Posix.IO ( dupTo, createPipe, stdInput
1111 , stdOutput, closeFd, fdToHandle
1212 )
13+import System.IO ( Handle, hPutStr, hClose, hGetContents
14+ , hSetEncoding, localeEncoding
15+ )
16+
17+import Data.ByteString.Lazy (ByteString)
18+import qualified Data.ByteString.Lazy as LB
1319
1420import Hakyll.Core.Compiler
1521
@@ -26,25 +32,54 @@ import Hakyll.Core.Compiler
2632--
2733-- The code is fairly straightforward, given that we use @.scss@ for sass:
2834--
29−-- > route "style.scss" $ setExtension "css"
30−-- > compile "style.scss" $
31−-- > getResourceString >>> unixFilter "sass" ["-s", "--scss"]
32−-- > >>> arr compressCss
35+-- > match "style.scss" $ do
36+-- > route $ setExtension "css"
37+-- > compile $ getResourceString >>> unixFilter "sass" ["-s", "--scss"]
38+-- > >>> arr compressCss
3339--
3440unixFilter :: String -- ^ Program name
3541 -> [String] -- ^ Program args
3642 -> Compiler String String -- ^ Resulting compiler
37−unixFilter programName args =
43+unixFilter = unixFilterWith writer reader
44+ where
45+ writer handle input = do
46+ hSetEncoding handle localeEncoding
47+ hPutStr handle input
48+ reader handle = do
49+ hSetEncoding handle localeEncoding
50+ hGetContents handle
51+
52+-- | Variant of 'unixFilter' that should be used for binary files
53+--
54+-- > match "music.wav" $ do
55+-- > route $ setExtension "ogg"
56+-- > compile $ getResourceLBS >>> unixFilter "oggenc" ["-"]
57+--
58+unixFilterLBS :: String -- ^ Program name
59+ -> [String] -- ^ Program args
60+ -> Compiler ByteString ByteString -- ^ Resulting compiler
61+unixFilterLBS = unixFilterWith LB.hPutStr LB.hGetContents
62+
63+-- | Overloaded compiler
64+--
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
70+unixFilterWith writer reader programName args =
3871 timedCompiler ("Executing external program " ++ programName) $
39− unsafeCompiler $ \input -> unixFilterIO programName args input
72+ unsafeCompiler $ unixFilterIO writer reader programName args
4073
4174-- | Internally used function
4275--
43−unixFilterIO :: String
44− -> [String]
76+unixFilterIO :: (Handle -> i -> IO ())
77+ -> (Handle -> IO o)
4578 -> String
46− -> IO String
47−unixFilterIO programName args input = do
79+ -> [String]
80+ -> i
81+ -> IO o
82+unixFilterIO writer reader programName args input = do
4883 -- Create pipes
4984 (stdinRead, stdinWrite) <- createPipe
5085 (stdoutRead, stdoutWrite) <- createPipe
@@ -68,9 +103,9 @@ unixFilterIO programName args input = do
68103 -- Write the input to the child pipe
69104 _ <- forkIO $ do
70105 stdinWriteHandle <- fdToHandle stdinWrite
71− hPutStr stdinWriteHandle input
106+ writer stdinWriteHandle input
72107 hClose stdinWriteHandle
73108
74109 -- Receive the output from the child
75110 stdoutReadHandle <- fdToHandle stdoutRead
76− hGetContents stdoutReadHandle
111+ reader stdoutReadHandle
src/Hakyll/Core/Writable.hs+4
@@ -8,6 +8,7 @@ module Hakyll.Core.Writable
88import Data.Word (Word8)
99
1010import qualified Data.ByteString as SB
11+import qualified Data.ByteString.Lazy as LB
1112import Text.Blaze (Html)
1213import Text.Blaze.Renderer.String (renderHtml)
1314
@@ -25,6 +26,9 @@ instance Writable [Char] where
2526instance Writable SB.ByteString where
2627 write p = SB.writeFile p
2728
29+instance Writable LB.ByteString where
30+ write p = LB.writeFile p
31+
2832instance Writable [Word8] where
2933 write p = write p . SB.pack
3034