summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper Van der Jeugt <jaspervdj@gmail.com>2010-01-09 21:40:31 +0100
committerJasper Van der Jeugt <jaspervdj@gmail.com>2010-01-09 21:40:31 +0100
commit73f6b1ab8cf3cb9468c547db6df1df9596f1470d (patch)
tree1d8b7205cc88388573c50798dd6e16effeb39ece
parentcb3e3b119313145b5b79d46d2c40390ce9d9a51b (diff)
downloadhakyll-73f6b1ab8cf3cb9468c547db6df1df9596f1470d.tar.gz
Some changes to the regex interface, and version bump.
-rw-r--r--hakyll.cabal6
-rw-r--r--src/Network/Hakyll/SimpleServer.hs1
-rw-r--r--src/Text/Hakyll/CompressCSS.hs16
-rw-r--r--src/Text/Hakyll/Context.hs7
-rw-r--r--src/Text/Hakyll/Regex.hs66
-rw-r--r--src/Text/Hakyll/Tags.hs1
-rw-r--r--src/Text/Hakyll/Util.hs7
-rw-r--r--tests/Tests.hs15
8 files changed, 90 insertions, 29 deletions
diff --git a/hakyll.cabal b/hakyll.cabal
index 984f6d9..a8e3b13 100644
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -1,5 +1,5 @@
Name: hakyll
-Version: 0.4
+Version: 0.4.1
Synopsis: A simple static site generator library.
Description:
@@ -30,7 +30,8 @@ library
containers >= 0.1,
bytestring >= 0.9 && < 0.9.2,
pandoc >= 1,
- regex-compat >= 0.92,
+ regex-base >= 0.83,
+ regex-tdfa >= 0.92,
network >= 2,
mtl >= 1.1,
old-locale >= 1,
@@ -45,4 +46,5 @@ library
Text.Hakyll.Util
Text.Hakyll.Tags
Text.Hakyll.Context
+ Text.Hakyll.Regex
Network.Hakyll.SimpleServer
diff --git a/src/Network/Hakyll/SimpleServer.hs b/src/Network/Hakyll/SimpleServer.hs
index 774eb6e..7b058f3 100644
--- a/src/Network/Hakyll/SimpleServer.hs
+++ b/src/Network/Hakyll/SimpleServer.hs
@@ -17,6 +17,7 @@ import qualified Data.ByteString.Char8 as B
import qualified Data.Map as M
import Text.Hakyll.Util
+import Text.Hakyll.Regex
-- | Function to log from a chan.
log :: Chan String -> IO ()
diff --git a/src/Text/Hakyll/CompressCSS.hs b/src/Text/Hakyll/CompressCSS.hs
index 8745368..85c061d 100644
--- a/src/Text/Hakyll/CompressCSS.hs
+++ b/src/Text/Hakyll/CompressCSS.hs
@@ -3,27 +3,23 @@ module Text.Hakyll.CompressCSS
) where
import Data.List (isPrefixOf)
-import Text.Regex (subRegex, mkRegex)
-
--- | subRegex with arguments flipped for easy function composition.
-subRegex' :: String -> String -> String -> String
-subRegex' pattern replacement str = subRegex (mkRegex pattern) str replacement
+import Text.Hakyll.Regex (substitute)
-- | Compress CSS to speed up your site.
compressCSS :: String -> String
compressCSS = compressSeparators
- . compressWhitespace
. stripComments
+ . compressWhitespace
-- | Compresses certain forms of separators.
compressSeparators :: String -> String
-compressSeparators = subRegex' ";\\s*}" "}"
- . subRegex' "\\s*([{};:])\\s*" "\\1"
- . subRegex' ";;*" ";"
+compressSeparators = substitute "; *}" "}"
+ . substitute " *([{};:]) *" "\\1"
+ . substitute ";;*" ";"
-- | Compresses all whitespace.
compressWhitespace :: String -> String
-compressWhitespace = subRegex' "\\s\\s*" " "
+compressWhitespace = substitute "[ \t\n][ \t\n]*" " "
-- | Function that strips CSS comments away.
stripComments :: String -> String
diff --git a/src/Text/Hakyll/Context.hs b/src/Text/Hakyll/Context.hs
index e3069b5..22409bf 100644
--- a/src/Text/Hakyll/Context.hs
+++ b/src/Text/Hakyll/Context.hs
@@ -10,11 +10,11 @@ import qualified Data.ByteString.Lazy.Char8 as B
import System.Locale (defaultTimeLocale)
import System.FilePath (takeFileName)
-import Text.Regex (subRegex, mkRegex)
import Text.Template (Context)
import Data.Time.Format (parseTime, formatTime)
import Data.Time.Clock (UTCTime)
import Data.Maybe (fromMaybe)
+import Text.Hakyll.Regex (substitute)
-- | Type for context manipulating functions.
type ContextManipulation = Context -> Context
@@ -38,9 +38,8 @@ renderDate key format defaultValue context =
M.insert (B.pack key) (B.pack value) context
where value = fromMaybe defaultValue pretty
pretty = do filePath <- M.lookup (B.pack "path") context
- let dateString = subRegex (mkRegex "^([0-9]*-[0-9]*-[0-9]*).*")
- (takeFileName $ B.unpack filePath)
- "\\1"
+ let dateString = substitute "^([0-9]*-[0-9]*-[0-9]*).*" "\\1"
+ (takeFileName $ B.unpack filePath)
time <- parseTime defaultTimeLocale
"%Y-%m-%d"
dateString :: Maybe UTCTime
diff --git a/src/Text/Hakyll/Regex.hs b/src/Text/Hakyll/Regex.hs
new file mode 100644
index 0000000..e2e21bc
--- /dev/null
+++ b/src/Text/Hakyll/Regex.hs
@@ -0,0 +1,66 @@
+-- | A module that exports a simple regex interface. This code is mostly copied
+-- from the regex-compat package at hackage.
+module Text.Hakyll.Regex
+ ( split
+ , substitute
+ ) where
+
+import Text.Regex.TDFA
+
+-- | Match a regular expression against a string, returning more information
+-- about the match.
+matchRegexAll :: Regex -> String -> Maybe (String, String, String, [String])
+matchRegexAll p str = matchM p str
+
+-- | Replaces every occurance of the given regexp with the replacement string.
+subRegex :: Regex -- ^ Search pattern
+ -> String -- ^ Input string
+ -> String -- ^ Replacement text
+ -> String -- ^ Output string
+subRegex _ "" _ = ""
+subRegex regexp inp replacement =
+ let -- bre matches a backslash then capture either a backslash or some digits
+ bre = makeRegex "\\\\(\\\\|[0-9]+)"
+ lookup' _ [] _ = []
+ lookup' [] _ _ = []
+ lookup' match' repl groups =
+ case matchRegexAll bre repl of
+ Nothing -> repl
+ Just (lead, _, trail, bgroups) ->
+ let newval =
+ if (head bgroups) == "\\"
+ then "\\"
+ else let index :: Int
+ index = (read (head bgroups)) - 1
+ in if index == -1
+ then match'
+ else groups !! index
+ in lead ++ newval ++ lookup' match' trail groups
+ in case matchRegexAll regexp inp of
+ Nothing -> inp
+ Just (lead, match', trail, groups) ->
+ lead ++ lookup' match' replacement groups ++ (subRegex regexp trail replacement)
+
+-- | Splits a string based on a regular expression. The regular expression
+-- should identify one delimiter.
+splitRegex :: Regex -> String -> [String]
+splitRegex _ [] = []
+splitRegex delim strIn = loop strIn where
+ loop str = case matchOnceText delim str of
+ Nothing -> [str]
+ Just (firstline, _, remainder) ->
+ if null remainder
+ then [firstline,""]
+ else firstline : loop remainder
+
+-- | Split a list at a certain element.
+split :: String -> String -> [String]
+split pattern = filter (not . null)
+ . splitRegex (makeRegex pattern)
+
+-- | Substitute a regex. Simplified interface.
+substitute :: String -- ^ Pattern to replace (regex).
+ -> String -- ^ Replacement string.
+ -> String -- ^ Input string.
+ -> String -- ^ Result.
+substitute pattern replacement str = subRegex (makeRegex pattern) str replacement
diff --git a/src/Text/Hakyll/Tags.hs b/src/Text/Hakyll/Tags.hs
index ea9ee87..69386be 100644
--- a/src/Text/Hakyll/Tags.hs
+++ b/src/Text/Hakyll/Tags.hs
@@ -12,6 +12,7 @@ import Data.List (intercalate)
import Control.Monad (foldM)
import Text.Hakyll.Context (ContextManipulation, renderValue)
+import Text.Hakyll.Regex
import Text.Hakyll.Util
import Text.Hakyll.Page
import Control.Arrow (second)
diff --git a/src/Text/Hakyll/Util.hs b/src/Text/Hakyll/Util.hs
index 319bed4..018c404 100644
--- a/src/Text/Hakyll/Util.hs
+++ b/src/Text/Hakyll/Util.hs
@@ -1,12 +1,10 @@
module Text.Hakyll.Util
( trim
- , split
, stripHTML
, link
) where
import Data.Char (isSpace)
-import Text.Regex (splitRegex, mkRegex)
-- | Trim a string (drop spaces and tabs at both sides).
trim :: String -> String
@@ -23,11 +21,6 @@ stripHTML str = let (beforeTag, rest) = break (== '<') str
where tail' [] = []
tail' xs = tail xs
--- | Split a list at a certain element.
-split :: String -> String -> [String]
-split pattern = filter (not . null)
- . splitRegex (mkRegex pattern)
-
-- | Make a HTML link.
--
-- > link "foo" "bar.html" == "<a href='bar.html'>foo</a>"
diff --git a/tests/Tests.hs b/tests/Tests.hs
index 3c2cb1e..e3cada6 100644
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -10,6 +10,7 @@ import qualified Data.ByteString.Lazy.Char8 as B
import Text.Hakyll.CompressCSS
import Text.Hakyll.Util
+import Text.Hakyll.Regex
import Text.Hakyll.Context
import Text.Hakyll.File
@@ -21,12 +22,14 @@ tests = [ testGroup "Util group" [ testProperty "trim length" prop_trim_length
, testCase "stripHTML 1" test_strip_html1
, testCase "stripHTML 2" test_strip_html2
, testCase "stripHTML 3" test_strip_html3
- , testCase "split 1" test_split1
- , testCase "split 2" test_split2
, testCase "link 1" test_link1
, testCase "link 2" test_link2
]
+ , testGroup "Regex group" [ testCase "split 1" test_split1
+ , testCase "split 2" test_split2
+ ]
+
, testGroup "CompressCSS group" [ testProperty "compressCSS length" prop_compress_css_length
, testCase "compressCSS 1" test_compress_css1
, testCase "compressCSS 2" test_compress_css2
@@ -61,14 +64,14 @@ test_strip_html2 = stripHTML "text" @?= "text"
test_strip_html3 = stripHTML "<b>Hakyll</b> is an <i>awesome</i> web framework <img src=\"foo.png\" />" @?=
"Hakyll is an awesome web framework "
--- Split test cases.
-test_split1 = split "," "1,2,3" @?= ["1", "2", "3"]
-test_split2 = split "," ",1,2," @?= ["1", "2"]
-
-- Link test cases.
test_link1 = link "foo bar" "/foo/bar.html" @?= "<a href=\"/foo/bar.html\">foo bar</a>"
test_link2 = link "back home" "/" @?= "<a href=\"/\">back home</a>"
+-- Split test cases.
+test_split1 = split "," "1,2,3" @?= ["1", "2", "3"]
+test_split2 = split "," ",1,2," @?= ["1", "2"]
+
-- CSS compression should always decrease the text length.
prop_compress_css_length str = length str >= length (compressCSS str)