From c1d16cdab337274a9f5aca40b887371ca1a1f5a1 Mon Sep 17 00:00:00 2001 From: Jasper Van der Jeugt Date: Mon, 27 Dec 2010 10:07:31 +0100 Subject: Add Page parser --- src/Hakyll/Web/Page/Read.hs | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/Hakyll/Web/Page/Read.hs 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 -- cgit v1.2.3