Skip to content

Commit

Permalink
Add an operator to set the content of an element.
Browse files Browse the repository at this point in the history
  • Loading branch information
noteed committed Jun 21, 2024
1 parent 1f9ce9f commit 9c10f31
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 10 deletions.
3 changes: 3 additions & 0 deletions examples/interpolation.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<p>
Hello, <a></a>.
</p>
<p>
Hello, <span><a>world</a></span>.
</p>
<p>
Hello, <a></a>.
</p>
Expand Down
1 change: 1 addition & 0 deletions examples/interpolation.slab
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ body
p Hello, #('Charlie').
p Hello, #(42).
p Hello, #(a).
p Hello, #(span | a | 'world').
p Hello, #{a}.
p Hello, #{a number #(1)}.
p Hello, #{el x}.
14 changes: 13 additions & 1 deletion src/Slab/Evaluate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,15 @@ evalExpr env = \case
(Int i, Int j) -> pure . Bool $ i == j
(SingleQuoteString s, SingleQuoteString t) -> pure . Bool $ s == t
_ -> throwE $ Error.EvaluateError $ "Unimplemented (equal): " <> T.pack (show (Equal a' b'))
Cons a b -> do
a' <- evalExpr env a
b' <- evalExpr env b
case (a', b') of
(Block bl, Block c) ->
pure . Block $ setContent [c] bl
(Block bl, SingleQuoteString s) ->
pure . Block $ setContent [BlockText Normal [Lit s]] bl
_ -> throwE $ Error.EvaluateError $ "Unimplemented (cons): " <> T.pack (show (Cons a' b'))
Application a b -> do
a' <- evalExpr env a
b' <- evalExpr env b
Expand All @@ -286,7 +295,9 @@ evalExpr env = \case
evalExpr capturedEnv code
frag@(Frag _ _ _) -> do
blocks <- evalFrag env ["frag"] "-" [] [] frag
pure . Block $ BlockList blocks
case blocks of
[bl] -> pure $ Block bl
_ -> pure . Block $ BlockList blocks
Block b -> do
b' <- eval env ["block"] b
pure $ Block b'
Expand Down Expand Up @@ -322,6 +333,7 @@ evalInline env = \case
code' <- evalExpr env code
case code' of
SingleQuoteString _ -> pure $ Place code'
Bool _ -> pure $ Place code'
Int _ -> pure $ Place code'
Block _ -> pure $ Place code'
-- Variable x -> context x -- Should not happen after evalExpr
Expand Down
18 changes: 10 additions & 8 deletions src/Slab/Parse.hs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ operatorTable =
, [InfixL (symbol "+" $> Add), InfixL (symbol "-" $> Sub)]
, [InfixL (symbol ">" $> GreaterThan), InfixL (symbol "<" $> LesserThan)]
, [InfixL (symbol "==" $> Equal)]
, -- I'd like to use : instead, but it is already used for objects...
[InfixR (symbol "|" $> Cons)]
]

parserVariable' :: Parser Expr
Expand Down Expand Up @@ -682,7 +684,7 @@ parseLit :: InlineContext -> Parser Inline
parseLit ctx = do
s <- case ctx of
NormalBlock -> M.takeWhile1P (Just "literal") (\c -> c /= '#' && c /= '\n')
InlineBlock -> M.takeWhile1P (Just "literal") (\c -> c /= '#' && c /= '\n' && c/= '}')
InlineBlock -> M.takeWhile1P (Just "literal") (\c -> c /= '#' && c /= '\n' && c /= '}')
pure $ Lit s

parsePlaceExpr :: Parser Inline
Expand All @@ -702,13 +704,13 @@ parsePlaceBlock = do
-- | Equivalent to `parserBlock` but in an inline context.
parseInlineBlock :: Parser Block
parseInlineBlock = do
header <- parserDiv <|> parserCall
template <- parseInlines' InlineBlock
-- Don't return anything of the template is empty. to avoid a newline when
-- rendering.
if null template
then pure $ header []
else pure $ header [BlockText Dot template]
header <- parserDiv <|> parserCall
template <- parseInlines' InlineBlock
-- Don't return anything of the template is empty. to avoid a newline when
-- rendering.
if null template
then pure $ header []
else pure $ header [BlockText Dot template]

parseEscape :: Parser Inline
parseEscape = do
Expand Down
1 change: 1 addition & 0 deletions src/Slab/Render.hs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ renderInline = \case
Syntax.Place code -> do
case code of
Syntax.SingleQuoteString s -> s
Syntax.Bool x -> T.pack $ show x
Syntax.Int x -> T.pack $ show x
Syntax.Block b -> TL.toStrict . renderHtml $ renderBlock b
x -> error $ "renderInline: unhandled value: " <> show x
Expand Down
12 changes: 11 additions & 1 deletion src/Slab/Syntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Slab.Syntax
, isDoctype
, pasteBlocks
, setAttrs
, setContent
, CommentType (..)
, Elem (..)
, TrailingSym (..)
Expand Down Expand Up @@ -84,12 +85,18 @@ pasteBlocks a b = BlockList $ peel a <> peel b
peel (BlockList xs) = xs
peel x = [x]

-- | Set attrs on a the block, if it is a BlockElem.
-- | Set attrs on a the first block, if it is a BlockElem.
setAttrs :: [Attr] -> [Block] -> [Block]
setAttrs attrs (BlockElem name mdot attrs' nodes : bs) =
BlockElem name mdot (attrs' <> attrs) nodes : bs
setAttrs _ bs = bs

-- | Set the content on a block, if it is a BlockElem.
setContent :: [Block] -> Block -> Block
setContent nodes (BlockElem name mdot attrs _) =
BlockElem name mdot attrs nodes
setContent _ b = b

-- | A "passthrough" comment will be included in the generated HTML.
data CommentType = NormalComment | PassthroughComment
deriving (Show, Eq)
Expand Down Expand Up @@ -190,6 +197,9 @@ data Expr
| GreaterThan Expr Expr
| LesserThan Expr Expr
| Equal Expr Expr
| -- Not really a cons for lists, but instead to add content to an element.
-- E.g. p : "Hello."
Cons Expr Expr
| Block Block
| -- Expr can be a fragment, so we can manipulate them with code later.
-- We also capture the current environment.
Expand Down

0 comments on commit 9c10f31

Please sign in to comment.