on master help sign in
Add Page parser
commitc1d16cdab337274a9f5aca40b887371ca1a1f5a1 authorJasper Van der Jeugt <jaspervdj@gmail.com> dateMon 27 Dec 2010, 10:07 (16 years ago) parent4981cfb
1 file changed+62
src/Hakyll/Web/Page/Read.hs+62
src/Hakyll/Web/Page/Read.hsnew file+62
@@ -0,0 +1,62 @@
1+-- | Module providing a function to parse a page from a file
2+--
3+module Hakyll.Web.Page.Read
4+ ( readPage
5+ ) where
6+
7+import Control.Applicative ((<$>), (<*>))
8+import Control.Arrow (second, (***))
9+import Control.Monad.State
10+import Data.List (isPrefixOf)
11+import Data.Map (Map)
12+import qualified Data.Map as M
13+
14+import Hakyll.Web.Page
15+import Hakyll.Web.Util.String
16+
17+-- | We're using a simple state monad as parser
18+--
19+type LineParser = State [String]
20+
21+-- | Check if the given string is a metadata delimiter.
22+--
23+isPossibleDelimiter :: String -> Bool
24+isPossibleDelimiter = isPrefixOf "---"
25+
26+-- | Read the metadata section from a page
27+--
28+parseMetadata :: LineParser (Map String String)
29+parseMetadata = get >>= \content -> case content of
30+ -- No lines means no metadata
31+ [] -> return M.empty
32+ -- Check if the file begins with a delimiter
33+ (l : ls) -> if not (isPossibleDelimiter l)
34+ then -- No delimiter means no body
35+ return M.empty
36+ else do -- Break the metadata section
37+ let (metadata, rest) = second (drop 1) $ break (== l) ls
38+ -- Put the rest back
39+ put rest
40+ -- Parse the metadata
41+ return $ M.fromList $ map parseMetadata' metadata
42+ where
43+ parseMetadata' :: String -> (String, String)
44+ parseMetadata' = (trim *** trim . drop 1) . break (== ':')
45+
46+-- | Read the body section of a page
47+--
48+parseBody :: LineParser String
49+parseBody = do
50+ body <- get
51+ put []
52+ return $ unlines body
53+
54+-- | Read an entire page
55+--
56+parsePage :: LineParser (Page String)
57+parsePage = Page <$> parseMetadata <*> parseBody
58+
59+-- | Read a page from a string
60+--
61+readPage :: String -> Page String
62+readPage = evalState parsePage . lines