ginger 0.7.0.0 → 0.7.1.0
raw patch · 4 files changed
+94/−8 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Text.Ginger.Parse: [poLStripBlocks] :: ParserOptions m -> Bool
+ Text.Ginger.Parse: [poTrimBlocks] :: ParserOptions m -> Bool
- Text.Ginger.Parse: ParserOptions :: IncludeResolver m -> Maybe SourceName -> Bool -> ParserOptions m
+ Text.Ginger.Parse: ParserOptions :: IncludeResolver m -> Maybe SourceName -> Bool -> Bool -> Bool -> ParserOptions m
Files
- CHANGELOG.md +5/−0
- ginger.cabal +1/−1
- src/Text/Ginger/Parse.hs +43/−6
- test/Text/Ginger/SimulationTests.hs +45/−1
CHANGELOG.md view
@@ -1,3 +1,8 @@+## 0.7.1.0++- `StripBlocks` and `LTrimBlocks` options+- `+` tag modifier to override whitespace stripping+ ## 0.7.0.0 - `keepTrailingNewlines` option
ginger.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: ginger-version: 0.7.0.0+version: 0.7.1.0 synopsis: An implementation of the Jinja2 template language in Haskell description: Ginger is Jinja, minus the most blatant pythonisms. Wants to be feature complete, but isn't quite there yet.
src/Text/Ginger/Parse.hs view
@@ -196,6 +196,8 @@ { poIncludeResolver :: IncludeResolver m , poSourceName :: Maybe SourceName , poKeepTrailingNewline :: Bool+ , poLStripBlocks :: Bool+ , poTrimBlocks :: Bool } mkParserOptions :: Monad m => IncludeResolver m -> ParserOptions m@@ -204,6 +206,8 @@ { poIncludeResolver = resolver , poSourceName = Nothing , poKeepTrailingNewline = False+ , poLStripBlocks = False+ , poTrimBlocks = False } data ParseState@@ -224,6 +228,21 @@ ignore :: Monad m => m a -> m () ignore = (>> return ()) +ifFlag :: Monad m => (ParserOptions m -> Bool) -> Parser m () -> Parser m () -> Parser m ()+ifFlag flag yes no = do+ cond <- asks flag+ if cond then yes else no++whenFlag :: Monad m => (ParserOptions m -> Bool) -> Parser m () -> Parser m ()+whenFlag flag yes = do+ cond <- asks flag+ when cond yes++unlessFlag :: Monad m => (ParserOptions m -> Bool) -> Parser m () -> Parser m ()+unlessFlag flag no = do+ cond <- asks flag+ when (not cond) no+ getResolver :: Monad m => Parser m (IncludeResolver m) getResolver = asks poIncludeResolver @@ -240,7 +259,8 @@ resolver <- getResolver currentSource <- fromMaybe "" <$> asks poSourceName let includeSourceName = takeDirectory currentSource </> sourceName- pres <- lift . lift $ parseGingerFile resolver includeSourceName+ opts <- ask+ pres <- lift . lift $ parseGingerFile' opts includeSourceName case pres of Right t -> return t Left err -> fail (show err)@@ -860,13 +880,14 @@ closeTagP :: Monad m => Parser m () closeTagP = do closeP '%'- keepTrailingNewline <- asks poKeepTrailingNewline- when- (not keepTrailingNewline)++ unlessFlag poKeepTrailingNewline (ignore . optional $ literalNewlineP) openP :: Monad m => Char -> Parser m ()-openP c = try (openWP c) <|> try (openNWP c)+openP c = try (openWP c)+ <|> try (openFWP c)+ <|> try (openNWP c) openWP :: Monad m => Char -> Parser m () openWP c = ignore $ do@@ -874,13 +895,23 @@ string [ '{', c, '-' ] spacesOrComment +openFWP :: Monad m => Char -> Parser m ()+openFWP c = ignore $ do+ string [ '{', c, '+' ]+ spacesOrComment++ openNWP :: Monad m => Char -> Parser m () openNWP c = ignore $ do+ whenFlag poLStripBlocks spaces string [ '{', c ]+ notFollowedBy $ oneOf "+-" spacesOrComment closeP :: Monad m => Char -> Parser m ()-closeP c = try (closeWP c) <|> try (closeNWP c)+closeP c = try (closeWP c)+ <|> try (closeFWP c)+ <|> try (closeNWP c) closeWP :: Monad m => Char -> Parser m () closeWP c = ignore $ do@@ -888,10 +919,16 @@ string [ '-', c, '}' ] spaces +closeFWP :: Monad m => Char -> Parser m ()+closeFWP c = ignore $ do+ spacesOrComment+ string [ '+', c, '}' ]+ closeNWP :: Monad m => Char -> Parser m () closeNWP c = ignore $ do spacesOrComment string [ c, '}' ]+ whenFlag poTrimBlocks spaces expressionP :: Monad m => Parser m (Expression SourcePos) expressionP = lambdaExprP <|> ternaryExprP
test/Text/Ginger/SimulationTests.hs view
@@ -29,7 +29,7 @@ [ testCase "Comment does not appear in output" $ mkTestHtml [] [] "- {# Comments #} -" "- -" ]- , testGroup "Dashed limiters eat whitespace"+ , testGroup "Dashed delimiters eat whitespace" [ testCase "comments" $ mkTestHtml [] [] "- {#- Comment -#} -" "--" , testCase "interpolations" $ mkTestHtml@@ -37,6 +37,45 @@ , testCase "flow" $ mkTestHtml [] [] "- {%- set x=1 -%} -" "--" ]+ , testGroup "Default delimiters eat whitespace with LStripBlocks"+ [ testCase "comments" $ mkTestHtmlOpts+ (\o -> o { poLStripBlocks = True })+ [] [] "- {# Comment #}" "-"+ , testCase "interpolations" $ mkTestHtmlOpts+ (\o -> o { poLStripBlocks = True })+ [] [] "- {{ '' }}" "-"+ , testCase "flow" $ mkTestHtmlOpts+ (\o -> o { poLStripBlocks = True })+ [] [] "- {% set x=1 %}" "-"+ , testCase "interpolations, left-only" $ mkTestHtmlOpts+ (\o -> o { poLStripBlocks = True })+ [] [] "- {{ 'a' }} -" "-a -"+ ]+ , testGroup "Default delimiters eat whitespace with TrimBlocks"+ [ testCase "comments" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True })+ [] [] "{# Comment #} -" "-"+ , testCase "interpolations" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True })+ [] [] "{{ '' }} -" "-"+ , testCase "flow" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True })+ [] [] "{% set x=1 %} -" "-"+ , testCase "interpolations, right-only" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True })+ [] [] "- {{ 'a' }} -" "- a-"+ ]+ , testGroup "Plussed delimiters override LStrip/TrimBlocks"+ [ testCase "comments" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True, poLStripBlocks = True })+ [] [] "- {#+ Comment +#} -" "- -"+ , testCase "interpolations" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True, poLStripBlocks = True })+ [] [] "- {{+ '' +}} -" "- -"+ , testCase "flow" $ mkTestHtmlOpts+ (\o -> o { poTrimBlocks = True, poLStripBlocks = True })+ [] [] "- {%+ set x=1 +%} -" "- -"+ ] , testGroup "Trailing newlines" [ testCase "eaten after blocks" $ mkTestHtml [] [] "{% if true %}\nHello!\n{% endif %}\n" "Hello!\n"@@ -782,6 +821,11 @@ mkTestHtml [] [("./features-included.html", "Hello, {{ user }}!")] "{% set user='world' %}{% include 'features-included.html' %}" "Hello, world!"+ , testCase "not eaten after blocks in included template when keepTrailingNewline is on" $+ mkTestHtmlOpts (\o -> o { poKeepTrailingNewline = True })+ [] [("./features-included.html", "Hello, {% if true %}\n{{ user }}{% endif %}\n!")]+ "{% set user='world' %}{% include 'features-included.html' %}"+ "Hello, \nworld\n!" , testCase "include referencing an included variable" $ do mkTestHtml [] [("./features-included.html", "{% set user = 'foobar' %}")] "{% include 'features-included.html' %}Hello, {{ user }}!"