packages feed

shakespeare-js 0.10.4 → 0.11.0

raw patch · 5 files changed

+197/−117 lines, 5 filesdep −processdep ~shakespearedep ~shakespeare-js

Dependencies removed: process

Dependency ranges changed: shakespeare, shakespeare-js

Files

Text/Coffee.hs view
@@ -3,66 +3,79 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-missing-fields #-}+-- | A Shakespearean module for CoffeeScript, introducing type-safe,+-- compile-time variable and url interpolation. It is exactly the same as+-- "Text.Julius", except that the template is first compiled to Javascript with+-- the system tool @coffee@.+--+-- To use this module, @coffee@ must be installed on your system.+--+-- @#{...}@ is the Shakespearean standard for variable interpolation, but+-- CoffeeScript already uses that sequence for string interpolation. Therefore,+-- Shakespearean interpolation is introduced with @%{...}@.+--+-- Further reading:+--+-- 1. Shakespearean templates: <http://www.yesodweb.com/book/templates>+--+-- 2. CoffeeScript: <http://coffeescript.org/> module Text.Coffee-    ( ToCoffee (..)-    , CoffeeUrl-    , Coffeescript-    , coffee+    ( -- * Functions+      -- ** Template-Reading Functions+      -- | These QuasiQuoter and Template Haskell methods return values of+      -- type @'JavascriptUrl' url@. See the Yesod book for details.+      coffee     , coffeeFile+    , coffeeFileReload     , coffeeFileDebug-    , renderCoffee++#ifdef TEST_EXPORT+    , coffeeSettings+#endif     ) where  import Language.Haskell.TH.Quote (QuasiQuoter (..)) import Language.Haskell.TH.Syntax-import Data.Text.Lazy.Builder (Builder, fromText, toLazyText, fromLazyText)-import qualified Data.Text as TS-import qualified Data.Text.Lazy as TL-import System.Process (readProcess)-import Data.Monoid import Text.Shakespeare--renderCoffee :: (url -> [(TS.Text, TS.Text)] -> TS.Text) -> CoffeeUrl url -> IO TL.Text-renderCoffee r s = do-  out <- readProcess "coffee" ["-epb", TL.unpack $ toLazyText $ unCoffee $ s r] []-  return $ TL.pack out-  where unCoffee (Coffeescript c) = c--newtype Coffeescript = Coffeescript { unCoffeescript :: Builder }-    deriving Monoid--type CoffeeUrl url = (url -> [(TS.Text, TS.Text)] -> TS.Text) -> Coffeescript---- the types that can be placed in a template-class ToCoffee c where-    toCoffee :: c -> Builder-instance ToCoffee [Char]  where toCoffee = fromLazyText . TL.pack-instance ToCoffee TS.Text where toCoffee = fromText-instance ToCoffee TL.Text where toCoffee = fromLazyText+import Text.Julius -settings :: Q ShakespeareSettings-settings = do-  toExp <- [|toCoffee|]-  wrapExp <- [|Coffeescript|]-  unWrapExp <- [|unCoffeescript|]-  return $ defaultShakespeareSettings { varChar = '%'-  , toBuilder = toExp-  , wrap = wrapExp-  , unwrap = unWrapExp+coffeeSettings :: Q ShakespeareSettings+coffeeSettings = do+  jsettings <- javascriptSettings+  return $ jsettings { varChar = '%'+  , preConversion = Just PreConvert {+      preConvert = ReadProcess "coffee" ["-epb"]+    , preEscapeBegin = "`"+    -- ^ backticks means the Coffeescript compiler will pass-through to javascript.+    , preEscapeEnd = "`"+    , preEscapeIgnore = "'\"`"+    -- ^ backticks are ignored inside a quote+    }   } +-- | Read inline, quasiquoted CoffeeScript. coffee :: QuasiQuoter coffee = QuasiQuoter { quoteExp = \s -> do-    rs <- settings+    rs <- coffeeSettings     quoteExp (shakespeare rs) s     } +-- | Read in a CoffeeScript template file. This function reads the file once, at+-- compile time. coffeeFile :: FilePath -> Q Exp coffeeFile fp = do-    rs <- settings+    rs <- coffeeSettings     shakespeareFile rs fp -coffeeFileDebug :: FilePath -> Q Exp-coffeeFileDebug fp = do-    rs <- settings+-- | Read in a CoffeeScript template file. This impure function uses+-- unsafePerformIO to re-read the file on every call, allowing for rapid+-- iteration.+coffeeFileReload :: FilePath -> Q Exp+coffeeFileReload fp = do+    rs <- coffeeSettings     shakespeareFileDebug rs fp++-- | Deprecated synonym for 'coffeeFileReload'+coffeeFileDebug :: FilePath -> Q Exp+coffeeFileDebug = coffeeFileReload+{-# DEPRECATED coffeeFileDebug "Please use coffeeFileReload instead." #-}
Text/Julius.hs view
@@ -3,14 +3,21 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-missing-fields #-}--- | This module is currently in an identity crisis. Originally called Julius, now being changed to just Javascript (shakespeare-javascript)+-- | A Shakespearean module for Javascript templates, introducing type-safe,+-- compile-time variable and url interpolation.--+-- To use this module, @coffee@ must be installed on your system.+--+-- You might consider trying 'Text.Coffee', which compiles down to Javascript.+--+-- Further reading: <http://www.yesodweb.com/book/templates>+--+-- This module is currently in an identity crisis. Originally called Julius, now being changed to just Javascript (shakespeare-javascript) module Text.Julius-    ( JavascriptUrl-    , Javascript (..)-    , ToJavascript (..)-    , renderJavascript-    , renderJavascriptUrl-    , js+    ( -- * Functions+      -- ** Template-Reading Functions+      -- | These QuasiQuoter and Template Haskell methods return values of+      -- type @'JavascriptUrl' url@. See the Yesod book for details.+      js     , julius     , juliusFile     , jsFile@@ -18,6 +25,20 @@     , jsFileDebug     , juliusFileReload     , jsFileReload++      -- * Datatypes+    , JavascriptUrl+    , Javascript (..)++      -- * Typeclass for interpolated variables+    , ToJavascript (..)++      -- ** Rendering Functions+    , renderJavascript+    , renderJavascriptUrl++      -- ** internal, used by 'Text.Coffee'+    , javascriptSettings     ) where  import Language.Haskell.TH.Quote (QuasiQuoter (..))@@ -31,21 +52,32 @@ renderJavascript :: Javascript -> TL.Text renderJavascript (Javascript b) = toLazyText b +-- | render with route interpolation. If using this module standalone, apart+-- from type-safe routes, a dummy renderer can be used:+-- +-- > renderJavascriptUrl (\_ _ -> undefined) javascriptUrl+--+-- When using Yesod, a renderer is generated for you, which can be accessed+-- within the GHandler monad: 'Yesod.Handler.getUrlRenderParams'. renderJavascriptUrl :: (url -> [(TS.Text, TS.Text)] -> TS.Text) -> JavascriptUrl url -> TL.Text renderJavascriptUrl r s = renderJavascript $ s r +-- | Newtype wrapper of 'Builder'. newtype Javascript = Javascript { unJavascript :: Builder }     deriving Monoid++-- | Return type of template-reading functions. type JavascriptUrl url = (url -> [(TS.Text, TS.Text)] -> TS.Text) -> Javascript +-- | A typeclass for types that can be interpolated in CoffeeScript templates. class ToJavascript a where     toJavascript :: a -> Builder instance ToJavascript [Char] where toJavascript = fromLazyText . TL.pack instance ToJavascript TS.Text where toJavascript = fromText instance ToJavascript TL.Text where toJavascript = fromLazyText -settings :: Q ShakespeareSettings-settings = do+javascriptSettings :: Q ShakespeareSettings+javascriptSettings = do   toJExp <- [|toJavascript|]   wrapExp <- [|Javascript|]   unWrapExp <- [|unJavascript|]@@ -56,7 +88,7 @@  js, julius :: QuasiQuoter js = QuasiQuoter { quoteExp = \s -> do-    rs <- settings+    rs <- javascriptSettings     quoteExp (shakespeare rs) s     } @@ -64,19 +96,21 @@  jsFile, juliusFile :: FilePath -> Q Exp jsFile fp = do-    rs <- settings+    rs <- javascriptSettings     shakespeareFile rs fp  juliusFile = jsFile  -jsFileDebug, juliusFileDebug :: FilePath -> Q Exp-jsFileDebug fp = do-    rs <- settings+jsFileReload, juliusFileReload :: FilePath -> Q Exp+jsFileReload fp = do+    rs <- javascriptSettings     shakespeareFileDebug rs fp -juliusFileDebug = jsFileDebug+juliusFileReload = jsFileReload -jsFileReload, juliusFileReload :: FilePath -> Q Exp-juliusFileReload = jsFileDebug-jsFileReload = jsFileDebug+jsFileDebug, juliusFileDebug :: FilePath -> Q Exp+juliusFileDebug = jsFileReload+{-# DEPRECATED juliusFileDebug "Please use juliusFileReload instead." #-}+jsFileDebug = jsFileReload+{-# DEPRECATED jsFileDebug "Please use jsFileReload instead." #-}
shakespeare-js.cabal view
@@ -1,5 +1,5 @@ name:            shakespeare-js-version:         0.10.4+version:         0.11.0 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>@@ -29,28 +29,48 @@  library     build-depends:   base             >= 4       && < 5-                   , shakespeare      >= 0.10    && < 0.11+                   , shakespeare      >= 0.10.3  && < 0.11                    , template-haskell                    , text             >= 0.7     && < 0.12-                   , process          >= 1.0     && < 1.2      exposed-modules:                      Text.Julius                      Text.Coffee     ghc-options:     -Wall+    if impl(ghc >= 7.4)+       cpp-options: -DGHC_7_4 +    if flag(test_coffee)+        cpp-options: -DTEST_COFFEE++    if flag(test_export)+        cpp-options: -DTEST_EXPORT++flag test_export+    default: False++flag test_coffee+    description: render tests through coffeescript render function+    -- cabal configure --enable-tests -ftest_coffee && cabal build && dist/build/test/test+    default: False+ test-suite test     hs-source-dirs: test     main-is: ../test.hs     type: exitcode-stdio-1.0      ghc-options:   -Wall-    build-depends: shakespeare-js   >= 0.10    && < 0.11-                 , shakespeare      >= 0.10    && < 0.11+    build-depends: shakespeare-js   >= 0.11    && < 0.12+                 , shakespeare      >= 0.10.3  && < 0.11                  , base             >= 4       && < 5                  , HUnit                  , hspec            >= 0.8     && < 0.10                  , text             >= 0.7     && < 0.12+                 , template-haskell++-- cabal bug+--    if flag(test_coffee)+--        cpp-options: -DTEST_COFFEE   source-repository head
test.hs view
@@ -1,5 +1,5 @@-import Test.Hspec+import Test.Hspec.Monadic import ShakespeareJsTest (specs)  main :: IO ()-main = hspecX $ descriptions [specs]+main = hspecX specs
test/ShakespeareJsTest.hs view
@@ -1,13 +1,18 @@ {-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE CPP #-}
 module ShakespeareJsTest (specs) where
 
 import Test.HUnit hiding (Test)
-import Test.Hspec
+import Test.Hspec.Monadic
 import Test.Hspec.HUnit ()
 
 import Prelude hiding (reverse)
+#ifdef TEST_COFFEE
+import Text.Coffee
+#endif
 import Text.Julius
+import Quoter (quote, quoteFile, quoteFileReload)
 import Data.List (intercalate)
 import qualified Data.Text.Lazy as T
 import qualified Data.List
@@ -15,78 +20,85 @@ import Data.Text (Text, pack, unpack)
 import Data.Monoid (mappend)
 
-specs :: [Spec]
-specs = describe "shakespeare-js"
-  [ it "julius" $ do
-    let var = "var"
+join :: [String] -> String
+#ifdef TEST_COFFEE
+join l = (intercalate ";\n" l)
+#else
+join = intercalate "\n"
+#endif
+
+specs :: Specs
+specs = describe "shakespeare-js" $ do
+  it "julius" $ do
+    let var = "x=2"
     let urlp = (Home, [(pack "p", pack "q")])
-    flip jelper [julius|שלום
-#{var}
-@{Home}
-@?{urlp}
-^{jmixin}
-|] $ intercalate "\r\n"
-        [ "שלום"
-        , var
-        , "url"
-        , "url?p=q"
-        , "var x;"
-        ] ++ "\r\n"
+    flip jelper [quote|['שלום', @{Home}, #{var}, '@?{urlp}', ^{jmixin} ]|]
+      $ intercalate " "
+        [ "['שלום',"
+        , "url, " ++ var ++ ","
+        , "'url?p=q',"
+        , "f(2) ]"
+        ]
 
 
-  , it "juliusFile" $ do
-    let var = "var"
+  it "juliusFile" $ do
+    let var = "x=2"
     let urlp = (Home, [(pack "p", pack "q")])
-    flip jelper $(juliusFile "test/juliuses/external1.julius") $ unlines
+    flip jelper $(quoteFile "test/juliuses/external1.julius") $ join
         [ "שלום"
         , var
         , "url"
         , "url?p=q"
-        , "var x;"
-        ]
+        , "f(2)"
+        ] ++ "\n"
 
 
-  , it "juliusFileDebug" $ do
-    let var = "var"
+  it "juliusFileReload" $ do
+    let var = "x=2"
     let urlp = (Home, [(pack "p", pack "q")])
-    flip jelper $(juliusFileDebug "test/juliuses/external1.julius") $ unlines
+    flip jelper $(quoteFileReload "test/juliuses/external1.julius") $ join
         [ "שלום"
         , var
         , "url"
         , "url?p=q"
-        , "var x;"
-        ]
+        , "f(2)"
+        ] ++ "\n"
 
 {- TODO
-  , it "juliusFileDebugChange" $ do
-      let var = "somevar"
-          test result = jelper result $(juliusFileDebug "test/juliuses/external2.julius")
-      writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
-      test "var somevar = 1;"
-      writeFile "test/juliuses/external2.julius" "var #{var} = 2;"
-      test "var somevar = 2;"
-      writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
-      -}
+  it "juliusFileDebugChange" $ do
+    let var = "somevar"
+        test result = jelper result $(juliusFileDebug "test/juliuses/external2.julius")
+    writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
+    test "var somevar = 1;"
+    writeFile "test/juliuses/external2.julius" "var #{var} = 2;"
+    test "var somevar = 2;"
+    writeFile "test/juliuses/external2.julius" "var #{var} = 1;"
+    -}
 
 
-  , it "julius module names" $
+  it "julius module names" $
     let foo = "foo"
         double = 3.14 :: Double
-        int = -5 :: Int in
-      jelper "oof oof 3.14 -5"
-        [julius|#{Data.List.reverse foo} #{L.reverse foo} #{show double} #{show int}|]
+        int = -5 :: Int
+    in jelper "[oof, oof, 3.14, -5]"
+#ifdef TEST_COFFEE
+         [quote|[%{Data.List.reverse foo}, %{L.reverse foo}, %{show double}, %{show int}]|]
+#else
+         [quote|[#{Data.List.reverse foo}, #{L.reverse foo}, #{show double}, #{show int}]|]
+#endif
 
 
-  , it "single dollar at and caret" $ do
-    jelper "$@^" [julius|$@^|]
-    jelper "#{@{^{" [julius|#\{@\{^\{|]
-
+-- not valid coffeescript
+#ifndef TEST_COFFEE
+  it "single dollar at and caret" $ do
+    jelper "$@^" [quote|$@^|]
+    jelper "#{@{^{" [quote|#\{@\{^\{|]
+#endif
 
-  , it "dollar operator" $ do
+  it "dollar operator" $ do
     let val = (1 :: Int, (2 :: Int, 3 :: Int))
-    jelper "2" [julius|#{ show $ fst $ snd val }|]
-    jelper "2" [julius|#{ show $ fst $ snd $ val}|]
-  ]
+    jelper "2" [quote|#{ show $ fst $ snd val }|]
+    jelper "2" [quote|#{ show $ fst $ snd $ val}|]
 
 
 
@@ -131,10 +143,11 @@ 
 
 jmixin :: JavascriptUrl u
-jmixin = [julius|var x;|]
+jmixin = [quote|f(2)|]
 
 jelper :: String -> JavascriptUrl Url -> Assertion
-jelper res h = T.pack res @=? renderJavascriptUrl render h
+jelper res h = do
+  T.pack res @=? renderJavascriptUrl render h
 
 instance Show Url where
     show _ = "FIXME remove this instance show Url"