on 877cb21 help sign in
hakyll/src/Hakyll/Web/CompressCss.hs
60 lines 2.2 kB history raw
1--------------------------------------------------------------------------------
2-- | Module used for CSS compression. The compression is currently in a simple
3-- state, but would typically reduce the number of bytes by about 25%.
4module Hakyll.Web.CompressCss
5 ( compressCssCompiler
6 , compressCss
7 ) where
10--------------------------------------------------------------------------------
11import Control.Applicative ((<$>))
12import Data.Char (isSpace)
13import Data.List (isPrefixOf)
16--------------------------------------------------------------------------------
17import Hakyll.Core.Compiler
18import Hakyll.Core.Item
19import Hakyll.Core.Util.String
22--------------------------------------------------------------------------------
23-- | Compiler form of 'compressCss'
24compressCssCompiler :: Compiler (Item String)
25compressCssCompiler = fmap compressCss <$> getResourceString
28--------------------------------------------------------------------------------
29-- | Compress CSS to speed up your site.
30compressCss :: String -> String
31compressCss = compressSeparators . stripComments . compressWhitespace
34--------------------------------------------------------------------------------
35-- | Compresses certain forms of separators.
36compressSeparators :: String -> String
37compressSeparators =
38 replaceAll "; *}" (const "}") .
39 replaceAll " *([{};:]) *" (take 1 . dropWhile isSpace) .
40 replaceAll ";+" (const ";")
43--------------------------------------------------------------------------------
44-- | Compresses all whitespace.
45compressWhitespace :: String -> String
46compressWhitespace = replaceAll "[ \t\n\r]+" (const " ")
49--------------------------------------------------------------------------------
50-- | Function that strips CSS comments away.
51stripComments :: String -> String
52stripComments [] = []
53stripComments str
54 | isPrefixOf "/*" str = stripComments $ eatComments $ drop 2 str
55 | otherwise = head str : stripComments (drop 1 str)
56 where
57 eatComments str'
58 | null str' = []
59 | isPrefixOf "*/" str' = drop 2 str'
60 | otherwise = eatComments $ drop 1 str'