    -- |
    -- Module      :  Text.Microstache.Parser
    -- Copyright   :  © 2016–2017 Stack Builders
    -- License     :  BSD 3 clause
    --
    -- Maintainer  :  Mark Karpov <markkarpov@openmailbox.org>
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Megaparsec parser for Mustache templates. You don't usually need to
    -- import the module, because "Text.Microstache" re-exports everything you may
    -- need, import that module instead.

    module Text.Microstache.Parser
      ( parseMustache )
    where

    import Control.Applicative   (Alternative (..), (<$), (<$>))
    import Control.Monad         (unless, void)
    import Data.Char             (isAlphaNum, isSpace)
    import Data.Functor.Identity (Identity, runIdentity)
    import Data.List             (intercalate)
    import Data.Maybe            (catMaybes)
    import Data.Text.Lazy        (Text)
    import Data.Word             (Word)
    import Text.Parsec
           (ParseError, ParsecT, Stream, anyChar, between, char, choice, eof,
           getPosition, getState, label, lookAhead, manyTill, notFollowedBy, oneOf,
           putState, runParserT, satisfy, sepBy1, sourceColumn, spaces, string, try,
           (<?>))
    import Text.Parsec.Char ()

    import Text.Microstache.Type

    import qualified Data.Text as T

    ----------------------------------------------------------------------------
    -- Parser

    -- | Parse given Mustache template.

    parseMustache
      :: FilePath
         -- ^ Location of file to parse
      -> Text
         -- ^ File contents (Mustache template)
      -> Either ParseError [Node]
         -- ^ Parsed nodes or parse error
    parseMustache :: String -> Text -> Either ParseError [Node]
    parseMustache String
    name Text
    contents = Identity (Either ParseError [Node]) -> Either ParseError [Node]
    forall a. Identity a -> a
    runIdentity (ParsecT Text Delimiters Identity [Node]
    -> Delimiters
    -> String
    -> Text
    -> Identity (Either ParseError [Node])
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> u -> String -> s -> m (Either ParseError a)
    runParserT (Parser () -> ParsecT Text Delimiters Identity [Node]
    pMustache Parser ()
    forall s (m :: * -> *) t u.
    (Stream s m t, Show t) =>
    ParsecT s u m ()
    eof) (String -> String -> Delimiters
    Delimiters String
    "{{" String
    "}}") String
    name Text
    contents)

    pMustache :: Parser () -> Parser [Node]
    pMustache :: Parser () -> ParsecT Text Delimiters Identity [Node]
    pMustache = ([Maybe Node] -> [Node])
    -> ParsecT Text Delimiters Identity [Maybe Node]
    -> ParsecT Text Delimiters Identity [Node]
    forall a b.
    (a -> b)
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    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]
     -> ParsecT Text Delimiters Identity [Node])
    -> (Parser () -> ParsecT Text Delimiters Identity [Maybe Node])
    -> Parser ()
    -> ParsecT Text Delimiters Identity [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 a b.
    a
    -> ParsecT Text Delimiters Identity b
    -> ParsecT Text Delimiters Identity a
    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
    <$> String
    -> (Key -> [Node] -> Node) -> ParsecT Text Delimiters Identity Node
    pSection String
    "#" 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
    <$> String
    -> (Key -> [Node] -> Node) -> ParsecT Text Delimiters Identity Node
    pSection String
    "^" 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 a b.
    a
    -> ParsecT Text Delimiters Identity b
    -> ParsecT Text Delimiters Identity a
    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
      start <- (Delimiters -> String) -> ParsecT Text Delimiters Identity String
    forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets Delimiters -> String
    openingDel
      (void . notFollowedBy . string') start
      let 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 String -> Parser ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (ParsecT Text Delimiters Identity String -> Parser ())
    -> (String -> ParsecT Text Delimiters Identity String)
    -> String
    -> Parser ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ParsecT Text Delimiters Identity String
    -> ParsecT Text Delimiters Identity String
    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 String
     -> ParsecT Text Delimiters Identity String)
    -> (String -> ParsecT Text Delimiters Identity String)
    -> String
    -> ParsecT Text Delimiters Identity String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ParsecT Text Delimiters Identity String
    string') String
    start
            , Parser ()
    pBol
            , Parser ()
    forall s (m :: * -> *) t u.
    (Stream s m t, Show t) =>
    ParsecT s u m ()
    eof ]
      TextBlock . T.pack <$> someTill anyChar 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
    <$> String -> ParsecT Text Delimiters Identity Key
    pTag String
    "&"
    {-# INLINE pUnescapedVariable #-}

    pUnescapedSpecial :: Parser Node
    pUnescapedSpecial :: ParsecT Text Delimiters Identity Node
    pUnescapedSpecial = do
      start <- (Delimiters -> String) -> ParsecT Text Delimiters Identity String
    forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets Delimiters -> String
    openingDel
      end   <- gets closingDel
      between (symbol $ start ++ "{") (string $ "}" ++ end) $
        UnescapedVar <$> pKey
    {-# INLINE pUnescapedSpecial #-}

    pSection :: String -> (Key -> [Node] -> Node) -> Parser Node
    pSection :: String
    -> (Key -> [Node] -> Node) -> ParsecT Text Delimiters Identity Node
    pSection String
    suffix Key -> [Node] -> Node
    f = do
      key   <- ParsecT Text Delimiters Identity Key
    -> ParsecT Text Delimiters Identity Key
    forall a. Parser a -> Parser a
    withStandalone (String -> ParsecT Text Delimiters Identity Key
    pTag String
    suffix)
      nodes <- (pMustache . withStandalone . pClosingTag) key
      return (f key nodes)
    {-# INLINE pSection #-}

    pPartial :: (Word -> Maybe Word) -> Parser Node
    pPartial :: (Word -> Maybe Word) -> ParsecT Text Delimiters Identity Node
    pPartial Word -> Maybe Word
    f = do
      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 <- pTag ">"
      let pname = Text -> PName
    PName (Text -> PName) -> Text -> PName
    forall a b. (a -> b) -> a -> b
    $ Text -> [Text] -> Text
    T.intercalate (String -> Text
    T.pack String
    ".") (Key -> [Text]
    unKey Key
    key)
      return (Partial pname pos)
    {-# INLINE pPartial #-}

    pComment :: Parser ()
    pComment :: Parser ()
    pComment = ParsecT Text Delimiters Identity String -> Parser ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (ParsecT Text Delimiters Identity String -> Parser ())
    -> ParsecT Text Delimiters Identity String -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ do
      start <- (Delimiters -> String) -> ParsecT Text Delimiters Identity String
    forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets Delimiters -> String
    openingDel
      end   <- gets closingDel
      (void . symbol) (start ++ "!")
      manyTill anyChar (string 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
      start <- (Delimiters -> String) -> ParsecT Text Delimiters Identity String
    forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets Delimiters -> String
    openingDel
      end   <- gets closingDel
      (void . symbol) (start ++ "=")
      start' <- pDelimiter <* scn
      end'   <- pDelimiter <* scn
      (void . string) ("=" ++ end)
      putState (Delimiters start' 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
    <$> String -> ParsecT Text Delimiters Identity Key
    pTag String
    ""
    {-# INLINE pEscapedVariable #-}

    withStandalone :: Parser a -> Parser a
    withStandalone :: forall a. Parser a -> Parser a
    withStandalone Parser a
    p = Parser a -> Parser a
    forall a. Parser a -> Parser a
    pStandalone Parser a
    p Parser a -> Parser a -> Parser a
    forall a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Parser a
    p
    {-# INLINE withStandalone #-}

    pStandalone :: Parser a -> Parser a
    pStandalone :: forall a. Parser a -> Parser a
    pStandalone Parser a
    p = Parser ()
    pBol Parser () -> Parser a -> Parser a
    forall a b.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    -> ParsecT Text Delimiters Identity b
    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 a b.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    -> ParsecT Text Delimiters Identity a
    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 a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    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 :: String -> ParsecT Text Delimiters Identity Key
    pTag String
    suffix = do
      start <- (Delimiters -> String) -> ParsecT Text Delimiters Identity String
    forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets Delimiters -> String
    openingDel
      end   <- gets closingDel
      between (symbol $ start ++ suffix) (string end) pKey
    {-# INLINE pTag #-}

    pClosingTag :: Key -> Parser ()
    pClosingTag :: Key -> Parser ()
    pClosingTag Key
    key = do
      start <- (Delimiters -> String) -> ParsecT Text Delimiters Identity String
    forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets Delimiters -> String
    openingDel
      end   <- gets closingDel
      let str = Key -> String
    keyToString Key
    key
      void $ between (symbol $ start ++ "/") (string end) (symbol 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 a b.
    (a -> b)
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    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]
     -> String -> ParsecT Text Delimiters Identity [Text])
    -> String
    -> 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]
    -> String -> ParsecT Text Delimiters Identity [Text]
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> String -> ParsecT s u m a
    label String
    "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 a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    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 a b.
    a -> ParsecT Text u Identity b -> 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 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 (String -> Text
    T.pack (String -> Text)
    -> ParsecT Text Delimiters Identity String
    -> 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 String
    forall a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity [a]
    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 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 a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> String -> ParsecT Text Delimiters Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m Char
    oneOf String
    "-_"
    {-# INLINE pKey #-}

    pDelimiter :: Parser String
    pDelimiter :: ParsecT Text Delimiters Identity String
    pDelimiter = ParsecT Text Delimiters Identity Char
    -> ParsecT Text Delimiters Identity String
    forall a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity [a]
    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 String
    -> String -> ParsecT Text Delimiters Identity String
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> String -> ParsecT s u m a
    <?> String
    "delimiter"
      where delChar :: Char -> Bool
    delChar 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
    /= Char
    '='
    {-# 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 a b.
    (a -> b)
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    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
      level <- ParsecT Text Delimiters Identity Word
    indentLevel
      unless (level == 1) empty
    {-# INLINE pBol #-}

    ----------------------------------------------------------------------------
    -- Auxiliary types

    -- | Type of Mustache parser monad stack.

    type Parser = ParsecT Text Delimiters Identity

    -- | State used in Mustache parser. It includes currently set opening and
    -- closing delimiters.

    data Delimiters = Delimiters
      { Delimiters -> String
    openingDel :: String
      , Delimiters -> String
    closingDel :: String }

    ----------------------------------------------------------------------------
    -- Lexer helpers and other

    -- TODO: OLEG inline
    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 String -> Parser ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (ParsecT Text Delimiters Identity Char
    -> ParsecT Text Delimiters Identity String
    forall a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity [a]
    forall (f :: * -> *) a. Alternative f => f a -> f [a]
    many (String -> ParsecT Text Delimiters Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m Char
    oneOf String
    " \t"))
    {-# INLINE sc #-}

    lexeme :: Parser a -> Parser a
    lexeme :: forall a. Parser a -> Parser a
    lexeme Parser a
    p = Parser a
    p Parser a -> Parser () -> Parser a
    forall a b.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    -> ParsecT Text Delimiters Identity 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 Char
    '\n') Parser () -> Parser () -> Parser ()
    forall a.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity a
    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 Char
    '\r' ParsecT Text Delimiters Identity Char
    -> ParsecT Text Delimiters Identity Char
    -> ParsecT Text Delimiters Identity Char
    forall a b.
    ParsecT Text Delimiters Identity a
    -> ParsecT Text Delimiters Identity b
    -> ParsecT Text Delimiters Identity b
    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 Char
    '\n')

    string' :: String -> Parser String
    string' :: String -> ParsecT Text Delimiters Identity String
    string' = ParsecT Text Delimiters Identity String
    -> ParsecT Text Delimiters Identity String
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (ParsecT Text Delimiters Identity String
     -> ParsecT Text Delimiters Identity String)
    -> (String -> ParsecT Text Delimiters Identity String)
    -> String
    -> ParsecT Text Delimiters Identity String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ParsecT Text Delimiters Identity String
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m String
    string

    symbol :: String -> Parser String
    symbol :: String -> ParsecT Text Delimiters Identity String
    symbol = ParsecT Text Delimiters Identity String
    -> ParsecT Text Delimiters Identity String
    forall a. Parser a -> Parser a
    lexeme (ParsecT Text Delimiters Identity String
     -> ParsecT Text Delimiters Identity String)
    -> (String -> ParsecT Text Delimiters Identity String)
    -> String
    -> ParsecT Text Delimiters Identity String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ParsecT Text Delimiters Identity String
    string'
    {-# INLINE symbol #-}

    keyToString :: Key -> String
    keyToString :: Key -> String
    keyToString (Key []) = String
    "."
    keyToString (Key [Text]
    ks) = String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate String
    "." (Text -> String
    T.unpack (Text -> String) -> [Text] -> [String]
    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 :: 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 s u m a
    p 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 a b.
    ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
    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 :: forall (m :: * -> *) u a s. Monad m => (u -> a) -> ParsecT s u m a
    gets u -> a
    f = (u -> a) -> ParsecT s u m u -> ParsecT s u m a
    forall a b. (a -> b) -> ParsecT s u m a -> ParsecT s u m b
    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