packages feed

hamlet 0.5.0.2 → 0.5.1

raw patch · 6 files changed

+115/−70 lines, 6 filesdep ~template-haskellPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: template-haskell

API changes (from Hackage documentation)

+ Text.Hamlet: class (Monad (HamletMonad a)) => HamletValue a where { data family HamletMonad a :: * -> *; type family HamletUrl a; }
+ Text.Hamlet: fromHamletValue :: (HamletValue a) => a -> HamletMonad a ()
+ Text.Hamlet: htmlToHamletMonad :: (HamletValue a) => Html -> HamletMonad a ()
+ Text.Hamlet: toHamletValue :: (HamletValue a) => HamletMonad a () -> a
+ Text.Hamlet: urlToHamletMonad :: (HamletValue a) => HamletUrl a -> [(String, String)] -> HamletMonad a ()

Files

Text/Cassius.hs view
@@ -268,9 +268,8 @@  cassiusMixin :: QuasiQuoter cassiusMixin =-    QuasiQuoter e p+    QuasiQuoter { quoteExp = e }   where-    p = error "cassiusMixin quasi-quoter for patterns does not exist"     e s = do         let a = either (error . show) id               $ parse parseLines s s@@ -288,10 +287,7 @@ newtype CassiusMixin url = CassiusMixin { unCassiusMixin :: Cassius url }  cassius :: QuasiQuoter-cassius =-    QuasiQuoter cassiusFromString p-  where-    p = error "cassius quasi-quoter for patterns does not exist"+cassius = QuasiQuoter { quoteExp = cassiusFromString }  cassiusFromString :: String -> Q Exp cassiusFromString s = do
Text/Hamlet.hs view
@@ -21,6 +21,7 @@     , Hamlet       -- * Typeclass     , ToHtml (..)+    , HamletValue (..)       -- * Construction/rendering     , renderHamlet     , renderHtml
Text/Hamlet/Quasi.hs view
@@ -1,7 +1,10 @@ {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE EmptyDataDecls #-} module Text.Hamlet.Quasi     ( hamlet     , xhamlet@@ -14,6 +17,7 @@     , xhamletFile     , hamletFileWithSettings     , ToHtml (..)+    , HamletValue (..)     , varName     , Html (..)     , Hamlet@@ -44,47 +48,45 @@  type Scope = [(Ident, Exp)] -docsToExp :: Exp -> Scope -> [Doc] -> Q Exp-docsToExp render scope docs = do-    exps <- mapM (docToExp render scope) docs-    me <- [|mempty|]-    ma <- [|mappend|]-    let ma' x y = InfixE (Just x) ma $ Just y-    return $-        case exps of-            [] -> me-            [x] -> x-            _ -> foldr1 ma' exps+docsToExp :: Scope -> [Doc] -> Q Exp+docsToExp scope docs = do+    exps <- mapM (docToExp scope) docs+    let stmts = map (BindS $ TupP []) exps+    rnull <- [|return ()|]+    return $ case exps of+        [] -> rnull+        [x] -> x+        _ -> DoE $ stmts ++ [NoBindS rnull] -docToExp :: Exp -> Scope -> Doc -> Q Exp-docToExp render scope (DocForall list ident@(Ident name) inside) = do+docToExp :: Scope -> Doc -> Q Exp+docToExp scope (DocForall list ident@(Ident name) inside) = do     let list' = deref scope list     name' <- newName name     let scope' = (ident, VarE name') : scope-    mh <- [|\a -> mconcat . map a|]-    inside' <- docsToExp render scope' inside+    mh <- [|mapM_|]+    inside' <- docsToExp scope' inside     let lam = LamE [VarP name'] inside'     return $ mh `AppE` lam `AppE` list'-docToExp render scope (DocMaybe val ident@(Ident name) inside mno) = do+docToExp scope (DocMaybe val ident@(Ident name) inside mno) = do     let val' = deref scope val     name' <- newName name     let scope' = (ident, VarE name') : scope-    inside' <- docsToExp render scope' inside+    inside' <- docsToExp scope' inside     let inside'' = LamE [VarP name'] inside'     ninside' <- case mno of                     Nothing -> [|Nothing|]                     Just no -> do-                        no' <- docsToExp render scope no+                        no' <- docsToExp scope no                         j <- [|Just|]                         return $ j `AppE` no'     mh <- [|maybeH|]     return $ mh `AppE` val' `AppE` inside'' `AppE` ninside'-docToExp render scope (DocCond conds final) = do+docToExp scope (DocCond conds final) = do     conds' <- mapM go conds     final' <- case final of                 Nothing -> [|Nothing|]                 Just f -> do-                    f' <- docsToExp render scope f+                    f' <- docsToExp scope f                     j <- [|Just|]                     return $ j `AppE` f'     ch <- [|condH|]@@ -93,35 +95,38 @@     go :: (Deref, [Doc]) -> Q Exp     go (d, docs) = do         let d' = deref scope d-        docs' <- docsToExp render scope docs+        docs' <- docsToExp scope docs         return $ TupE [d', docs']-docToExp render v (DocContent c) = contentToExp render v c+docToExp v (DocContent c) = contentToExp v c -contentToExp :: Exp -> Scope -> Content -> Q Exp-contentToExp _ _ (ContentRaw s) = do-    os <- [|Html . fromByteString . S8.pack|]+contentToExp :: Scope -> Content -> Q Exp+contentToExp _ (ContentRaw s) = do+    os <- [|htmlToHamletMonad . Html . fromByteString . S8.pack|]     let s' = LitE $ StringL $ S8.unpack $ BSU.fromString s     return $ os `AppE` s'-contentToExp _ scope (ContentVar d) = do-    str <- [|toHtml|]+contentToExp scope (ContentVar d) = do+    str <- [|htmlToHamletMonad . toHtml|]     return $ str `AppE` deref scope d-contentToExp render scope (ContentUrl hasParams d) = do+contentToExp scope (ContentUrl hasParams d) = do     ou <- if hasParams-            then [|\r (u, p) -> Html $ fromHtmlEscapedString $ r u p|]-            else [|\r u -> Html $ fromHtmlEscapedString $ r u []|]+            then [|\(u, p) -> urlToHamletMonad u p|]+            else [|\u -> urlToHamletMonad u []|]     let d' = deref scope d-    return $ ou `AppE` render `AppE` d'-contentToExp render scope (ContentEmbed d) = do+    return $ ou `AppE` d'+contentToExp scope (ContentEmbed d) = do     let d' = deref scope d-    return (d' `AppE` render)+    fhv <- [|fromHamletValue|]+    return $ fhv `AppE` d'  -- | Calls 'hamletWithSettings'' with 'defaultHamletSettings'. hamlet' :: QuasiQuoter hamlet' = hamletWithSettings' defaultHamletSettings+{-# DEPRECATED hamlet' "Use hamlet directly now" #-}  -- | Calls 'hamletWithSettings'' using XHTML 1.0 Strict settings. xhamlet' :: QuasiQuoter xhamlet' = hamletWithSettings' xhtmlHamletSettings+{-# DEPRECATED xhamlet' "Use xhamlet directly now" #-}  -- | Calls 'hamletWithSettings' with 'defaultHamletSettings'. hamlet :: QuasiQuoter@@ -142,28 +147,30 @@ -- Please see accompanying documentation for a description of Hamlet syntax. hamletWithSettings :: HamletSettings -> QuasiQuoter hamletWithSettings set =-    QuasiQuoter (hamletFromString set)-      $ error "Cannot quasi-quote Hamlet to patterns"+    QuasiQuoter+        { quoteExp = hamletFromString set+        }  -- | A quasi-quoter that converts Hamlet syntax into a 'Html' (). -- -- Please see accompanying documentation for a description of Hamlet syntax. hamletWithSettings' :: HamletSettings -> QuasiQuoter hamletWithSettings' set =-    QuasiQuoter (\s -> do-        x <- hamletFromString set s-        id' <- [|id|]-        return $ x `AppE` id')-    $ error "Cannot quasi-quote Hamlet to patterns"+    QuasiQuoter+        { quoteExp = \s -> do+            x <- hamletFromString set s+            id' <- [|(\y _ -> y) :: String -> [(String, String)] -> String|]+            return $ x `AppE` id'+        }  hamletFromString :: HamletSettings -> String -> Q Exp hamletFromString set s = do-  case parseDoc set s of-    Error s' -> error s'-    Ok d -> do-        render <- newName "_render"-        func <- docsToExp (VarE render) [] d-        return $ LamE [VarP render] func+    case parseDoc set s of+        Error s' -> error s'+        Ok d -> do+            thv <- [|toHamletValue|]+            exp' <- docsToExp [] d+            return $ thv `AppE` exp'  hamletFileWithSettings :: HamletSettings -> FilePath -> Q Exp hamletFileWithSettings set fp = do@@ -203,16 +210,16 @@ -- a true exists, then the corresponding right action is performed. Only the -- first is performed. In there are no true values, then the second argument is -- performed, if supplied.-condH :: [(Bool, Html)] -> Maybe Html -> Html-condH [] Nothing = mempty+condH :: Monad m => [(Bool, m ())] -> Maybe (m ()) -> m ()+condH [] Nothing = return () condH [] (Just x) = x condH ((True, y):_) _ = y condH ((False, _):rest) z = condH rest z  -- | Runs the second argument with the value in the first, if available. -- Otherwise, runs the third argument, if available.-maybeH :: Maybe v -> (v -> Html) -> Maybe Html -> Html-maybeH Nothing _ Nothing = mempty+maybeH :: Monad m => Maybe v -> (v -> m ()) -> Maybe (m ()) -> m ()+maybeH Nothing _ Nothing = return () maybeH Nothing _ (Just x) = x maybeH (Just v) f _ = f v @@ -225,3 +232,41 @@  -- | An function generating an 'Html' given a URL-rendering function. type Hamlet url = (url -> [(String, String)] -> String) -> Html++class Monad (HamletMonad a) => HamletValue a where+    data HamletMonad a :: * -> *+    type HamletUrl a+    toHamletValue :: HamletMonad a () -> a+    htmlToHamletMonad :: Html -> HamletMonad a ()+    urlToHamletMonad :: HamletUrl a -> [(String, String)] -> HamletMonad a ()+    fromHamletValue :: a -> HamletMonad a ()++type Render url = url -> [(String, String)] -> String+instance HamletValue (Hamlet url) where+    newtype HamletMonad (Hamlet url) a =+        HMonad { runHMonad :: Render url -> (Html, a) }+    type HamletUrl (Hamlet url) = url+    toHamletValue = fmap fst . runHMonad+    htmlToHamletMonad x = HMonad $ const (x, ())+    urlToHamletMonad url pairs = HMonad $ \r ->+        (Html $ fromHtmlEscapedString $ r url pairs, ())+    fromHamletValue f = HMonad $ \r -> (f r, ())+instance Monad (HamletMonad (Hamlet url)) where+    return x = HMonad $ const (mempty, x)+    (HMonad f) >>= g = HMonad $ \render ->+        let (html1, x) = f render+            (html2, y) = runHMonad (g x) render+         in (html1 `mappend` html2, y)+data NoConstructor+instance HamletValue Html where+    newtype HamletMonad Html a = HtmlMonad { runHtmlMonad :: (Html, a) }+    type HamletUrl Html = NoConstructor+    toHamletValue = fst . runHtmlMonad+    htmlToHamletMonad x = HtmlMonad (x, ())+    urlToHamletMonad = error "urlToHamletMonad on NoConstructor"+    fromHamletValue h = HtmlMonad (h, ())+instance Monad (HamletMonad Html) where+    return x = HtmlMonad (mempty, x)+    HtmlMonad (html1, x) >>= g = HtmlMonad $+        let HtmlMonad (html2, y) = g x+         in (html1 `mappend` html2, y)
Text/Julius.hs view
@@ -118,10 +118,7 @@     return $ LamE [VarP r] d  julius :: QuasiQuoter-julius =-    QuasiQuoter juliusFromString p-  where-    p = error "julius quasi-quoter for patterns does not exist"+julius = QuasiQuoter { quoteExp = juliusFromString }  juliusFromString :: String -> Q Exp juliusFromString s = do
hamlet.cabal view
@@ -1,5 +1,5 @@ name:            hamlet-version:         0.5.0.2+version:         0.5.1 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>@@ -32,21 +32,21 @@ stability:       unstable cabal-version:   >= 1.6 build-type:      Simple-homepage:        http://docs.yesodweb.com/hamlet/+homepage:        http://docs.yesodweb.com/  flag buildtests   description: Build the executable to run unit tests   default: False  library-    build-depends:   base >= 4 && < 5,-                     bytestring >= 0.9 && < 0.10,-                     utf8-string >= 0.3.4 && < 0.4,-                     template-haskell,-                     blaze-builder >= 0.1 && < 0.2,-                     neither >= 0.0.1 && < 0.1,-                     parsec >= 2 && < 4,-                     failure >= 0.1.0 && < 0.2+    build-depends:   base             >= 4       && < 5+                   , bytestring       >= 0.9     && < 0.10+                   , utf8-string      >= 0.3.4   && < 0.4+                   , template-haskell+                   , blaze-builder    >= 0.1     && < 0.2+                   , neither          >= 0.0.1   && < 0.1+                   , parsec           >= 2       && < 4+                   , failure          >= 0.1.0   && < 0.2     exposed-modules: Text.Hamlet                      Text.Hamlet.RT                      Text.Cassius
runtests.hs view
@@ -459,6 +459,12 @@     helper "<br>" $ const $ [$hamlet'|%br|]
     helper "<br/>" $ const $ [$xhamlet'|%br|]
 
+    -- new with generalized stuff
+    helper' "foo" [$hamlet|foo|]
+    helper' "foo" [$xhamlet|foo|]
+    helper "<br>" $ const $ [$hamlet|%br|]
+    helper "<br/>" $ const $ [$xhamlet|%br|]
+
 caseHamletDebug :: Assertion
 caseHamletDebug = do
     helper "<p>foo</p>\n<p>bar</p>\n" [$hamletDebug|