heterocephalus 1.0.0.2 → 1.0.1.0
raw patch · 2 files changed
+135/−35 lines, 2 filesdep ~doctestPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: doctest
API changes (from Hackage documentation)
+ Text.Heterocephalus: compileFileWithDefault :: DefaultScope -> HeterocephalusSetting -> FilePath -> Q Exp
+ Text.Heterocephalus: compileFromStringWithDefault :: DefaultScope -> HeterocephalusSetting -> String -> Q Exp
+ Text.Heterocephalus: compileHtmlFileWithDefault :: FilePath -> DefaultScope -> Q Exp
+ Text.Heterocephalus: compileTextFileWithDefault :: FilePath -> DefaultScope -> Q Exp
+ Text.Heterocephalus: compileWithDefault :: DefaultScope -> HeterocephalusSetting -> QuasiQuoter
+ Text.Heterocephalus: instance Data.String.IsString Text.Shakespeare.Base.Ident
+ Text.Heterocephalus: type DefaultScope = [(Ident, Q Exp)]
Files
- heterocephalus.cabal +3/−3
- src/Text/Heterocephalus.hs +132/−32
heterocephalus.cabal view
@@ -1,9 +1,9 @@ name: heterocephalus-version: 1.0.0.2+version: 1.0.1.0 synopsis: A type safe template engine for collaborating with front end development tools description: Recent front end developing tools are growing fast and have created the complicated ecosystem, and few front end developer want to use Shakespeare template instead of commonly used @node@ friendly engines such that @pug@, @slim@, @haml@, though Shakespeare template has great feature of compile time variable interpolation and type checking.-+ . From this observation, Heterocephalus is developed for using with another feature rich template engine and only provides the way to interpolate server side variables into the precompiled template file with @forall@ and @if@ statement. homepage: https://github.com/arowM/heterocephalus#readme@@ -47,7 +47,7 @@ main-is: Doctest.hs build-depends: base , Glob- , doctest+ , doctest >= 0.10 , heterocephalus ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010
src/Text/Heterocephalus.hs view
@@ -1,26 +1,43 @@ {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-} {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} module Text.Heterocephalus ( -- * Core functions- compileText- , compileTextFile- , compileHtml+ compileTextFile+ , compileTextFileWithDefault , compileHtmlFile+ , compileHtmlFileWithDefault + -- * QuasiQuoters+ , compileText+ , compileHtml+ -- * low-level , HeterocephalusSetting(escapeExp)+ , DefaultScope , compile+ , compileWithDefault , compileFile+ , compileFileWithDefault , compileFromString+ , compileFromStringWithDefault ) where +#if MIN_VERSION_base(4,9,0)+#else+import Control.Applicative ((<$>))+#endif+import Control.Monad (forM) import Data.Char (isDigit) 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.Quote #if MIN_VERSION_template_haskell(2,9,0) import Language.Haskell.TH.Syntax hiding (Module)@@ -41,9 +58,89 @@ >>> import Text.Blaze.Renderer.String -} +{-| A function to compile template file.+ This function __DOES NOT__ escape template variables.+ To render the compiled file, use @'Text.Blaze.Renderer'.*.renderMarkup@.++ >>> putStr $ renderMarkup (let as = ["<a>", "b"] in $(compileTextFile "templates/sample.txt"))+ sample+ key: <a>,+ key: b,+ -}+compileTextFile :: FilePath -> Q Exp+compileTextFile = compileFile textSetting++{-| Same as 'compileText' but we can specify default scope.++ >>> :set -XOverloadedStrings+ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileTextFileWithDefault "templates/sample.txt"+ >>> [("as", [| ["foo", "bar"] |])]+ >>> )+ >>> )+ >>> :}+ sample+ key: <a>,+ key: b,++ >>> :{+ >>> putStr $ renderMarkup (+ >>> $(compileTextFileWithDefault "templates/sample.txt"+ >>> [("as", [| ["foo", "bar"] |])]+ >>> )+ >>> )+ >>> :}+ sample+ key: foo,+ key: bar,+ -}+compileTextFileWithDefault :: FilePath -> DefaultScope -> Q Exp+compileTextFileWithDefault fp scope = compileFileWithDefault scope textSetting fp++{-| Same as 'compileTextFile' but escapes template variables for Html.++ >>> putStr $ renderMarkup (let as = ["<a>", "b"] in $(compileHtmlFile "templates/sample.txt"))+ sample+ key: <a>,+ key: b,+ -}+compileHtmlFile :: FilePath -> Q Exp+compileHtmlFile fp = compileHtmlFileWithDefault fp []++{-| Same as 'compileHtmlFile' but we can specify default scope.++ >>> :set -XOverloadedStrings+ >>> :{+ >>> putStr $ renderMarkup (+ >>> let as = ["<a>", "b"]+ >>> in $(compileHtmlFileWithDefault "templates/sample.txt"+ >>> [("as", [| ["foo", "bar"] |])]+ >>> )+ >>> )+ >>> :}+ sample+ key: <a>,+ key: b,++ >>> :{+ >>> putStr $ renderMarkup (+ >>> $(compileHtmlFileWithDefault "templates/sample.txt"+ >>> [("as", [| ["foo", "bar"] |])]+ >>> )+ >>> )+ >>> :}+ sample+ key: foo,+ key: bar,+ -}+compileHtmlFileWithDefault :: FilePath -> DefaultScope -> Q Exp+compileHtmlFileWithDefault fp scope = compileFileWithDefault scope htmlSetting fp+ {-| Heterocephalus quasi-quoter. This function DOES NOT escape template variables.- To render the compiled file, use @Text.Blaze.Renderer.*.renderMarkup@.+ To render the compiled file, use @'Text.Blaze.Renderer'.*.renderMarkup@. >>> renderMarkup (let as = ["<a>", "b"] in [compileText|sample %{ forall a <- as }key: #{a}, %{ endforall }|]) "sample key: <a>, key: b, "@@ -63,32 +160,13 @@ compileHtml :: QuasiQuoter compileHtml = compile htmlSetting -{-| Heterocephalus quasi-quoter.- Same as 'compileText' but this function read template literal from an external file.-- >>> putStr $ renderMarkup (let as = ["<a>", "b"] in $(compileTextFile "templates/sample.txt"))- sample- key: <a>,- key: b,- -}-compileTextFile :: FilePath -> Q Exp-compileTextFile = compileFile textSetting--{-| Heterocephalus quasi-quoter.- Same as 'compileTextFile' but escapes template variables for Html.-- >>> putStr $ renderMarkup (let as = ["<a>", "b"] in $(compileHtmlFile "templates/sample.txt"))- sample- key: <a>,- key: b,- -}-compileHtmlFile :: FilePath -> Q Exp-compileHtmlFile = compileFile htmlSetting- compile :: HeterocephalusSetting -> QuasiQuoter-compile set =+compile = compileWithDefault []++compileWithDefault :: DefaultScope -> HeterocephalusSetting -> QuasiQuoter+compileWithDefault scope set = QuasiQuoter- { quoteExp = compileFromString set+ { quoteExp = compileFromStringWithDefault scope set , quotePat = error "not used" , quoteType = error "not used" , quoteDec = error "not used"@@ -97,17 +175,34 @@ {-| Compile a template file. -} compileFile :: HeterocephalusSetting -> FilePath -> Q Exp-compileFile set fp = do+compileFile = compileFileWithDefault []++{-| Same as 'compileFile' but we can specify default scope.+-}+compileFileWithDefault :: DefaultScope -> HeterocephalusSetting -> FilePath -> Q Exp+compileFileWithDefault scope' set fp = do #ifdef GHC_7_4 qAddDependentFile fp #endif contents <- fmap TL.unpack $ qRunIO $ readUtf8File fp- compileFromString set contents+ compileFromStringWithDefault scope' set contents compileFromString :: HeterocephalusSetting -> String -> Q Exp-compileFromString set s =- docsToExp set [] $ docFromString s+compileFromString = compileFromStringWithDefault [] +compileFromStringWithDefault :: DefaultScope -> HeterocephalusSetting -> String -> Q Exp+compileFromStringWithDefault scope' set s = do+ scope <-+ forM scope' $ \(ident, qexp) -> (ident, ) <$> overwriteScope ident qexp+ docsToExp set scope $ docFromString s++overwriteScope :: Ident -> Q Exp -> Q Exp+overwriteScope (Ident str) qexp = do+ mName <- lookupValueName str+ case mName of+ Just x -> varE x+ Nothing -> qexp+ docFromString :: String -> [Doc] docFromString s = case parseDoc s of@@ -131,6 +226,11 @@ textSetting = HeterocephalusSetting { escapeExp = [|preEscapedToMarkup|] }++type DefaultScope = [(Ident, Q Exp)]++instance IsString Ident where+ fromString = Ident -- ============================================== -- Helper functions