[more edits to jmacro section Jeremy Shaw **20110519175532 Ignore-this: 44402adbcef08b24618b34e124af651a ] hunk ./JMacro.markdown.lhs 31 -The happstack-jmacro library makes it easy to use JMacro with Happstack and HSP. +The happstack-jmacro library makes it easy to use JMacro with Happstack and HSP. hunk ./JMacro.markdown.lhs 43 - TypeSynonymInstances, QuasiQuotes #-} +> TypeSynonymInstances, QuasiQuotes #-} hunk ./JMacro.markdown.lhs 60 -> import Control.Monad (msum) +> import Control.Monad (msum) hunk ./JMacro.markdown.lhs 63 -> import qualified Data.Map as Map -> import Data.Maybe (fromMaybe) -> import Data.Unique -> import Happstack.Server +> import qualified Data.Map as Map +> import Data.Maybe (fromMaybe) +> import Happstack.Server (Response, ServerPartT, dir, mapServerPartT, look, nullConf, +> ok, simpleHTTP, toResponse) hunk ./JMacro.markdown.lhs 69 -> import HSP -> import HSP.ServerPartT () -- ^ instance 'XMLGenerator ServerPartT' +> import HSP (Attr(..), EmbedAsAttr(..), EmbedAsChild(..), genElement +> , genEElement) +> import HSP.ServerPartT () -- ^ instance 'XMLGenerator ServerPartT' hunk ./JMacro.markdown.lhs 73 -> import Language.Javascript.JMacro -> import System.Random +> import Language.Javascript.JMacro (ToJExpr(..), Ident(..), JStat(..), JExpr(..), JVal(..), jmacro, jsv, jLam, jVarTy) +> import System.Random (Random(..)) hunk ./JMacro.markdown.lhs 128 +The syntax `[$jmacro| ... |]` is the magic incantation for running the +`jmacro` quasiquoter. In GHC 7.x, the $ is no longer required, so in +theory you could write, `[jmacro| ... |]`. However, HSX has not been updated to support the $ free syntax. So, for now you will need to stick with the $ syntax, despite the compiler warnings saying, Warning: Deprecated syntax: quasiquotes no longer need a dollar sign: $jmacro. + hunk ./JMacro.markdown.lhs 144 -So far, using jmacro with HSP looks almost exactly like using HSP with -out jmacro. That's actually pretty exciting. It mean that the mental -tax for using jmacro over straight javascript is very low. +So far, using HSP with jmacro looks almost exactly like using HSP with +plain-old javascript. That's actually pretty exciting. It means that +the mental tax for using jmacro over straight javascript is very low. hunk ./JMacro.markdown.lhs 169 -Click me! text. It uses a global variable to keep track of the -number of clicks. Normally that would spell trouble. If we tried to -use that code twice on the same page, the instances would overwrite -each other. +Click me! text. It uses a global variable to keep track of +the number of clicks. Normally that would spell trouble. If we tried +to use that code twice on the same page, both copies would end up +writing to the same global variable `clickCnt`. hunk ./JMacro.markdown.lhs 189 + hunk ./JMacro.markdown.lhs 207 -Now all the copies of clickMe2 will share the same counter: +The use of ! when declaring a variable disables hygienic naming. Now all the copies of clickMe2 will share the same counter: hunk ./JMacro.markdown.lhs 236 -Often times we want to call some javascript code that contains some Haskell values spliced in. This can be done using `( )`. +We can also splice Haskell values into the javascript code by using `( )`. In the following example, the `onclick` action for the <button> calls `revealFortune()`. The argument to revealForture is the `String` returned by evaluating the Haskell expression `fortunes !! n`. hunk ./JMacro.markdown.lhs 268 -JMacro can embed 'primitives' such as `Int`, `Bool`, `Char`, `String`, etc, by default. But we can also embed other types by creating a `ToJExpr` instance for them. For example, let's say we create some types for reporting the weather: +JMacro can embed common types such as `Int`, `Bool`, `Char`, `String`, etc, by default. But we can also embed other types by creating a `ToJExpr` instance for them. For example, let's say we create some types for reporting the weather: hunk ./JMacro.markdown.lhs 313 -For `Fahrenheit`, we were actually able to derive the `ToJExpr` instance automatically (aka, `deriving (ToJExpr)`). +For `Fahrenheit`, we were actually able to derive the `ToJExpr` instance automatically (aka, `deriving (ToJExpr)`), because it a `newtype` wrapper around `Double` which already has a `ToExpr` instance. hunk ./JMacro.markdown.lhs 315 -For `Skies`, we can just convert the values into javascript strings: +For `Skies`, we can just convert the constructors into javascript strings: hunk ./JMacro.markdown.lhs 325 -For the `Weather` type, we create a javascript object/hash/associative array: +For the `Weather` type, we create a javascript object/hash/associative array/record/whatever you want to call it: hunk ./JMacro.markdown.lhs 364 -So far we have use jmacro to generate javascript that is embedded in HTML. We can also use it to create standalone javascript files. +So far we have use jmacro to generate javascript that is embedded in HTML. We can also use it to create standalone javascript. hunk ./JMacro.markdown.lhs 379 -Then we have a part with two sub-parts: +(Note that we use the bang synaxt when declaring `greet` so that it will not be renamed.) Then we have a server part with two sub-parts: hunk ./JMacro.markdown.lhs 386 -If external/script.js is requested, then we check for a query string parameter 'greeting' and generate the script. `toResponse` will automatically convert the script to a `Response` and serve it with the content-type, text/javascript; charset=UTF-8: +If external/script.js is requested, then we check for a query string parameter `greeting` and generate the script. `toResponse` will automatically convert the script to a `Response` and serve it with the content-type, text/javascript; charset=UTF-8: hunk ./JMacro.markdown.lhs 394 -Next we have an html page that includes the external script, and calls jmacro; +Next we have an html page that includes the external script, and calls the `greet` function: hunk ./JMacro.markdown.lhs 406 -And little page that links to all the demos: + +Here is a little page that links to all the jmacro demos: + hunk ./JMacro.markdown.lhs 441 +