aboutsummaryrefslogtreecommitdiff
path: root/mustache/src/Text/Mustache/Parser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'mustache/src/Text/Mustache/Parser.hs')
-rw-r--r--mustache/src/Text/Mustache/Parser.hs27
1 files changed, 18 insertions, 9 deletions
diff --git a/mustache/src/Text/Mustache/Parser.hs b/mustache/src/Text/Mustache/Parser.hs
index 317e7aa..2dc5d93 100644
--- a/mustache/src/Text/Mustache/Parser.hs
+++ b/mustache/src/Text/Mustache/Parser.hs
@@ -38,7 +38,6 @@ module Text.Mustache.Parser
import Control.Monad
import Data.Char (isAlphaNum, isSpace)
import Data.List (nub)
-import Data.Monoid ((<>))
import Data.Text as T (Text, null, pack)
import Prelude as Prel
import Text.Mustache.Types
@@ -60,8 +59,10 @@ data MustacheState = MustacheState
}
+data SectionStart = Normal | Existing | Inverted
+
data ParseTagRes
- = SectionBegin Bool DataIdentifier
+ = SectionBegin SectionStart DataIdentifier
| SectionEnd DataIdentifier
| Tag (Node Text)
| HandledTag
@@ -79,6 +80,9 @@ partialBegin = '>'
-- | @^@
invertedSectionBegin :: Char
invertedSectionBegin = '^'
+-- | @^@
+existingSectionBegin :: Char
+existingSectionBegin = '?'
-- | @{@ and @}@
unescape2 :: (Char, Char)
unescape2 = ('{', '}')
@@ -223,16 +227,16 @@ parseLine = do
continueFromTag :: ParseTagRes -> Parser STree
-continueFromTag (SectionBegin inverted name) = do
+continueFromTag (SectionBegin start name) = do
textNodes <- flushText
state@(MustacheState
{ currentSectionName = previousSection }) <- getState
putState $ state { currentSectionName = return name }
innerSectionContent <- parseText
- let sectionTag =
- if inverted
- then InvertedSection
- else Section
+ let sectionTag = case start of
+ Normal -> Section
+ Inverted -> InvertedSection
+ Existing -> ExistingSection
modifyState $ \s -> s { currentSectionName = previousSection }
outerSectionContent <- parseText
return (textNodes <> [sectionTag name innerSectionContent] <> outerSectionContent)
@@ -255,7 +259,7 @@ switchOnTag = do
(MustacheState { sDelimiters = ( _, end )}) <- getState
choice
- [ SectionBegin False <$> (try (char sectionBegin) >> genParseTagEnd mempty)
+ [ SectionBegin Normal <$> (try (char sectionBegin) >> genParseTagEnd mempty)
, SectionEnd
<$> (try (char sectionEnd) >> genParseTagEnd mempty)
, Tag . Variable False
@@ -266,7 +270,12 @@ switchOnTag = do
<$> (try (char partialBegin) >> spaces >> (noneOf (nub end) `manyTill` try (spaces >> string end)))
, return HandledTag
<< (try (char delimiterChange) >> parseDelimChange)
- , SectionBegin True
+ , SectionBegin Existing
+ <$> (try (char existingSectionBegin) >> genParseTagEnd mempty >>= \case
+ n@(NamedData _) -> return n
+ _ -> parserFail "Existing Sections can not be implicit."
+ )
+ , SectionBegin Inverted
<$> (try (char invertedSectionBegin) >> genParseTagEnd mempty >>= \case
n@(NamedData _) -> return n
_ -> parserFail "Inverted Sections can not be implicit."