aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMirek Kratochvil <exa.exa@gmail.com>2023-05-27 20:21:15 +0200
committerMirek Kratochvil <exa.exa@gmail.com>2023-05-27 20:21:15 +0200
commit08742b6b310468ac5e6e09adb5a31d300c998411 (patch)
treef6caa335f6220769dee3737805e38021a18f3e8c
parent73498534cfdccab95e580f8d6b121655d00e7578 (diff)
downloadreploy-08742b6b310468ac5e6e09adb5a31d300c998411.tar.gz
reploy-08742b6b310468ac5e6e09adb5a31d300c998411.tar.bz2
implement simple harmless "true check" to mustache
-rw-r--r--mustache/src/Text/Mustache/Compile.hs1
-rw-r--r--mustache/src/Text/Mustache/Internal/Types.hs2
-rw-r--r--mustache/src/Text/Mustache/Parser.hs27
-rw-r--r--mustache/src/Text/Mustache/Render.hs12
4 files changed, 32 insertions, 10 deletions
diff --git a/mustache/src/Text/Mustache/Compile.hs b/mustache/src/Text/Mustache/Compile.hs
index 8079d6c..8e8b676 100644
--- a/mustache/src/Text/Mustache/Compile.hs
+++ b/mustache/src/Text/Mustache/Compile.hs
@@ -118,6 +118,7 @@ getPartials = join . fmap getPartials'
getPartials' :: Node Text -> [FilePath]
getPartials' (Partial _ p) = return p
getPartials' (Section _ n) = getPartials n
+getPartials' (ExistingSection _ n) = getPartials n
getPartials' (InvertedSection _ n) = getPartials n
getPartials' _ = mempty
diff --git a/mustache/src/Text/Mustache/Internal/Types.hs b/mustache/src/Text/Mustache/Internal/Types.hs
index d499ba3..296d590 100644
--- a/mustache/src/Text/Mustache/Internal/Types.hs
+++ b/mustache/src/Text/Mustache/Internal/Types.hs
@@ -28,7 +28,6 @@ import qualified Data.Text.Lazy as LT
import qualified Data.Vector as V
import Data.Word (Word8, Word16, Word32, Word64)
import Language.Haskell.TH.Lift (deriveLift)
-import Language.Haskell.TH.Syntax
import Numeric.Natural (Natural)
@@ -101,6 +100,7 @@ type ASTree α = [Node α]
data Node α
= TextBlock α
| Section DataIdentifier (ASTree α)
+ | ExistingSection DataIdentifier (ASTree α)
| InvertedSection DataIdentifier (ASTree α)
| Variable Bool DataIdentifier
| Partial (Maybe α) FilePath
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."
diff --git a/mustache/src/Text/Mustache/Render.hs b/mustache/src/Text/Mustache/Render.hs
index 7a0ad89..b0ae5b6 100644
--- a/mustache/src/Text/Mustache/Render.hs
+++ b/mustache/src/Text/Mustache/Render.hs
@@ -148,6 +148,18 @@ substituteNode (Section (NamedData secName) secSTree) =
shiftContext newContext $ substituteAST secSTree
Nothing -> tellError $ SectionTargetNotFound secName
+-- substituting an existing section (exact invert of the inverted section)
+substituteNode (ExistingSection Implicit _) = tellError InvertedImplicitSection
+substituteNode (ExistingSection (NamedData secName) invSecSTree) =
+ search secName >>= \case
+ Just (Bool False) -> return ()
+ Just (Array a) | V.null a -> return ()
+ Just Null -> return ()
+ Nothing -> return ()
+ _ -> contents
+ where
+ contents = mapM_ substituteNode invSecSTree
+
-- substituting an inverted section
substituteNode (InvertedSection Implicit _) = tellError InvertedImplicitSection
substituteNode (InvertedSection (NamedData secName) invSecSTree) =