module Text.Microstache.Parser
( parseMustache )
where
import Control.Applicative hiding (many)
import Control.Monad
import Data.Char (isSpace, isAlphaNum)
import Data.List (intercalate)
import Data.Functor.Identity
import Data.Maybe (catMaybes)
import Data.Text.Lazy (Text)
import Text.Parsec hiding ((<|>))
import Text.Parsec.Char ()
import Data.Word (Word)
import Text.Microstache.Type
import qualified Data.Text as T
parseMustache
:: FilePath
-> Text
-> Either ParseError [Node]
parseMustache :: FilePath -> Text -> Either ParseError [Node]
parseMustache = Parsec Text Delimiters [Node]
-> Delimiters -> FilePath -> Text -> Either ParseError [Node]
forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> FilePath -> s -> Either ParseError a
runParser (Parser () -> Parsec Text Delimiters [Node]
pMustache Parser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) (FilePath -> FilePath -> Delimiters
Delimiters "{{" "}}")
pMustache :: Parser () -> Parser [Node]
pMustache :: Parser () -> Parsec Text Delimiters [Node]
pMustache = ([Maybe Node] -> [Node])
-> ParsecT Text Delimiters Identity [Maybe Node]
-> Parsec Text Delimiters [Node]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Maybe Node] -> [Node]
forall a. [Maybe a] -> [a]
catMaybes (ParsecT Text Delimiters Identity [Maybe Node]
-> Parsec Text Delimiters [Node])
-> (Parser () -> ParsecT Text Delimiters Identity [Maybe Node])
-> Parser ()
-> Parsec Text Delimiters [Node]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Text Delimiters Identity (Maybe Node)
-> Parser () -> ParsecT Text Delimiters Identity [Maybe Node]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ([ParsecT Text Delimiters Identity (Maybe Node)]
-> ParsecT Text Delimiters Identity (Maybe Node)
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ParsecT Text Delimiters Identity (Maybe Node)]
alts)
where
alts :: [ParsecT Text Delimiters Identity (Maybe Node)]
alts =
[ Maybe Node
forall a. Maybe a
Nothing Maybe Node
-> Parser () -> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser () -> Parser ()
forall a. Parser a -> Parser a
withStandalone Parser ()
pComment
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath
-> (Key -> [Node] -> Node) -> ParsecT Text Delimiters Identity Node
pSection "#" Key -> [Node] -> Node
Section
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath
-> (Key -> [Node] -> Node) -> ParsecT Text Delimiters Identity Node
pSection "^" Key -> [Node] -> Node
InvertedSection
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity Node
forall a. Parser a -> Parser a
pStandalone ((Word -> Maybe Word) -> ParsecT Text Delimiters Identity Node
pPartial Word -> Maybe Word
forall a. a -> Maybe a
Just)
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word -> Maybe Word) -> ParsecT Text Delimiters Identity Node
pPartial (Maybe Word -> Word -> Maybe Word
forall a b. a -> b -> a
const Maybe Word
forall a. Maybe a
Nothing)
, Maybe Node
forall a. Maybe a
Nothing Maybe Node
-> Parser () -> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser () -> Parser ()
forall a. Parser a -> Parser a
withStandalone Parser ()
pSetDelimiters
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Node
pUnescapedVariable
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Node
pUnescapedSpecial
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Node
pEscapedVariable
, Node -> Maybe Node
forall a. a -> Maybe a
Just (Node -> Maybe Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity (Maybe Node)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Node
pTextBlock ]
{-# INLINE pMustache #-}
pTextBlock :: Parser Node
pTextBlock :: ParsecT Text Delimiters Identity Node
pTextBlock = do
FilePath
start <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
openingDel
(Parser () -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser () -> Parser ())
-> (FilePath -> Parser ()) -> FilePath -> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Text Delimiters Identity FilePath -> Parser ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
string') FilePath
start
let terminator :: Parser ()
terminator = [Parser ()] -> Parser ()
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice
[ (ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath)
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> ParsecT Text Delimiters Identity FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
string') FilePath
start
, Parser ()
pBol
, Parser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof ]
Text -> Node
TextBlock (Text -> Node) -> (FilePath -> Text) -> FilePath -> Node
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text
T.pack (FilePath -> Node)
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity Node
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Char
-> Parser () -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
someTill ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar Parser ()
terminator
{-# INLINE pTextBlock #-}
pUnescapedVariable :: Parser Node
pUnescapedVariable :: ParsecT Text Delimiters Identity Node
pUnescapedVariable = Key -> Node
UnescapedVar (Key -> Node)
-> ParsecT Text Delimiters Identity Key
-> ParsecT Text Delimiters Identity Node
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> ParsecT Text Delimiters Identity Key
pTag "&"
{-# INLINE pUnescapedVariable #-}
pUnescapedSpecial :: Parser Node
pUnescapedSpecial :: ParsecT Text Delimiters Identity Node
pUnescapedSpecial = do
FilePath
start <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
openingDel
FilePath
end <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
closingDel
ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity Node
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (FilePath -> ParsecT Text Delimiters Identity FilePath
symbol (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath -> ParsecT Text Delimiters Identity FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
start FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ "{") (FilePath -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m FilePath
string (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath -> ParsecT Text Delimiters Identity FilePath
forall a b. (a -> b) -> a -> b
$ "}" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
end) (ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity Node)
-> ParsecT Text Delimiters Identity Node
-> ParsecT Text Delimiters Identity Node
forall a b. (a -> b) -> a -> b
$
Key -> Node
UnescapedVar (Key -> Node)
-> ParsecT Text Delimiters Identity Key
-> ParsecT Text Delimiters Identity Node
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Key
pKey
{-# INLINE pUnescapedSpecial #-}
pSection :: String -> (Key -> [Node] -> Node) -> Parser Node
pSection :: FilePath
-> (Key -> [Node] -> Node) -> ParsecT Text Delimiters Identity Node
pSection suffix :: FilePath
suffix f :: Key -> [Node] -> Node
f = do
Key
key <- ParsecT Text Delimiters Identity Key
-> ParsecT Text Delimiters Identity Key
forall a. Parser a -> Parser a
withStandalone (FilePath -> ParsecT Text Delimiters Identity Key
pTag FilePath
suffix)
[Node]
nodes <- (Parser () -> Parsec Text Delimiters [Node]
pMustache (Parser () -> Parsec Text Delimiters [Node])
-> (Key -> Parser ()) -> Key -> Parsec Text Delimiters [Node]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser () -> Parser ()
forall a. Parser a -> Parser a
withStandalone (Parser () -> Parser ()) -> (Key -> Parser ()) -> Key -> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Parser ()
pClosingTag) Key
key
Node -> ParsecT Text Delimiters Identity Node
forall (m :: * -> *) a. Monad m => a -> m a
return (Key -> [Node] -> Node
f Key
key [Node]
nodes)
{-# INLINE pSection #-}
pPartial :: (Word -> Maybe Word) -> Parser Node
pPartial :: (Word -> Maybe Word) -> ParsecT Text Delimiters Identity Node
pPartial f :: Word -> Maybe Word
f = do
Maybe Word
pos <- Word -> Maybe Word
f (Word -> Maybe Word)
-> ParsecT Text Delimiters Identity Word
-> ParsecT Text Delimiters Identity (Maybe Word)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Word
indentLevel
Key
key <- FilePath -> ParsecT Text Delimiters Identity Key
pTag ">"
let pname :: PName
pname = Text -> PName
PName (Text -> PName) -> Text -> PName
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate (FilePath -> Text
T.pack ".") (Key -> [Text]
unKey Key
key)
Node -> ParsecT Text Delimiters Identity Node
forall (m :: * -> *) a. Monad m => a -> m a
return (PName -> Maybe Word -> Node
Partial PName
pname Maybe Word
pos)
{-# INLINE pPartial #-}
pComment :: Parser ()
= ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> ParsecT Text Delimiters Identity FilePath -> Parser ()
forall a b. (a -> b) -> a -> b
$ do
FilePath
start <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
openingDel
FilePath
end <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
closingDel
(ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
symbol) (FilePath
start FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ "!")
ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar (FilePath -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m FilePath
string FilePath
end)
{-# INLINE pComment #-}
pSetDelimiters :: Parser ()
pSetDelimiters :: Parser ()
pSetDelimiters = Parser () -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser () -> Parser ()) -> Parser () -> Parser ()
forall a b. (a -> b) -> a -> b
$ do
FilePath
start <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
openingDel
FilePath
end <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
closingDel
(ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
symbol) (FilePath
start FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ "=")
FilePath
start' <- ParsecT Text Delimiters Identity FilePath
pDelimiter ParsecT Text Delimiters Identity FilePath
-> Parser () -> ParsecT Text Delimiters Identity FilePath
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
scn
FilePath
end' <- ParsecT Text Delimiters Identity FilePath
pDelimiter ParsecT Text Delimiters Identity FilePath
-> Parser () -> ParsecT Text Delimiters Identity FilePath
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
scn
(ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m FilePath
string) ("=" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
end)
Delimiters -> Parser ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (FilePath -> FilePath -> Delimiters
Delimiters FilePath
start' FilePath
end')
{-# INLINE pSetDelimiters #-}
pEscapedVariable :: Parser Node
pEscapedVariable :: ParsecT Text Delimiters Identity Node
pEscapedVariable = Key -> Node
EscapedVar (Key -> Node)
-> ParsecT Text Delimiters Identity Key
-> ParsecT Text Delimiters Identity Node
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> ParsecT Text Delimiters Identity Key
pTag ""
{-# INLINE pEscapedVariable #-}
withStandalone :: Parser a -> Parser a
withStandalone :: Parser a -> Parser a
withStandalone p :: Parser a
p = Parser a -> Parser a
forall a. Parser a -> Parser a
pStandalone Parser a
p Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser a
p
{-# INLINE withStandalone #-}
pStandalone :: Parser a -> Parser a
pStandalone :: Parser a -> Parser a
pStandalone p :: Parser a
p = Parser ()
pBol Parser () -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a -> Parser a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Parser () -> Parser () -> Parser a -> Parser a
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between Parser ()
sc (Parser ()
sc Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Parser () -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Parser ()
eol Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof)) Parser a
p)
{-# INLINE pStandalone #-}
pTag :: String -> Parser Key
pTag :: FilePath -> ParsecT Text Delimiters Identity Key
pTag suffix :: FilePath
suffix = do
FilePath
start <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
openingDel
FilePath
end <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
closingDel
ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity Key
-> ParsecT Text Delimiters Identity Key
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (FilePath -> ParsecT Text Delimiters Identity FilePath
symbol (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath -> ParsecT Text Delimiters Identity FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
start FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
suffix) (FilePath -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m FilePath
string FilePath
end) ParsecT Text Delimiters Identity Key
pKey
{-# INLINE pTag #-}
pClosingTag :: Key -> Parser ()
pClosingTag :: Key -> Parser ()
pClosingTag key :: Key
key = do
FilePath
start <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
openingDel
FilePath
end <- (Delimiters -> FilePath)
-> ParsecT Text Delimiters Identity FilePath
forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
gets Delimiters -> FilePath
closingDel
let str :: FilePath
str = Key -> FilePath
keyToString Key
key
ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity FilePath -> Parser ())
-> ParsecT Text Delimiters Identity FilePath -> Parser ()
forall a b. (a -> b) -> a -> b
$ ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (FilePath -> ParsecT Text Delimiters Identity FilePath
symbol (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath -> ParsecT Text Delimiters Identity FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
start FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ "/") (FilePath -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m FilePath
string FilePath
end) (FilePath -> ParsecT Text Delimiters Identity FilePath
symbol FilePath
str)
{-# INLINE pClosingTag #-}
pKey :: Parser Key
pKey :: ParsecT Text Delimiters Identity Key
pKey = (([Text] -> Key)
-> ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity Key
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Text] -> Key
Key (ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity Key)
-> (ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text])
-> ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text]
forall a. Parser a -> Parser a
lexeme (ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text])
-> (ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text])
-> ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParsecT Text Delimiters Identity [Text]
-> FilePath -> ParsecT Text Delimiters Identity [Text])
-> FilePath
-> ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ParsecT Text Delimiters Identity [Text]
-> FilePath -> ParsecT Text Delimiters Identity [Text]
forall s u (m :: * -> *) a.
ParsecT s u m a -> FilePath -> ParsecT s u m a
label "key") (ParsecT Text Delimiters Identity [Text]
forall u a. ParsecT Text u Identity [a]
implicit ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text]
-> ParsecT Text Delimiters Identity [Text]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Text Delimiters Identity [Text]
other)
where
implicit :: ParsecT Text u Identity [a]
implicit = [] [a] -> ParsecT Text u Identity Char -> ParsecT Text u Identity [a]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT Text u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '.'
other :: ParsecT Text Delimiters Identity [Text]
other = ParsecT Text Delimiters Identity Text
-> ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity [Text]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
sepBy1 (FilePath -> Text
T.pack (FilePath -> Text)
-> ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity FilePath
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some ParsecT Text Delimiters Identity Char
ch) (Char -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '.')
ch :: ParsecT Text Delimiters Identity Char
ch = ParsecT Text Delimiters Identity Char
alphaNumChar ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> FilePath -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m Char
oneOf "-_"
{-# INLINE pKey #-}
pDelimiter :: Parser String
pDelimiter :: ParsecT Text Delimiters Identity FilePath
pDelimiter = ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity FilePath
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some ((Char -> Bool) -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
delChar) ParsecT Text Delimiters Identity FilePath
-> FilePath -> ParsecT Text Delimiters Identity FilePath
forall s u (m :: * -> *) a.
ParsecT s u m a -> FilePath -> ParsecT s u m a
<?> "delimiter"
where delChar :: Char -> Bool
delChar x :: Char
x = Bool -> Bool
not (Char -> Bool
isSpace Char
x) Bool -> Bool -> Bool
&& Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '='
{-# INLINE pDelimiter #-}
indentLevel :: Parser Word
indentLevel :: ParsecT Text Delimiters Identity Word
indentLevel = (SourcePos -> Word)
-> ParsecT Text Delimiters Identity SourcePos
-> ParsecT Text Delimiters Identity Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Column -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Column -> Word) -> (SourcePos -> Column) -> SourcePos -> Word
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourcePos -> Column
sourceColumn) ParsecT Text Delimiters Identity SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
pBol :: Parser ()
pBol :: Parser ()
pBol = do
Word
level <- ParsecT Text Delimiters Identity Word
indentLevel
Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Word
level Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== 1) Parser ()
forall (f :: * -> *) a. Alternative f => f a
empty
{-# INLINE pBol #-}
type Parser = ParsecT Text Delimiters Identity
data Delimiters = Delimiters
{ Delimiters -> FilePath
openingDel :: String
, Delimiters -> FilePath
closingDel :: String }
scn :: Parser ()
scn :: Parser ()
scn = Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
{-# INLINE scn #-}
sc :: Parser ()
sc :: Parser ()
sc = ParsecT Text Delimiters Identity FilePath -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity FilePath
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (FilePath -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m Char
oneOf " \t"))
{-# INLINE sc #-}
lexeme :: Parser a -> Parser a
lexeme :: Parser a -> Parser a
lexeme p :: Parser a
p = Parser a
p Parser a -> Parser () -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
{-# INLINE lexeme #-}
eol :: Parser ()
eol :: Parser ()
eol = ParsecT Text Delimiters Identity Char -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Char -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\n') Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Text Delimiters Identity Char -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Char -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\r' ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity Char
-> ParsecT Text Delimiters Identity Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\n')
string' :: String -> Parser String
string' :: FilePath -> ParsecT Text Delimiters Identity FilePath
string' = ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath)
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> ParsecT Text Delimiters Identity FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
forall s (m :: * -> *) u.
Stream s m Char =>
FilePath -> ParsecT s u m FilePath
string
symbol :: String -> Parser String
symbol :: FilePath -> ParsecT Text Delimiters Identity FilePath
symbol = ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath
forall a. Parser a -> Parser a
lexeme (ParsecT Text Delimiters Identity FilePath
-> ParsecT Text Delimiters Identity FilePath)
-> (FilePath -> ParsecT Text Delimiters Identity FilePath)
-> FilePath
-> ParsecT Text Delimiters Identity FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ParsecT Text Delimiters Identity FilePath
string'
{-# INLINE symbol #-}
keyToString :: Key -> String
keyToString :: Key -> FilePath
keyToString (Key []) = "."
keyToString (Key ks :: [Text]
ks) = FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate "." (Text -> FilePath
T.unpack (Text -> FilePath) -> [Text] -> [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
ks)
{-# INLINE keyToString #-}
someTill :: Stream s m t => ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
someTill :: ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
someTill p :: ParsecT s u m a
p end :: ParsecT s u m end
end = (:) (a -> [a] -> [a]) -> ParsecT s u m a -> ParsecT s u m ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m a
p ParsecT s u m ([a] -> [a])
-> ParsecT s u m [a] -> ParsecT s u m [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT s u m a
p ParsecT s u m end
end
gets :: Monad m => (u -> a) -> ParsecT s u m a
gets :: (u -> a) -> ParsecT s u m a
gets f :: u -> a
f = (u -> a) -> ParsecT s u m u -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap u -> a
f ParsecT s u m u
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
alphaNumChar :: Parser Char
alphaNumChar :: ParsecT Text Delimiters Identity Char
alphaNumChar = (Char -> Bool) -> ParsecT Text Delimiters Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isAlphaNum