diff --git a/examples/expr-block.html b/examples/expr-block.html index 2462894..cd19af0 100644 --- a/examples/expr-block.html +++ b/examples/expr-block.html @@ -2,3 +2,7 @@

+
+
+
+
diff --git a/examples/expr-block.slab b/examples/expr-block.slab index e378954..d70b998 100644 --- a/examples/expr-block.slab +++ b/examples/expr-block.slab @@ -1,2 +1,3 @@ let brs = br + br body= brs +div= brs diff --git a/src/Slab/Evaluate.hs b/src/Slab/Evaluate.hs index 9241303..91cd7f8 100644 --- a/src/Slab/Evaluate.hs +++ b/src/Slab/Evaluate.hs @@ -75,10 +75,10 @@ eval env stack = \case Nothing -> pure $ BlockInclude mname path Nothing node@(BlockFragmentDef _ _ _) -> pure node - BlockFragmentCall name attrs values args -> do + BlockFragmentCall name mdot attrs values args -> do body <- call env stack name values args let body' = setAttrs attrs body - pure $ BlockFragmentCall name attrs values body' + pure $ BlockFragmentCall name mdot attrs values body' BlockFor name mindex values nodes -> do -- Re-use BlockFor to construct a single node to return. let zero :: Int @@ -169,7 +169,7 @@ namedBlock _ = pure [] unnamedBlock :: Monad m => Block -> ExceptT Error.Error m [Block] unnamedBlock (BlockImport path _ args) = - pure [BlockFragmentCall (T.pack path) [] [] args] + pure [BlockFragmentCall (T.pack path) NoSym [] [] args] unnamedBlock (BlockFragmentDef _ _ _) = pure [] unnamedBlock node = pure [node] @@ -293,7 +293,7 @@ extractVariables env = concatMap f f (BlockInclude _ _ children) = maybe [] (extractVariables env) children f (BlockFor _ _ _ _) = [] f (BlockFragmentDef name names children) = [(name, Frag names env children)] - f (BlockFragmentCall _ _ _ _) = [] + f (BlockFragmentCall _ _ _ _ _) = [] f (BlockComment _ _) = [] f (BlockFilter _ _) = [] f (BlockRawElem _ _) = [] @@ -329,7 +329,7 @@ simplify' = \case node@(BlockText _ _) -> [node] BlockInclude _ _ mnodes -> maybe [] simplify mnodes BlockFragmentDef _ _ _ -> [] - BlockFragmentCall _ _ _ args -> simplify args + BlockFragmentCall _ _ _ _ args -> simplify args BlockFor _ _ _ nodes -> simplify nodes node@(BlockComment _ _) -> [node] node@(BlockFilter _ _) -> [node] diff --git a/src/Slab/Execute.hs b/src/Slab/Execute.hs index a9657b6..f10b7b4 100644 --- a/src/Slab/Execute.hs +++ b/src/Slab/Execute.hs @@ -45,9 +45,9 @@ exec ctx = \case Syntax.BlockFragmentDef name params nodes -> do nodes' <- execute ctx nodes pure $ Syntax.BlockFragmentDef name params nodes' - Syntax.BlockFragmentCall name attrs values nodes -> do + Syntax.BlockFragmentCall name mdot attrs values nodes -> do nodes' <- execute ctx nodes - pure $ Syntax.BlockFragmentCall name attrs values nodes' + pure $ Syntax.BlockFragmentCall name mdot attrs values nodes' node@(Syntax.BlockFor _ _ _ _) -> pure node node@(Syntax.BlockComment _ _) -> pure node node@(Syntax.BlockFilter _ _) -> pure node diff --git a/src/Slab/Parse.hs b/src/Slab/Parse.hs index e8fc881..a1c017c 100644 --- a/src/Slab/Parse.hs +++ b/src/Slab/Parse.hs @@ -103,6 +103,10 @@ parserElement :: Parser (L.IndentOpt Parser Block Block) parserElement = do ref <- L.indentLevel header <- parserDiv + parserElemBody ref header + +parserElemBody :: Pos -> ([Block] -> Block) -> Parser (L.IndentOpt Parser Block Block) +parserElemBody ref header = case trailingSym $ header [] of HasDot -> do template <- parseInlines @@ -464,16 +468,14 @@ parserParameters = parserList' "{" "}" parserIdentifier "arguments" -------------------------------------------------------------------------------- parserFragmentCall :: Parser (L.IndentOpt Parser Block Block) parserFragmentCall = do + ref <- L.indentLevel -- TODO Use parserNameWithAttrs. name <- parserIdentifier attrs <- concat <$> many parserAttrs' + trailing <- parserTrailingSym args <- maybe [] id <$> optional parserArguments - template <- parseInlines - case template of - [] -> - pure $ L.IndentMany Nothing (pure . BlockFragmentCall name attrs args) parserNode - _ -> - pure $ L.IndentNone $ BlockFragmentCall name attrs args [BlockText Normal template] + let header = BlockFragmentCall name trailing attrs args + parserElemBody ref header -- E.g. {}, {1, 'a'} parserArguments :: Parser [Expr] diff --git a/src/Slab/PreProcess.hs b/src/Slab/PreProcess.hs index eb27a62..8d620f5 100644 --- a/src/Slab/PreProcess.hs +++ b/src/Slab/PreProcess.hs @@ -72,9 +72,9 @@ preproc ctx@Context {..} = \case BlockFragmentDef name params nodes -> do nodes' <- preprocess ctx nodes pure $ BlockFragmentDef name params nodes' - BlockFragmentCall name attrs values nodes -> do + BlockFragmentCall name mdot attrs values nodes -> do nodes' <- preprocess ctx nodes - pure $ BlockFragmentCall name attrs values nodes' + pure $ BlockFragmentCall name mdot attrs values nodes' node@(BlockFor _ _ _ _) -> pure node node@(BlockComment _ _) -> pure node node@(BlockFilter _ _) -> pure node diff --git a/src/Slab/Render.hs b/src/Slab/Render.hs index 8eeb24a..ff60f66 100644 --- a/src/Slab/Render.hs +++ b/src/Slab/Render.hs @@ -72,7 +72,7 @@ renderBlock (Syntax.BlockInclude (Just "escape-html") _ (Just nodes)) = renderBlock (Syntax.BlockInclude _ _ (Just nodes)) = mapM_ renderBlock nodes renderBlock (Syntax.BlockInclude _ path Nothing) = H.stringComment $ "include " <> path renderBlock (Syntax.BlockFragmentDef _ _ _) = mempty -renderBlock (Syntax.BlockFragmentCall _ _ _ nodes) = mapM_ renderBlock nodes -- TODO attrs +renderBlock (Syntax.BlockFragmentCall _ _ _ _ nodes) = mapM_ renderBlock nodes renderBlock (Syntax.BlockFor _ _ _ nodes) = mapM_ renderBlock nodes renderBlock (Syntax.BlockComment b content) = case b of @@ -129,7 +129,7 @@ extractText = f f (Syntax.BlockText _ _) = error "extractTexts called on unevaluated BlockText" f (Syntax.BlockInclude _ _ _) = error "extractTexts called on a BlockInclude" f (Syntax.BlockFragmentDef _ _ _) = error "extractTexts called on a BlockFragmentDef" - f (Syntax.BlockFragmentCall _ _ _ _) = error "extractTexts called on a BlockFragmentCall" + f (Syntax.BlockFragmentCall _ _ _ _ _) = error "extractTexts called on a BlockFragmentCall" f (Syntax.BlockFor _ _ _ _) = error "extractTexts called on a BlockFor" f (Syntax.BlockComment _ _) = error "extractTexts called on a BlockComment" f (Syntax.BlockFilter _ _) = error "extractTexts called on a BlockFilter" diff --git a/src/Slab/Syntax.hs b/src/Slab/Syntax.hs index 9ae0e0d..0609621 100644 --- a/src/Slab/Syntax.hs +++ b/src/Slab/Syntax.hs @@ -44,7 +44,7 @@ data Block | -- | This doesn't exist in Pug. This is like a mixin than receive block arguments. -- Or like a parent template that can be @extended@ by a child template. BlockFragmentDef Text [Text] [Block] - | BlockFragmentCall Text [Attr] [Expr] [Block] + | BlockFragmentCall Text TrailingSym [Attr] [Expr] [Block] | BlockFor Text (Maybe Text) Expr [Block] | -- TODO Should we allow string interpolation here ? BlockComment CommentType Text @@ -72,6 +72,7 @@ isDoctype _ = False trailingSym :: Block -> TrailingSym trailingSym (BlockElem _ sym _ _) = sym +trailingSym (BlockFragmentCall _ sym _ _ _) = sym trailingSym _ = NoSym -- | Takes two blocks and returns a BlockList containing both, but peel the @@ -247,7 +248,7 @@ extractClasses = nub . sort . concatMap f f (BlockText _ _) = [] f (BlockInclude _ _ children) = maybe [] extractClasses children f (BlockFragmentDef _ _ _) = [] -- We extract them in BlockFragmentCall instead. - f (BlockFragmentCall _ attrs _ children) = concatMap g attrs <> extractClasses children + f (BlockFragmentCall _ _ attrs _ children) = concatMap g attrs <> extractClasses children f (BlockFor _ _ _ children) = extractClasses children f (BlockComment _ _) = [] f (BlockFilter _ _) = [] @@ -283,7 +284,8 @@ extractFragments = concatMap f f (BlockText _ _) = [] f (BlockInclude _ _ children) = maybe [] extractFragments children f (BlockFragmentDef name _ children) = [BlockFragmentDef' name children] - f (BlockFragmentCall name _ _ children) = [BlockFragmentCall' name] <> extractFragments children + f (BlockFragmentCall name _ _ _ children) = + [BlockFragmentCall' name] <> extractFragments children f (BlockFor _ _ _ children) = extractFragments children f (BlockComment _ _) = [] f (BlockFilter _ _) = []