packages feed

ginger 0.5.2.1 → 0.5.3.0

raw patch · 5 files changed

+117/−4 lines, 5 filesdep −wrytePVP ok

version bump matches the API change (PVP)

Dependencies removed: wryte

API changes (from Hackage documentation)

+ Text.Ginger.GVal: marshalFunction :: (Functor m, Functor n) => (forall a. m a -> n a) -> (forall a. n a -> m a) -> Function m -> Function n
+ Text.Ginger.GVal: marshalGValEx :: (Functor m, Functor n) => (forall a. m a -> n a) -> (forall a. n a -> m a) -> GVal m -> GVal n
+ Text.Ginger.Run: hoistContext :: Monad m => (h -> t) -> (t -> h) -> GingerContext m h -> GingerContext m t
+ Text.Ginger.Run: hoistNewlines :: (h -> t) -> (t -> h) -> Newlines h -> Newlines t
+ Text.Ginger.Run: hoistRun :: Monad m => (h -> t) -> (t -> h) -> Run m h a -> Run m t a
+ Text.Ginger.Run: hoistRunState :: Monad m => (h -> t) -> (t -> h) -> RunState m h -> RunState m t
+ Text.Ginger.Run.VM: withEncoder :: (ContextEncodable h, Monad m) => (GVal (Run m h) -> h) -> Run m h a -> Run m h a

Files

ginger.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                ginger-version:             0.5.2.1+version:             0.5.3.0 synopsis:            An implementation of the Jinja2 template language in Haskell description:         Ginger is Jinja, minus the most blatant pythonisms. Wants                      to be feature complete, but isn't quite there yet.@@ -50,7 +50,6 @@                , unordered-containers >= 0.2.5                , utf8-string                , vector-               , wryte   hs-source-dirs:      src   default-language:    Haskell2010 @@ -66,7 +65,6 @@                  , text                  , transformers                  , unordered-containers >= 0.2.5-                 , wryte  test-suite tests     type: exitcode-stdio-1.0
src/Text/Ginger/GVal.hs view
@@ -2,6 +2,7 @@ {-#LANGUAGE MultiParamTypeClasses #-} {-#LANGUAGE FlexibleInstances #-} {-#LANGUAGE ScopedTypeVariables #-}+{-#LANGUAGE RankNTypes #-}  -- | GVal is a generic unitype value, representing the kind of values that -- Ginger can understand.@@ -34,6 +35,7 @@                , not                , fst, snd                , Monad+               , Functor                ) import qualified Prelude import Data.Maybe ( fromMaybe, catMaybes, isJust, mapMaybe )@@ -127,6 +129,39 @@         , length = length g         , asJSON = asJSON g         }++-- | Marshal a GVal between carrier monads.+-- Unlike 'marshalGVal', 'asFunction' information is retained by hoisting+-- them using the provided hoisting functions. For 'Run' monads, which is+-- what 'GVal' is typically used with, the 'hoistRun' function can be used+-- to construct suitable hoisting functions.+marshalGValEx :: (Functor m, Functor n)+              => (forall a. m a -> n a)+              -> (forall a. n a -> m a)+              -> GVal m+              -> GVal n+marshalGValEx hoist unhoist g =+    GVal+        { asList = fmap (marshalGValEx hoist unhoist) <$> asList g+        , asDictItems = fmap (\items -> [(k, marshalGValEx hoist unhoist v) | (k, v) <- items]) (asDictItems g)+        , asLookup = fmap (fmap (marshalGValEx hoist unhoist) .) (asLookup g)+        , asHtml = asHtml g+        , asText = asText g+        , asBoolean = asBoolean g+        , asNumber = asNumber g+        , asFunction = marshalFunction hoist unhoist <$> asFunction g+        , isNull = isNull g+        , length = length g+        , asJSON = asJSON g+        }++marshalFunction :: (Functor m, Functor n) => (forall a. m a -> n a) -> (forall a. n a -> m a) -> Function m -> Function n+-- [(Maybe Text, GVal m)] -> m (GVal m)+marshalFunction hoist unhoist f args =+    let args' = [ (name, marshalGValEx unhoist hoist value)+                | (name, value) <- args+                ]+    in marshalGValEx hoist unhoist <$> hoist (f args')  -- | Convenience wrapper around 'asDictItems' to represent a 'GVal' as a -- 'HashMap'.
src/Text/Ginger/Run.hs view
@@ -46,6 +46,11 @@ , Run, liftRun, liftRun2 -- * Helper functions for interpreting argument lists , extractArgs, extractArgsT, extractArgsL, extractArgsDefL+-- * Hoisting+, hoistContext+, hoistRun+, hoistNewlines+, hoistRunState ) where 
src/Text/Ginger/Run/Type.hs view
@@ -24,6 +24,11 @@ -- * The Newlines type -- | Required for handling indentation , Newlines (..)+-- * Hoisting+, hoistContext+, hoistRun+, hoistNewlines+, hoistRunState ) where @@ -89,6 +94,29 @@         , contextNewlines :: Maybe (Newlines h)         } +-- | Hoist a context onto a different output type.+-- @hoistContext fwd rev context@ returns a context over a different+-- output type, applying the @fwd@ and @rev@ projections to convert+-- between the original and desired output types.+hoistContext :: Monad m => (h -> t) -> (t -> h) -> GingerContext m h -> GingerContext m t+hoistContext fwd rev c =+    GingerContext+        { contextLookup = \varName ->+            marshalGValEx+                (hoistRun fwd rev)+                (hoistRun rev fwd) <$>+                hoistRun fwd rev (contextLookup c varName)+        , contextWrite = \val ->+            hoistRun fwd rev (contextWrite c $ rev val)+        , contextEncode = \gval ->+            fwd .+                contextEncode c .+                marshalGValEx (hoistRun rev fwd) (hoistRun fwd rev) $+                gval+        , contextNewlines =+            hoistNewlines fwd rev <$> contextNewlines c+        }+ contextWriteEncoded :: GingerContext m h -> GVal (Run m h) -> Run m h () contextWriteEncoded context =     contextWrite context . contextEncode context@@ -213,6 +241,18 @@         , endsWithNewline :: h -> Bool         } +-- | Hoist a 'Newlines' onto a different output type.+-- You don't normally need to use this directly; see 'hoistRun' and/or+-- 'hoistContext'.+hoistNewlines :: (h -> t) -> (t -> h) -> Newlines h -> Newlines t+hoistNewlines fwd rev n =+    Newlines+        { splitLines = List.map fwd . splitLines n . rev+        , joinLines = fwd . joinLines n . List.map rev+        , stripIndent = fwd . stripIndent n . rev+        , endsWithNewline = endsWithNewline n . rev+        }+ textNewlines :: Newlines Text textNewlines =     Newlines@@ -249,6 +289,20 @@         , rsAtLineStart :: Bool -- is the next output position the first column         } +-- | Hoist a 'RunState' onto a different output type.+-- You don't normally need to use this directly; see 'hoistRun' and/or+-- 'hoistContext'.+hoistRunState :: Monad m => (h -> t) -> (t -> h) -> RunState m h -> RunState m t+hoistRunState fwd rev rs =+    RunState+        { rsScope = marshalGValEx (hoistRun fwd rev) (hoistRun rev fwd) <$> rsScope rs+        , rsCapture = fwd $ rsCapture rs+        , rsCurrentTemplate = rsCurrentTemplate rs+        , rsCurrentBlockName = rsCurrentBlockName rs+        , rsIndentation = fmap fwd <$> rsIndentation rs+        , rsAtLineStart = rsAtLineStart rs+        }+ -- | Internal type alias for our template-runner monad stack. type Run m h = StateT (RunState m h) (ReaderT (GingerContext m h) m) @@ -259,3 +313,18 @@ -- | Lift a function from the host monad @m@ into the 'Run' monad. liftRun2 :: Monad m => (a -> m b) -> a -> Run m h b liftRun2 f x = liftRun $ f x++-- | Hoist a 'Run' action onto a different output type.+-- @hoistRun fwd rev action@ hoists the @action@ from @Run m h a@ to+-- @Run m t a@, applying @fwd@ and @rev@ to convert between the output+-- types.+hoistRun :: Monad m => (h -> t) -> (t -> h) -> Run m h a -> Run m t a+hoistRun fwd rev action = do+    contextT <- ask+    let contextH = hoistContext rev fwd contextT+    stateT <- get+    let stateH = hoistRunState rev fwd stateT+    (x, stateH') <- lift . lift $ runReaderT (runStateT action stateH) contextH+    let stateT' = hoistRunState fwd rev stateH'+    put stateT'+    return x
src/Text/Ginger/Run/VM.hs view
@@ -7,7 +7,7 @@ import Text.Ginger.GVal import Data.Monoid ( (<>) ) import Control.Monad.State (MonadState (..), get, gets, modify)-import Control.Monad.Reader (asks)+import Control.Monad.Reader (asks, local) import qualified Data.HashMap.Strict as HashMap import Data.HashMap.Strict (HashMap) @@ -28,6 +28,12 @@     r <- a     modify (\s -> s { rsScope = scope })     return r++-- | Override the encoder used for converting 'GVal's to the output type.+-- This can be used for things like temporarily disabling HTML encoding.+withEncoder :: (ContextEncodable h, Monad m) => (GVal (Run m h) -> h) -> Run m h a -> Run m h a+withEncoder encoder =+    local (\context -> context { contextEncode = encode })  setVar :: Monad m => VarName -> GVal (Run m h) -> Run m h () setVar name val = do