heterocephalus 1.0.1.2 → 1.0.2.0
raw patch · 3 files changed
+216/−3 lines, 3 filesdep +dlistPVP ok
version bump matches the API change (PVP)
Dependencies added: dlist
API changes (from Hackage documentation)
+ Text.Heterocephalus: compileFileWith :: ScopeM () -> HeterocephalusSetting -> FilePath -> Q Exp
+ Text.Heterocephalus: compileHtmlFileWith :: FilePath -> ScopeM () -> Q Exp
+ Text.Heterocephalus: compileTextFileWith :: FilePath -> ScopeM () -> Q Exp
+ Text.Heterocephalus: compileWith :: ScopeM () -> HeterocephalusSetting -> QuasiQuoter
+ Text.Heterocephalus: data ScopeM a
+ Text.Heterocephalus: instance GHC.Base.Applicative Text.Heterocephalus.ScopeM
+ Text.Heterocephalus: instance GHC.Base.Functor Text.Heterocephalus.ScopeM
+ Text.Heterocephalus: instance GHC.Base.Monad Text.Heterocephalus.ScopeM
+ Text.Heterocephalus: overwrite :: Ident -> Q Exp -> ScopeM ()
+ Text.Heterocephalus: setDefault :: Ident -> Q Exp -> ScopeM ()
Files
- CHANGELOG.md +11/−0
- heterocephalus.cabal +3/−1
- src/Text/Heterocephalus.hs +202/−2
+ CHANGELOG.md view
@@ -0,0 +1,11 @@+Change Log+==========++Version 1.0.2.0 (2016-12-13)+----------------------------++#### New features++* Add `compileTextFileWith` and `compileHtmlFileWith` to inject extra variables+* Add `ScopeM` type for specifying extra template variables+* Add `setDefault` and `overwrite` for constructing `ScopeM`
heterocephalus.cabal view
@@ -1,5 +1,5 @@ name: heterocephalus-version: 1.0.1.2+version: 1.0.2.0 synopsis: A type-safe template engine for working with popular front end development tools description: Recent front end development tools and languages are growing fast and have@@ -23,6 +23,7 @@ build-type: Simple extra-source-files: templates/*.txt README.md+ CHANGELOG.md cabal-version: >=1.10 library@@ -34,6 +35,7 @@ , blaze-html >= 0.8 && < 0.9 , blaze-markup >= 0.7 && < 0.8 , containers >= 0.5 && < 0.6+ , dlist >= 0.7.1.1 , parsec >= 3.1 && < 3.2 , shakespeare >= 2.0 && < 2.1 , template-haskell >= 2.7 && < 3
src/Text/Heterocephalus.hs view
@@ -19,20 +19,29 @@ ( -- * Core functions compileTextFile+ , compileTextFileWith , compileTextFileWithDefault , compileHtmlFile+ , compileHtmlFileWith , compileHtmlFileWithDefault -- * QuasiQuoters , compileText , compileHtml + -- * ScopeM+ , ScopeM+ , setDefault+ , overwrite+ -- * low-level , HeterocephalusSetting(escapeExp) , DefaultScope , compile+ , compileWith , compileWithDefault , compileFile+ , compileFileWith , compileFileWithDefault , compileFromString , compileFromStringWithDefault@@ -40,16 +49,19 @@ #if MIN_VERSION_base(4,9,0) #else-import Control.Applicative ((<$>))+import Control.Applicative ((<$>), (<*>), Applicative(..))+import Data.Monoid (mempty) #endif import Control.Monad (forM) import Data.Char (isDigit)+import Data.DList (DList)+import qualified Data.DList as DList import qualified Data.Foldable as F import Data.List (intercalate) import Data.String (IsString(..)) import Data.Text (Text, pack) import qualified Data.Text.Lazy as TL-import Language.Haskell.TH.Lib (varE)+import Language.Haskell.TH.Lib (ExpQ, varE) import Language.Haskell.TH.Quote #if MIN_VERSION_template_haskell(2,9,0) import Language.Haskell.TH.Syntax hiding (Module)@@ -82,6 +94,52 @@ compileTextFile :: FilePath -> Q Exp compileTextFile = compileFile textSetting +{-| Same as 'compileText' but allows the user to specify extra values for template parameters.+ Values declared by 'overwrite' overwrites same name variables.+ Values declared by 'setDefault' are overwritten by same name variables.++ >>> :set -XOverloadedStrings+ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileTextFileWith "templates/sample.txt" $ do+ >>> setDefault "as" [| ["foo", "bar"] |]+ >>> )+ >>> )+ >>> :}+ sample+ key: <a>,+ key: b,++ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileTextFileWith "templates/sample.txt" $ do+ >>> overwrite "as" [| ["foo", "bar"] |]+ >>> )+ >>> )+ >>> :}+ sample+ key: foo,+ key: bar,++ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileTextFileWith "templates/sample.txt" $ do+ >>> overwrite "as" [| ["bazbaz", "barbar"] |]+ >>> setDefault "as" [| ["foo", "bar"] |]+ >>> overwrite "as" [| ["baz", "foobar"] |]+ >>> )+ >>> )+ >>> :}+ sample+ key: baz,+ key: foobar,+ -}+compileTextFileWith :: FilePath -> ScopeM () -> Q Exp+compileTextFileWith fp scopeM = compileFileWith scopeM textSetting fp+ {-| Same as 'compileText' but allows the user to specify default values for template parameters. >>> :set -XOverloadedStrings@@ -121,6 +179,52 @@ compileHtmlFile :: FilePath -> Q Exp compileHtmlFile fp = compileHtmlFileWithDefault fp [] +{-| Same as 'compileHtmlFile' but allows the user to specify extra values for template parameters.+ Values declared by 'overwrite' overwrites same name variables.+ Values declared by 'setDefault' are overwritten by same name variables.++ >>> :set -XOverloadedStrings+ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileHtmlFileWith "templates/sample.txt" $ do+ >>> setDefault "as" [| ["foo", "bar"] |]+ >>> )+ >>> )+ >>> :}+ sample+ key: <a>,+ key: b,++ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileHtmlFileWith "templates/sample.txt" $ do+ >>> overwrite "as" [| ["foo", "bar"] |]+ >>> )+ >>> )+ >>> :}+ sample+ key: foo,+ key: bar,++ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileHtmlFileWith "templates/sample.txt" $ do+ >>> overwrite "as" [| ["bazbaz", "barbar"] |]+ >>> setDefault "as" [| ["foo", "bar"] |]+ >>> overwrite "as" [| ["baz", "foobar"] |]+ >>> )+ >>> )+ >>> :}+ sample+ key: baz,+ key: foobar,+ -}+compileHtmlFileWith :: FilePath -> ScopeM () -> Q Exp+compileHtmlFileWith fp scopeM = compileFileWith scopeM htmlSetting fp+ {-| Same as 'compileHtmlFile' but allows the user to specify default values for template parameters. >>> :set -XOverloadedStrings@@ -175,6 +279,19 @@ compile :: HeterocephalusSetting -> QuasiQuoter compile = compileWithDefault [] +{-| QuasiQuoter.+ -}+compileWith :: ScopeM () -> HeterocephalusSetting -> QuasiQuoter+compileWith scopeM set =+ QuasiQuoter+ { quoteExp = compileFromStringWith scopeM set+ , quotePat = error "not used"+ , quoteType = error "not used"+ , quoteDec = error "not used"+ }++{-| QuasiQuoter.+ -} compileWithDefault :: DefaultScope -> HeterocephalusSetting -> QuasiQuoter compileWithDefault scope set = QuasiQuoter@@ -191,6 +308,14 @@ {-| Same as 'compileFile' but we can specify default scope. -}+compileFileWith :: ScopeM () -> HeterocephalusSetting -> FilePath -> Q Exp+compileFileWith scopeM set fp = do+ qAddDependentFile fp+ contents <- fmap TL.unpack $ qRunIO $ readUtf8File fp+ compileFromStringWith scopeM set contents++{-| Same as 'compileFile' but we can specify default scope.+-} compileFileWithDefault :: DefaultScope -> HeterocephalusSetting -> FilePath -> Q Exp compileFileWithDefault scope' set fp = do qAddDependentFile fp@@ -200,6 +325,18 @@ compileFromString :: HeterocephalusSetting -> String -> Q Exp compileFromString = compileFromStringWithDefault [] +compileFromStringWith :: ScopeM () -> HeterocephalusSetting -> String -> Q Exp+compileFromStringWith scopeM set s = do+ defScope' <-+ forM defScope $ \(ident, qexp) -> (ident, ) <$> overwriteScope ident qexp+ owScope' <-+ forM owScope $ \(ident, qexp) -> (ident, ) <$> qexp+ docsToExp set (owScope' ++ defScope') $ docFromString s+ where+ (defDList, owDList) = runScopeM scopeM+ defScope = DList.toList defDList+ owScope = DList.toList owDList+ compileFromStringWithDefault :: DefaultScope -> HeterocephalusSetting -> String -> Q Exp compileFromStringWithDefault scope' set s = do scope <-@@ -238,6 +375,69 @@ } type DefaultScope = [(Ident, Q Exp)]++type DefaultDList = DList (Ident, Q Exp)+type OverwriteDList = DList (Ident, Q Exp)++{- | A type to handle extra scopes.+ - This is opaque type, so use 'setDefault' and 'overwrite'+ - to construct new 'ScopeM'.+ -}+data ScopeM a+ = SetDefault Ident ExpQ (ScopeM a)+ | Overwrite Ident ExpQ (ScopeM a)+ | PureScopeM a++{- | Get default values and values to overwrite from 'ScopeM'.+ -}+runScopeM :: ScopeM a -> (DefaultDList, OverwriteDList)+runScopeM (SetDefault ident qexp next) =+ let (defaults, overwrites) = runScopeM next+ in (DList.snoc defaults (ident, qexp), overwrites)+runScopeM (Overwrite ident qexp next) =+ let (defaults, overwrites) = runScopeM next+ in (defaults, DList.snoc overwrites (ident, qexp))+runScopeM (PureScopeM _) =+ (mempty, mempty)++instance Functor ScopeM where+ fmap f (SetDefault ident qexp next) =+ SetDefault ident qexp $ fmap f next+ fmap f (Overwrite ident qexp next) =+ Overwrite ident qexp $ fmap f next+ fmap f (PureScopeM x) =+ PureScopeM $ f x++instance Applicative ScopeM where+ pure = PureScopeM+ SetDefault ident qexp next <*> f =+ SetDefault ident qexp $ next <*> f+ Overwrite ident qexp next <*> f =+ Overwrite ident qexp $ next <*> f+ PureScopeM g <*> f = f >>= (PureScopeM . g)++instance Monad ScopeM where+#if MIN_VERSION_base(4,9,0)+#else+ return = PureScopeM+#endif+ SetDefault ident qexp next >>= f = SetDefault ident qexp $ next >>= f+ Overwrite ident qexp next >>= f = Overwrite ident qexp $ next >>= f+ PureScopeM a >>= f = f a++{-| Constructor for 'ScopeM'.+ - Values declared by this function are overwritten+ - by same name variables exits in scope of render function.+ -}+setDefault :: Ident -> Q Exp -> ScopeM ()+setDefault ident qexp = SetDefault ident qexp $ pure ()++{-| Constructor for 'ScopeM'.+ - Values declared by this function overwrites+ - same name variables exits in scope of render function.+ -}+overwrite :: Ident -> Q Exp -> ScopeM ()+overwrite ident qexp = Overwrite ident qexp $ pure () instance IsString Ident where fromString = Ident