packages feed

hamlet 0.0.1 → 0.0.2

raw patch · 5 files changed

+123/−22 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Text.Hamlet.Monad: maybeH :: (Monad m) => Maybe v -> (v -> Hamlet url m ()) -> Hamlet url m ()
+ Text.Hamlet.Parse: DocMaybe :: Deref -> Ident -> [Doc] -> Doc

Files

Text/Hamlet/Monad.hs view
@@ -18,6 +18,7 @@     , liftHamlet     , mapH     , condH+    , maybeH     , printHamlet     , hamletToText     , cdata@@ -176,6 +177,14 @@ condH ((x, y):rest) z = do     x' <- liftHamlet x     if x' then y else condH rest z++-- | Runs the second argument with the value in the first, if available.+maybeH :: Monad m+       => Maybe v+       -> (v -> Hamlet url m ())+       -> Hamlet url m ()+maybeH Nothing _ = return ()+maybeH (Just v) f = f v  -- | Prints a Hamlet to standard out. Good for debugging. printHamlet :: (url -> String) -> Hamlet url IO () -> IO ()
Text/Hamlet/Parse.hs view
@@ -19,6 +19,7 @@ import Control.Monad import Control.Arrow import Data.Data+import Data.List (intercalate)  #if TEST import Test.Framework (testGroup, Test)@@ -54,10 +55,12 @@           | LineIf Deref           | LineElseIf Deref           | LineElse+          | LineMaybe Deref Ident           | LineTag             { _lineTagName :: String             , _lineAttr :: [(String, [Content])]             , _lineContent :: [Content]+            , _lineClasses :: [[Content]]             }           | LineContent [Content]     deriving (Eq, Show, Read)@@ -86,12 +89,19 @@ parseLine _ ('$':'e':'l':'s':'e':'i':'f':' ':rest) =     LineElseIf <$> parseDeref rest parseLine _ "$else" = Ok LineElse+parseLine _ ('$':'m':'a':'y':'b':'e':' ':rest) =+    case words rest of+        [x, y] -> do+            x' <- parseDeref x+            (False, y') <- parseIdent' False y+            return $ LineMaybe x' y'+        _ -> Error $ "Invalid maybe: " ++ rest parseLine _ x@(c:_) | c `elem` "%#." = do     let (begin, rest) = break (== ' ') x         rest' = dropWhile (== ' ') rest-    (tn, attr) <- parseTag begin+    (tn, attr, classes) <- parseTag begin     con <- parseContent rest'-    return $ LineTag tn attr con+    return $ LineTag tn attr con classes parseLine _ s = LineContent <$> parseContent s  #if TEST@@ -105,14 +115,16 @@     parseLine' "$elseif foo.bar" @?= Ok (LineElseIf fooBar)     parseLine' "$else" @?= Ok LineElse     parseLine' "%img!src=@foo.bar@"-        @?= Ok (LineTag "img" [("src", [ContentUrl fooBar])] [])+        @?= Ok (LineTag "img" [("src", [ContentUrl fooBar])] [] [])     parseLine' ".$foo.bar$"-        @?= Ok (LineTag "div" [("class", [ContentVar fooBar])] [])-    parseLine' "%span#foo.bar!baz=bin"-        @?= Ok (LineTag "span" [ ("baz", [ContentRaw "bin"])-                               , ("class", [ContentRaw "bar"])-                               , ("id", [ContentRaw "foo"])-                               ] [])+        @?= Ok (LineTag "div" [] [] [[ContentVar fooBar]])+    parseLine' "%span#foo.bar.bar2!baz=bin"+        @?= Ok (LineTag "span" [ ("id", [ContentRaw "foo"])+                               , ("baz", [ContentRaw "bin"])+                               ] []+                               [ [ContentRaw "bar"]+                               , [ContentRaw "bar2"]+                               ]) #endif  parseContent :: String -> Result [Content]@@ -199,25 +211,26 @@     parseIdent "*foo" @?= Ok (True, Ident "foo") #endif -parseTag :: String -> Result (String, [(String, [Content])])+parseTag :: String -> Result (String, [(String, [Content])], [[Content]]) parseTag s = do     pieces <- takePieces s-    foldM go ("div", []) pieces+    (a, b, c) <- foldM go ("div", id, id) pieces+    return (a, b [], c [])   where-    go (_, attrs) ('%':tn) = Ok (tn, attrs)-    go (tn, attrs) ('.':cl) = do+    go (_, attrs, classes) ('%':tn) = Ok (tn, attrs, classes)+    go (tn, attrs, classes) ('.':cl) = do         con <- parseContent cl-        Ok (tn, ("class", con) : attrs)-    go (tn, attrs) ('#':cl) = do+        Ok (tn, attrs, classes . (:) con)+    go (tn, attrs, classes) ('#':cl) = do         con <- parseContent cl-        Ok (tn, ("id", con) : attrs)-    go (tn, attrs) ('!':rest) = do+        Ok (tn, attrs . (:) ("id", con), classes)+    go (tn, attrs, classes) ('!':rest) = do         let (name, val) = break (== '=') rest         val' <-             case val of                 ('=':rest') -> parseContent rest'                 _ -> Ok []-        Ok (tn, (name, val') : attrs)+        Ok (tn, attrs . (:) (name, val'), classes)     go _ _ = error "Invalid branch in Text.Hamlet.Parse.parseTag"  takePieces :: String -> Result [String]@@ -247,6 +260,7 @@  data Doc = DocForall Deref Ident [Doc]          | DocCond [(Deref, [Doc])] (Maybe [Doc])+         | DocMaybe Deref Ident [Doc]          | DocContent [Content]     deriving (Show, Eq, Read, Data, Typeable) @@ -261,7 +275,15 @@     (ifs, el, rest') <- parseConds set ((:) (d, inside')) rest     rest'' <- nestToDoc set rest'     Ok $ DocCond ifs el : rest''-nestToDoc set (Nest (LineTag tn attrs content) inside:rest) = do+nestToDoc set (Nest (LineMaybe d i) inside:rest) = do+    inside' <- nestToDoc set inside+    rest' <- nestToDoc set rest+    Ok $ DocMaybe d i inside' : rest'+nestToDoc set (Nest (LineTag tn attrs content classes) inside:rest) = do+    let attrs' = case classes of+                    [] -> attrs+                    _ -> ("class", intercalate [ContentRaw " "] classes)+                       : attrs     let closeStyle =             if not (null content) || not (null inside)                 then CloseSeparate@@ -273,10 +295,10 @@                  CloseInside -> ContentRaw "/>"                  _ -> ContentRaw ">"         start = ContentRaw $ "<" ++ tn-        attrs' = concatMap attrToContent attrs+        attrs'' = concatMap attrToContent attrs'     inside' <- nestToDoc set inside     rest' <- nestToDoc set rest-    Ok $ DocContent (start : attrs' ++ seal : content)+    Ok $ DocContent (start : attrs'' ++ seal : content)        : inside' ++ end ++ rest' nestToDoc set (Nest (LineContent content) inside:rest) = do     inside' <- nestToDoc set inside@@ -289,6 +311,8 @@ compressDoc [] = [] compressDoc (DocForall d i doc:rest) =     DocForall d i (compressDoc doc) : compressDoc rest+compressDoc (DocMaybe d i doc:rest) =+    DocMaybe d i (compressDoc doc) : compressDoc rest compressDoc (DocCond x y:rest) =     DocCond (map (second compressDoc) x) (compressDoc `fmap` y)     : compressDoc rest
Text/Hamlet/Quasi.hs view
@@ -49,6 +49,15 @@     let dos = LamE [VarP ident'] $ DoE $ inside' []     let stmt = NoBindS $ mh `AppE` dos `AppE` deref''     return (vars', arg, stmts . stmts' . (:) stmt)+docToStmt (vars, arg, stmts) (DocMaybe deref ident@(Ident name) inside) = do+    (vars', base, stmts') <- bindDeref vars arg deref+    ident' <- newName name+    let vars'' = ([ident], VarE ident') : vars'+    (_, _, inside') <- foldM docToStmt (vars'', arg, id) inside+    let dos = LamE [VarP ident'] $ DoE $ inside' []+    mh <- [|maybeH|]+    let stmt = NoBindS $ mh `AppE` base `AppE` dos+    return (vars', arg, stmts . stmts' . (:) stmt) docToStmt (vars, arg, stmts) (DocCond conds final) = do     conds' <- liftConds vars arg conds id     final' <- case final of
hamlet.cabal view
@@ -1,5 +1,5 @@ name:            hamlet-version:         0.0.1+version:         0.0.2 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>
runtests.hs view
@@ -45,6 +45,14 @@     , testCase "script not empty" caseScriptNotEmpty     , testCase "meta empty" caseMetaEmpty     , testCase "input empty" caseInputEmpty+    , testCase "multiple classes" caseMultiClass+    , testCase "attrib order" caseAttribOrder+    , testCase "nothing" caseNothing+    , testCase "nothing monad" caseNothingMonad+    , testCase "nothing chain " caseNothingChain+    , testCase "just" caseJust+    , testCase "just monad" caseJustMonad+    , testCase "just chain " caseJustChain     ]  data Url = Home@@ -66,6 +74,10 @@     , mfalse :: m Bool     , list :: [Arg m url]     , enum :: Enumerator (Arg m url) m+    , nothing :: Maybe HtmlContent+    , mnothing :: m (Maybe HtmlContent)+    , just :: Maybe HtmlContent+    , mjust :: m (Maybe HtmlContent)     }  arg :: Monad m => Arg m url@@ -84,6 +96,10 @@     , mfalse = return False     , list = [arg, arg, arg]     , enum = fromList $ list arg+    , nothing = Nothing+    , mnothing = return Nothing+    , just = Just $ Unencoded $ pack "just"+    , mjust = return $ Just $ Unencoded $ pack "just"     }  helper :: String -> (Arg IO Url -> Hamlet Url IO ()) -> Assertion@@ -237,3 +253,46 @@ caseInputEmpty = do     helper "<input>" [$hamlet|%input|]     helper "<input/>" [$xhamlet|%input|]++caseMultiClass :: Assertion+caseMultiClass = do+    helper "<div class=\"foo bar\"></div>" [$hamlet|.foo.bar|]++caseAttribOrder :: Assertion+caseAttribOrder = helper "<meta 1 2 3>" [$hamlet|%meta!1!2!3|]++caseNothing :: Assertion+caseNothing = helper "" [$hamlet|+$maybe nothing n+    nothing+|]++caseNothingMonad :: Assertion+caseNothingMonad = helper "" [$hamlet|+$maybe *mnothing n+    nothing $n$+|]++caseNothingChain :: Assertion+caseNothingChain = helper "" [$hamlet|+$maybe getArg.*getArgM.getArg.*mnothing n+    nothing $n$+|]++caseJust :: Assertion+caseJust = helper "it's just" [$hamlet|+$maybe just n+    it's $n$+|]++caseJustMonad :: Assertion+caseJustMonad = helper "it's just" [$hamlet|+$maybe *mjust n+    it's $n$+|]++caseJustChain :: Assertion+caseJustChain = helper "it's just" [$hamlet|+$maybe getArg.*getArgM.getArg.*mjust n+    it's $n$+|]