packages feed

glabrous 0.1.1.0 → 0.1.2.0

raw patch · 4 files changed

+89/−61 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Text.Glabrous.Types: instance Data.Aeson.Types.Class.FromJSON Text.Glabrous.Types.Context
- Text.Glabrous.Types: instance Data.Aeson.Types.Class.ToJSON Text.Glabrous.Types.Context
+ Text.Glabrous: isSet :: Context -> Bool
+ Text.Glabrous: variablesOf :: Context -> [Text]
+ Text.Glabrous.Types: instance Data.Aeson.Types.FromJSON.FromJSON Text.Glabrous.Types.Context
+ Text.Glabrous.Types: instance Data.Aeson.Types.ToJSON.ToJSON Text.Glabrous.Types.Context

Files

README.md view
@@ -1,10 +1,5 @@ # Glabrous [![Build Status](https://travis-ci.org/MichelBoucey/glabrous.svg?branch=master)](https://travis-ci.org/MichelBoucey/glabrous) ---Glabrous is a minimalistic Mustache-like syntax, truly logic-less, pure Text template library.--* Use only the simplest Mustache tag {{name}}-* HTML agnostic+Glabrous is a minimalistic Mustache-like syntax - using only the simplest Mustache tag: {{name}} -, truly logic-less, HTML agnostic pure Text template library. -Bug fixes & improvements are welcome.+Any improvement is welcome.
glabrous.cabal view
@@ -1,5 +1,5 @@ name:                glabrous-version:             0.1.1.0+version:             0.1.2.0 synopsis:            A template library description:         A minimalistic, Mustache-like syntax, truly logic-less,                      pure Text template library
src/Text/Glabrous.hs view
@@ -11,41 +11,61 @@  module Text.Glabrous     (-    -- * Template++    -- * 'Template'+       Template (..)     , Tag+     -- ** Get a 'Template'+     , fromText     , readTemplateFile+     -- ** 'Template' operations+     , toText     , isFinal     , tagsOf     , tagsRename     , compress     , writeTemplateFile-    -- * Context++    -- * 'Context'+     , Context (..)+     -- ** Get a 'Context'+     , initContext     , fromList     , fromTemplate+     -- ** 'Context' operations+     , setVariables     , deleteVariables+    , variablesOf+    , isSet     , unsetContext+     -- ** JSON 'Context' file+     , readContextFile     , writeContextFile     , initContextFile+     -- * Processing+     , process     , processWithDefault     , partialProcess     , G.Result (..)     , partialProcess'+     ) where +import           Control.Monad import           Data.Aeson import           Data.Aeson.Encode.Pretty (encodePretty) import qualified Data.ByteString.Lazy     as L@@ -57,28 +77,26 @@ import           Text.Glabrous.Internal import           Text.Glabrous.Types      as G --- | Optimize a 'Template' content after (many) partialProcess(') rewriting(s).+-- | Optimize a 'Template' content after (many) 'partialProcess'(') rewriting(s). compress :: Template -> Template-compress t =-    Template { content = packC (content t) [] }+compress Template {..} =+    Template { content = go content [] }   where-    packC ts !o = do-        let (a,b) = span isL ts+    go ts !ac = do+        let (a,b) = span isLiteral ts+            u = uncons b         if not (null a)-            then packC b (o ++ [concatL a])-            else if not (null b)-                     then do let (a',b') = span (not.isL) b-                             if not (null a')-                                 then packC b' (o ++ a')-                                 else if not (null b')-                                          then packC b' o-                                          else o-                     else o+            then case u of+                Just (c,d) -> go d (ac ++ [concatLiterals a] ++ [c])+                Nothing    -> ac ++ [concatLiterals a]+            else case u of+                Just (e,f) -> go f (ac ++ [e])+                Nothing    -> ac       where-        isL (Literal _) = True-        isL (Tag _)     = False-        concatL _ts =-            foldr trans (Literal "") _ts+        isLiteral (Literal _) = True+        isLiteral (Tag _)     = False+        concatLiterals =+            foldr trans (Literal "")           where             trans (Literal a) (Literal b) = Literal (a `T.append` b)             trans _           _           = undefined@@ -92,22 +110,26 @@ -- >λ>setVariables [("something","something new"), ("about","Haskell")] context -- >Context {variables = fromList [("etc.","..."),("about","Haskell"),("something","something new"),("name","")]} setVariables :: [(T.Text,T.Text)] -> Context -> Context-setVariables ts c@Context{..} =-    case uncons ts of-        Just ((k,v),ts') ->-            setVariables ts' Context { variables = H.insert k v variables }-        Nothing          -> c+setVariables ts Context {..} =+    go ts variables+  where+    go _ts vs =+        case uncons _ts of+            Just ((k,v),ts') -> go ts' $ H.insert k v vs+            Nothing          -> Context { variables = vs }  -- | Delete variables from a 'Context' by these names. -- -- >λ>deleteVariables ["something"] context -- >Context {variables = fromList [("etc.","..."),("about","Haskell"),("name","")]} deleteVariables :: [T.Text] -> Context -> Context-deleteVariables ts c@Context{..} =-    case uncons ts of-        Just (k,ts') ->-            deleteVariables ts' Context { variables = H.delete k variables }-        Nothing      -> c+deleteVariables ts Context {..} =+    go ts variables+  where+    go _ts vs =+        case uncons _ts of+            Just (k,ts') -> go ts' $ H.delete k vs+            Nothing      -> Context { variables = vs }  -- | Build a 'Context' from a list of 'Tag's and replacement 'T.Text's. --@@ -117,8 +139,8 @@ fromList :: [(T.Text, T.Text)] -> Context fromList ts = Context { variables = H.fromList ts } --- | Extract 'Tag's from a 'Template' and build--- a 'Context' with all its variables empty.+-- | Build an adhoc 'Context' for the given+-- 'Template' with all its variables empty. fromTemplate :: Template -> Context fromTemplate t = setVariables ((\e -> (e,T.empty)) <$> tagsOf t) initContext @@ -149,7 +171,7 @@ -- @ -- initContextFile :: FilePath -> Context -> IO ()-initContextFile f Context{..} = L.writeFile f $+initContextFile f Context {..} = L.writeFile f $     encodePretty Context { variables = H.map (const T.empty) variables }  -- | Build 'Just' a (sub)'Context' made of unset variables@@ -159,12 +181,21 @@ -- >Just (Context {variables = fromList [("name","")]}) -- unsetContext :: Context -> Maybe Context-unsetContext Context{..} = do+unsetContext Context {..} = do     let vs = H.filter (== T.empty) variables-    if vs /= H.empty-       then Just Context { variables = vs }-       else Nothing+    guard (vs /= H.empty)+    return Context { variables = vs } +-- | 'True' if the all variables of+-- the given 'Context' are not empty+isSet :: Context -> Bool+isSet Context {..} =+    H.foldr (\v b -> b && v /= T.empty) True variables++-- | Get the list of the given 'Context' variables+variablesOf :: Context -> [T.Text]+variablesOf Context {..} = H.keys variables+ -- | Get a 'Template' from a file. readTemplateFile :: FilePath -> IO (Either String Template) readTemplateFile f = fromText <$> I.readFile f@@ -177,7 +208,7 @@ -- as it is, with its 'Tag's, if they exist (no -- 'Context' is processed). toText :: Template -> T.Text-toText Template{..} =+toText Template {..} =     T.concat $ trans <$> content   where     trans (Literal c) = c@@ -185,14 +216,14 @@  -- | Get the list of 'Tag's in the given 'Template'. tagsOf :: Template -> [Tag]-tagsOf Template{..} =+tagsOf Template {..} =     (\(Tag k) -> k) <$> filter isTag content   where     isTag (Tag _) = True     isTag _       = False  tagsRename :: [(T.Text,T.Text)] -> Template -> Template-tagsRename ts Template{..} =+tagsRename ts Template {..} =     Template { content = rename <$> content }   where     rename t@(Tag n) =@@ -204,7 +235,7 @@ -- | 'True' if a 'Template' has no more 'Tag' -- inside and can be used as a final 'T.Text'. isFinal :: Template -> Bool-isFinal Template{..} =+isFinal Template {..} =     allLiteral content   where     allLiteral t =@@ -226,12 +257,12 @@                    -> Template                    -> Context                    -> T.Text-processWithDefault d Template{..} c = toTextWithContext (const d) c content+processWithDefault d Template {..} c = toTextWithContext (const d) c content  -- | Process a (sub)'Context' present in the given template, leaving -- untouched, if they exist, other 'Tag's, to obtain a new template. partialProcess :: Template -> Context -> Template-partialProcess Template{..} c =+partialProcess Template {..} c =     Template { content = transTags content c }   where     transTags ts Context{..} =@@ -250,18 +281,16 @@ -- >λ>partialProcess' template context -- >Partial {template = Template {content = [Literal "Some ",Tag "tags",Literal " are unused in this ",Tag "text",Literal "."]}, tags = ["tags","text"]} partialProcess' :: Template -> Context -> G.Result-partialProcess' t c@Context{..} =-    case foldl trans (Template { content = [] },[]) (content t) of-        (f,[]) -> Final $ toTextWithContext (const T.empty) c (content f)-        (p,p') -> G.Partial p p'+partialProcess' t c@Context {..} =+    case foldl trans ([],[]) (content t) of+        (f,[]) -> Final $ toTextWithContext (const T.empty) c f+        (p,p') -> G.Partial Template { content = p } p'   where-    trans (!c',ts) t' =+    trans (!c',!ts) t' =         case t' of             Tag k     ->                 case H.lookup k variables of-                    Just v  -> (addToken (Literal v) c',ts)-                    Nothing -> (addToken t' c',ts ++ [k])-            Literal _ -> (addToken t' c',ts)-      where-        addToken a b = Template { content = content b ++ [a] }+                    Just v  -> (c' ++ [Literal v],ts)+                    Nothing -> (c' ++ [t'],ts ++ [k])+            Literal _ -> (c' ++ [t'],ts) 
tests/hspec.hs view
@@ -71,6 +71,10 @@         it "gets a Context made of unset variables of the given context" $         fromJust <$> unsetContext <$> setVariables variablesList <$> fromTemplate <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` Context {variables = H.fromList [("tortor",""),("commodo",""),("fermentum",""),("rhoncus",""),("bibendum",""),("venenatis","")]}  +    describe "isSet" $+        it "true if all variables are not empty" $+        (return $ isSet context') `shouldReturn` True+      describe "writeContextFile" $         it "writes a context to a file" $ do             !acontext <- fromJust <$> readContextFile contextFile