diff options
author | Jasper Van der Jeugt <jaspervdj@gmail.com> | 2010-12-27 10:07:31 +0100 |
---|---|---|
committer | Jasper Van der Jeugt <jaspervdj@gmail.com> | 2010-12-27 10:07:31 +0100 |
commit | c1d16cdab337274a9f5aca40b887371ca1a1f5a1 (patch) | |
tree | 8023b11f53870ac46726423403d344b11bb00e8b | |
parent | 4981cfbb7f5e2630f8b41a34a8e55796283d531c (diff) | |
download | hakyll-c1d16cdab337274a9f5aca40b887371ca1a1f5a1.tar.gz |
Add Page parser
-rw-r--r-- | src/Hakyll/Web/Page/Read.hs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/Hakyll/Web/Page/Read.hs b/src/Hakyll/Web/Page/Read.hs new file mode 100644 index 0000000..f840eba --- /dev/null +++ b/src/Hakyll/Web/Page/Read.hs @@ -0,0 +1,62 @@ +-- | Module providing a function to parse a page from a file +-- +module Hakyll.Web.Page.Read + ( readPage + ) where + +import Control.Applicative ((<$>), (<*>)) +import Control.Arrow (second, (***)) +import Control.Monad.State +import Data.List (isPrefixOf) +import Data.Map (Map) +import qualified Data.Map as M + +import Hakyll.Web.Page +import Hakyll.Web.Util.String + +-- | We're using a simple state monad as parser +-- +type LineParser = State [String] + +-- | Check if the given string is a metadata delimiter. +-- +isPossibleDelimiter :: String -> Bool +isPossibleDelimiter = isPrefixOf "---" + +-- | Read the metadata section from a page +-- +parseMetadata :: LineParser (Map String String) +parseMetadata = get >>= \content -> case content of + -- No lines means no metadata + [] -> return M.empty + -- Check if the file begins with a delimiter + (l : ls) -> if not (isPossibleDelimiter l) + then -- No delimiter means no body + return M.empty + else do -- Break the metadata section + let (metadata, rest) = second (drop 1) $ break (== l) ls + -- Put the rest back + put rest + -- Parse the metadata + return $ M.fromList $ map parseMetadata' metadata + where + parseMetadata' :: String -> (String, String) + parseMetadata' = (trim *** trim . drop 1) . break (== ':') + +-- | Read the body section of a page +-- +parseBody :: LineParser String +parseBody = do + body <- get + put [] + return $ unlines body + +-- | Read an entire page +-- +parsePage :: LineParser (Page String) +parsePage = Page <$> parseMetadata <*> parseBody + +-- | Read a page from a string +-- +readPage :: String -> Page String +readPage = evalState parsePage . lines |