summaryrefslogtreecommitdiff
path: root/src/Hakyll/Web/CompressCss.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Hakyll/Web/CompressCss.hs')
-rw-r--r--src/Hakyll/Web/CompressCss.hs44
1 files changed, 35 insertions, 9 deletions
diff --git a/src/Hakyll/Web/CompressCss.hs b/src/Hakyll/Web/CompressCss.hs
index 58d52b4..0371d8b 100644
--- a/src/Hakyll/Web/CompressCss.hs
+++ b/src/Hakyll/Web/CompressCss.hs
@@ -8,14 +8,12 @@ module Hakyll.Web.CompressCss
--------------------------------------------------------------------------------
-import Data.Char (isSpace)
import Data.List (isPrefixOf)
--------------------------------------------------------------------------------
import Hakyll.Core.Compiler
import Hakyll.Core.Item
-import Hakyll.Core.Util.String
--------------------------------------------------------------------------------
@@ -33,27 +31,55 @@ compressCss = compressSeparators . stripComments . compressWhitespace
--------------------------------------------------------------------------------
-- | Compresses certain forms of separators.
compressSeparators :: String -> String
-compressSeparators =
- replaceAll "; *}" (const "}") .
- replaceAll " *([{};]) *" (take 1 . dropWhile isSpace) .
- replaceAll ";+" (const ";")
-
+compressSeparators [] = []
+compressSeparators str
+ | isConstant = head str : retainConstants compressSeparators (head str) (drop 1 str)
+ | stripFirst = compressSeparators (drop 1 str)
+ | stripSecond = compressSeparators (head str : (drop 2 str))
+ | otherwise = head str : compressSeparators (drop 1 str)
+ where
+ isConstant = or $ map (isOfPrefix str) ["\"", "'"]
+ stripFirst = or $ map (isOfPrefix str) [" ", " {", " }", " :", ";;", ";}"]
+ stripSecond = or $ map (isOfPrefix str) ["{ ", "} ", ": ", "; "]
--------------------------------------------------------------------------------
-- | Compresses all whitespace.
compressWhitespace :: String -> String
-compressWhitespace = replaceAll "[ \t\n\r]+" (const " ")
-
+compressWhitespace [] = []
+compressWhitespace str
+ | isConstant = head str : retainConstants compressWhitespace (head str) (drop 1 str)
+ | replaceOne = compressWhitespace (' ' : (drop 1 str))
+ | replaceTwo = compressWhitespace (' ' : (drop 2 str))
+ | otherwise = head str : compressWhitespace (drop 1 str)
+ where
+ isConstant = or $ map (isOfPrefix str) ["\"", "'"]
+ replaceOne = or $ map (isOfPrefix str) ["\t", "\n", "\r"]
+ replaceTwo = or $ map (isOfPrefix str) [" \t", " \n", " \r", " "]
--------------------------------------------------------------------------------
-- | Function that strips CSS comments away.
stripComments :: String -> String
stripComments [] = []
stripComments str
+ | isConstant = head str : retainConstants stripComments (head str) (drop 1 str)
| isPrefixOf "/*" str = stripComments $ eatComments $ drop 2 str
| otherwise = head str : stripComments (drop 1 str)
where
+ isConstant = or $ map (isOfPrefix str) ["\"", "'"]
eatComments str'
| null str' = []
| isPrefixOf "*/" str' = drop 2 str'
| otherwise = eatComments $ drop 1 str'
+
+--------------------------------------------------------------------------------
+-- | Helper function to handle string constants correctly.
+retainConstants :: (String -> String) -> Char -> String -> String
+retainConstants f delim str
+ | null str = []
+ | isPrefixOf [delim] str = head str : f (drop 1 str)
+ | otherwise = head str : retainConstants f delim (drop 1 str)
+
+--------------------------------------------------------------------------------
+-- | Helper function to determine whether a string is a substring.
+isOfPrefix :: String -> String -> Bool
+isOfPrefix = flip isPrefixOf