--------------------------------------------------------------------------------
-- | Parser utilities
module Hakyll.Core.Util.Parser
    ( metadataKey
    ) where


--------------------------------------------------------------------------------
import           Control.Applicative ((<|>))
import           Control.Monad       (guard, mzero, void)
import qualified Text.Parsec         as P
import           Text.Parsec.String  (Parser)


--------------------------------------------------------------------------------
metadataKey :: Parser String
metadataKey :: Parser String
metadataKey = do
    -- Ensure trailing '-' binds to '$' if present.
    let hyphon :: ParsecT String u Identity Char
hyphon = ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT String u Identity Char -> ParsecT String u Identity Char)
-> ParsecT String u Identity Char -> ParsecT String u Identity Char
forall a b. (a -> b) -> a -> b
$ do
            ParsecT String u Identity Char -> ParsecT String u Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String u Identity Char -> ParsecT String u Identity ())
-> ParsecT String u Identity Char -> ParsecT String u Identity ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'-'
            Char
x <- ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
P.lookAhead ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.anyChar
            Bool -> ParsecT String u Identity ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT String u Identity ())
-> Bool -> ParsecT String u Identity ()
forall a b. (a -> b) -> a -> b
$ Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'$'
            Char -> ParsecT String u Identity Char
forall (f :: * -> *) a. Applicative f => a -> f a
pure Char
'-'

    String
i <- (:) (Char -> String -> String)
-> ParsecT String () Identity Char
-> ParsecT String () Identity (String -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.letter ParsecT String () Identity (String -> String)
-> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.alphaNum ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"_." ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String () Identity Char
forall u. ParsecT String u Identity Char
hyphon)
    if String
i String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
reservedKeys then Parser String
forall (m :: * -> *) a. MonadPlus m => m a
mzero else String -> Parser String
forall (m :: * -> *) a. Monad m => a -> m a
return String
i


--------------------------------------------------------------------------------
reservedKeys :: [String]
reservedKeys :: [String]
reservedKeys = [String
"if", String
"else", String
"endif", String
"for", String
"sep", String
"endfor", String
"partial"]