Skip to content

Instantly share code, notes, and snippets.

@jaspervdj
Created July 18, 2011 15:05
Show Gist options
  • Save jaspervdj/1089784 to your computer and use it in GitHub Desktop.
Save jaspervdj/1089784 to your computer and use it in GitHub Desktop.
Hakyll page parser using Parsec
import Control.Applicative ((<$>), (<*>), (<*))
import Text.Parsec.Prim (many, skipMany)
import Text.Parsec.Combinator (choice, many1, manyTill, option)
import Text.Parsec.Char (alphaNum, anyChar, char, newline, spaces, string)
import Text.Parsec.String (Parser)
openMetadata :: Parser String
openMetadata = many1 (char '-') <* newline
metadataField :: Parser (String, String)
metadataField = do
key <- manyTill alphaNum $ char ':'
spaces
value <- manyTill anyChar newline
trailing' <- many trailing
return (key, value ++ concat trailing')
where
trailing = (++) <$> many1 (char ' ') <*> manyTill anyChar newline
closeMetadata :: String -> Parser ()
closeMetadata open = do
_ <- choice $ map (string . replicate len) ['-', '.']
_ <- newline
return ()
where
len = length open
metadata :: Parser [(String, String)]
metadata = do
open <- openMetadata
metadata' <- many metadataField
closeMetadata open
return metadata'
page :: Parser ([(String, String)], String)
page = do
metadata' <- option [] metadata
skipMany newline
body <- many anyChar
return (metadata', body)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment