{- | this module provides a QuasiQuoter that supports the HSX syntax. -- Module : Language.Haskell.HSX.Tranform -- Copyright : (c) Niklas Broberg 2004-2012 -- License : BSD-style (see the file LICENSE.txt) -- -- Maintainer : Niklas Broberg, niklas.broberg@gmail.com -- Stability : experimental -- Portability : portable -- You will need to enable the QuasiQuotes extension for it to work, which you can do by adding this to the top of your file: {-\# LANGUAGE QuasiQuotes \#-} Here is a simple example that generates an HTML fragment: > import Data.Char (toUpper) > import HSX.QQ (hsx) > import HSX.XMLGenerator > > html :: (XMLGenerator m) => XMLGenT m (XMLType m) > html = [hsx|

<% map toUpper "hello, world!" %>

|] The syntax used by the hsx QuasiQuoter is the same as what is used by @trhsx@. It is mostly normal XML syntax which a few key differences: 1. strings inside tags and attributes are automatically escaped -- you do not need to do <, etc. 2. The <% %> syntax is used to embed the result of evaluating a Haskell expression into the XML Values are embedde using the 'EmbedAsChild' and 'EmbedAsAttr' classes. Additional instances can be added to support application specific types. -} module Language.Haskell.HSX.QQ ( hsx ) where import qualified Language.Haskell.Exts.Syntax as Hs import Language.Haskell.Exts hiding (Exp, parse, parseExp) import Language.Haskell.HSX.Transform (transformExp) import Language.Haskell.Meta.Parse hiding (parseHsExp, parseExp) import Language.Haskell.Meta.Syntax.Translate (toExp) import Language.Haskell.TH (Exp, ExpQ) import Language.Haskell.TH.Quote (QuasiQuoter(..)) -- | QuasiQuoter which can be used to parse HSX syntax hsx :: QuasiQuoter hsx = QuasiQuoter { quoteExp = parseHsxExp , quotePat = error "the hsx QuasiQuoter can only be used on expressions." , quoteType = error "the hsx QuasiQuoter can only be used on expressions." , quoteDec = error "the hsx QuasiQuoter can only be used on expressions." } parseHsxExp :: String -> ExpQ parseHsxExp = either (error . show) (return . toExp . transformExp) . parseHsExp parseExp :: String -> Either String Exp parseExp = either Left (Right . toExp . transformExp) . parseHsExp parseHsExp :: String -> Either String Hs.Exp parseHsExp = either Left (Right . transformExp) . parseResultToEither . parseExpWithMode parseMode parseMode :: ParseMode parseMode = ParseMode "" Haskell2010 allExtensions False True (Just baseFixities) allExtensions :: [Extension] allExtensions = map EnableExtension [RecursiveDo,ParallelListComp,MultiParamTypeClasses,FunctionalDependencies,RankNTypes,ExistentialQuantification, ScopedTypeVariables,ImplicitParams,FlexibleContexts,FlexibleInstances,EmptyDataDecls,KindSignatures, BangPatterns,TemplateHaskell,ForeignFunctionInterface,Arrows,Generics,NamedFieldPuns,PatternGuards, MagicHash,TypeFamilies,StandaloneDeriving,TypeOperators,RecordWildCards,GADTs,UnboxedTuples, PackageImports,QuasiQuotes,TransformListComp,ViewPatterns,XmlSyntax,RegularPatterns]