@@ -0,0 +1,62 @@
1+-- | Module providing a function to parse a page from a file
3+module Hakyll.Web.Page.Read
7+import Control.Applicative ((<$>), (<*>))
8+import Control.Arrow (second, (***))
9+import Control.Monad.State
10+import Data.List (isPrefixOf)
12+import qualified Data.Map as M
14+import Hakyll.Web.Page
15+import Hakyll.Web.Util.String
17+-- | We're using a simple state monad as parser
19+type LineParser = State [String]
21+-- | Check if the given string is a metadata delimiter.
23+isPossibleDelimiter :: String -> Bool
24+isPossibleDelimiter = isPrefixOf "---"
26+-- | Read the metadata section from a page
28+parseMetadata :: LineParser (Map String String)
29+parseMetadata = get >>= \content -> case content of
30+ -- No lines means no metadata
32+ -- Check if the file begins with a delimiter
33+ (l : ls) -> if not (isPossibleDelimiter l)
34+ then -- No delimiter means no body
36+ else do -- Break the metadata section
37+ let (metadata, rest) = second (drop 1) $ break (== l) ls
40+ -- Parse the metadata
41+ return $ M.fromList $ map parseMetadata' metadata
43+ parseMetadata' :: String -> (String, String)
44+ parseMetadata' = (trim *** trim . drop 1) . break (== ':')
46+-- | Read the body section of a page
48+parseBody :: LineParser String
52+ return $ unlines body
54+-- | Read an entire page
56+parsePage :: LineParser (Page String)
57+parsePage = Page <$> parseMetadata <*> parseBody
59+-- | Read a page from a string
61+readPage :: String -> Page String
62+readPage = evalState parsePage . lines