packages feed

glabrous 0.4.0 → 1.0.0

raw patch · 5 files changed

+58/−35 lines, 5 filesdep ~hspecPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: hspec

API changes (from Hackage documentation)

- Text.Glabrous: data Context
- Text.Glabrous: data Template
- Text.Glabrous: type Tag = Text
- Text.Glabrous.Types: data Context
- Text.Glabrous.Types: data Template
- Text.Glabrous.Types: type Tag = Text
+ Text.Glabrous: insertMany :: Template -> [(Token, Template)] -> Maybe Template
+ Text.Glabrous: newtype Context
+ Text.Glabrous: newtype Template
+ Text.Glabrous.Types: newtype Context
+ Text.Glabrous.Types: newtype Template
- Text.Glabrous: Context :: !(HashMap Text Text) -> Context
+ Text.Glabrous: Context :: HashMap Text Text -> Context
- Text.Glabrous: Template :: ![Token] -> Template
+ Text.Glabrous: Template :: [Token] -> Template
- Text.Glabrous: [content] :: Template -> ![Token]
+ Text.Glabrous: [content] :: Template -> [Token]
- Text.Glabrous: [variables] :: Context -> !(HashMap Text Text)
+ Text.Glabrous: [variables] :: Context -> HashMap Text Text
- Text.Glabrous: insert :: Template -> Text -> Template -> Maybe Template
+ Text.Glabrous: insert :: Template -> Token -> Template -> Maybe Template
- Text.Glabrous: tagsOf :: Template -> [Tag]
+ Text.Glabrous: tagsOf :: Template -> [Token]
- Text.Glabrous.Types: Context :: !(HashMap Text Text) -> Context
+ Text.Glabrous.Types: Context :: HashMap Text Text -> Context
- Text.Glabrous.Types: Template :: ![Token] -> Template
+ Text.Glabrous.Types: Template :: [Token] -> Template
- Text.Glabrous.Types: [content] :: Template -> ![Token]
+ Text.Glabrous.Types: [content] :: Template -> [Token]
- Text.Glabrous.Types: [variables] :: Context -> !(HashMap Text Text)
+ Text.Glabrous.Types: [variables] :: Context -> HashMap Text Text

Files

glabrous.cabal view
@@ -1,5 +1,5 @@ name:                glabrous-version:             0.4.0+version:             1.0.0 synopsis:            A template DSL library description:         A minimalistic, Mustache-like syntax, truly logic-less,                      pure Text template DSL library@@ -45,7 +45,7 @@                      , directory > 1.2 && < 1.4                      , either >= 4.4.1 && < 5.1                      , glabrous-                     , hspec >= 2.1.10 && < 2.6+                     , hspec >= 2.1.10 && < 2.7                      , text >= 1.2.1 && < 1.3                      , unordered-containers == 0.2.*   default-language:    Haskell2010
src/Text/Glabrous.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns      #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE TupleSections     #-}  -- | A minimalistic Mustache-like syntax, truly logic-less, -- pure 'T.Text' template library@@ -14,7 +15,6 @@    -- * 'Template'     Template (..)-  , Tag    -- ** Get a 'Template'   , fromText@@ -29,6 +29,7 @@   , compress   , writeTemplateFile   , insert+  , insertMany    -- * 'Context'   , Context (..)@@ -56,22 +57,22 @@   , process   , processWithDefault   , partialProcess-  , G.Result (..)+  , Result (..)   , partialProcess'    ) where  import           Control.Monad            (guard)-import           Data.Aeson+import           Data.Aeson               hiding (Result) import           Data.Aeson.Encode.Pretty (encodePretty) import qualified Data.ByteString.Lazy     as L import qualified Data.HashMap.Strict      as H-import           Data.List                (uncons)+import           Data.List                (intersect,uncons) import qualified Data.Text                as T import qualified Data.Text.IO             as I  import           Text.Glabrous.Internal-import           Text.Glabrous.Types      as G+import           Text.Glabrous.Types  -- | Optimize a 'Template' content after (many) 'partialProcess'(') rewriting(s). compress :: Template -> Template@@ -138,11 +139,11 @@ -- >λ>fromTagsList ["tag","etc."] -- >Context {variables = fromList [("etc.",""),("tag","")]} fromTagsList :: [T.Text] -> Context-fromTagsList ts = fromList $ (\t -> (t,T.empty)) <$> ts+fromTagsList ts = fromList $ (,T.empty) <$> ts  -- | Build an unset ad hoc 'Context' from the given 'Template'. fromTemplate :: Template -> Context-fromTemplate t = setVariables ((\e -> (e,T.empty)) <$> tagsOf t) initContext+fromTemplate t = setVariables ((\(Tag e) -> (e,T.empty)) <$> tagsOf t) initContext  -- | Get a 'Context' from a JSON file. readContextFile :: FilePath -> IO (Maybe Context)@@ -216,21 +217,45 @@ writeTemplateFile f t = I.writeFile f (toText t)  -- | get 'Just' a new 'Template' by inserting a 'Template'--- into another one by replacing the 'Tag' named, or 'Nothing'.+-- into another one by replacing the 'Tag', or 'Nothing'.+--+-- >λ>insert t0 (Tag "template1") t1 insert :: Template       -- ^ The Template to insert in-       -> T.Text         -- ^ The Tag name to be replaced+       -> Token          -- ^ The Tag to be replaced        -> Template       -- ^ The Template to be inserted        -> Maybe Template -- ^ Just the new Template, or Nothing-insert te tn te' = do-  guard (Tag tn `elem` content te)+insert _ (Literal _) _ = Nothing+insert te t te' = do+  guard (t `elem` content te)   return Template { content = foldl trans [] (content te) }   where-    trans o t@(Tag tn') =-      if tn' == tn+    trans o t'@(Tag _) =+      if t' == t         then o ++ content te'-        else o ++ [t]+        else o ++ [t']     trans o l = o ++ [l] +-- | get 'Just' a new 'Template' by inserting many 'Template's,+-- if there is at least one tag correspondence, or 'Nothing'.+--+-- >λ>insertMany t0 [(Tag "template1",t1),(Tag "template2",t2)]+insertMany :: Template -> [(Token,Template)] -> Maybe Template+insertMany te ttps = do+  guard (tagsOf te `intersect` (fst <$> ttps) /= mempty)+  return Template { content = foldl trans [] (content te) }+  where+    trans o li@(Literal _) = o ++ [li]+    trans o ta@(Tag _) =+      case lookupTemplate ta ttps of+        Nothing  -> o ++ [ta]+        Just te' -> o ++ content te'+    lookupTemplate (Literal _) _ = Nothing+    lookupTemplate _ []          = Nothing+    lookupTemplate t (p:ps) =+      if fst p == t+        then Just (snd p)+        else lookupTemplate t ps+ -- | Output the content of the given 'Template' -- as it is, with its 'Tag's, if they exist. toText :: Template -> T.Text@@ -250,12 +275,8 @@     trans o (Tag _) = o  -- | Get the list of 'Tag's in the given 'Template'.-tagsOf :: Template -> [Tag]-tagsOf Template{..} =-  (\(Tag k) -> k) <$> filter isTag content-  where-    isTag (Tag _) = True-    isTag _       = False+tagsOf :: Template -> [Token]+tagsOf Template{..} = filter isTag content  tagsRename :: [(T.Text,T.Text)] -> Template -> Template tagsRename ts Template{..} =@@ -307,11 +328,11 @@ -- -- >λ>partialProcess' template context -- >Partial {template = Template {content = [Literal "Some ",Tag "tags",Literal " are unused in this ",Tag "text",Literal "."]}, context = Context {variables = fromList [("text",""),("tags","")]}}-partialProcess' :: Template -> Context -> G.Result+partialProcess' :: Template -> Context -> Result partialProcess' t c@Context{..} =-  case foldl trans ([],[]) (content t) of+  case foldl trans (mempty,mempty) (content t) of     (f,[]) -> Final (toTextWithContext (const T.empty) c f)-    (p,p') -> G.Partial Template { content = p } (fromTagsList p')+    (p,p') -> Partial Template { content = p } (fromTagsList p')   where     trans (!c',!ts) t' =       case t' of
src/Text/Glabrous/Internal.hs view
@@ -9,11 +9,11 @@ import           Data.Maybe           (fromMaybe) import qualified Data.Text            as T -import           Text.Glabrous.Types  as G+import           Text.Glabrous.Types  toTextWithContext :: (T.Text -> T.Text) -> Context -> [Token] -> T.Text toTextWithContext tagDefault Context{..} ts =-  T.concat $ trans <$> ts+  T.concat (trans <$> ts)   where     trans (Tag k)     = fromMaybe (tagDefault k) (H.lookup k variables)     trans (Literal c) = c@@ -33,13 +33,17 @@ isLiteral (Literal _) = True isLiteral _           = False +isTag :: Token -> Bool+isTag (Tag _) = True+isTag _       = False+ tokens :: Parser [Token] tokens =   many' token   where     token = literal <|> tag <|> leftover     leftover = do-      c <- takeWhile1 $ not . content+      c <- takeWhile1 (not . content)       return (Literal c)     literal = do       c <- takeWhile1 content
src/Text/Glabrous/Types.hs view
@@ -18,16 +18,16 @@  instance Serialize Token -data Template =+newtype Template =   Template-    { content :: ![Token] }+    { content :: [Token] }     deriving (Eq, Show, Generic)  instance Serialize Template -data Context =+newtype Context =   Context-    { variables :: !(H.HashMap T.Text T.Text) }+    { variables :: H.HashMap T.Text T.Text }     deriving (Eq, Show)  instance ToJSON Context where@@ -38,8 +38,6 @@   parseJSON (Object o) = return     Context { variables = H.fromList ((\(k,String v) -> (k,v)) <$> H.toList o) }   parseJSON _          = fail "expected an object"--type Tag = T.Text  data Result   = Final !T.Text
tests/hspec.hs view
@@ -49,7 +49,7 @@      describe "tagsOf" $         it "returns the list of tags in a template" $-            tagsOf <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` ["ipsum","tortor","lectus","vehicula","bibendum","condimentum","tellus","faucibus","cursus","commodo","vestibulum","lobortis","fermentum","maximus","venenatis","sagittis","vitae","rhoncus"]+            tagsOf <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` [Tag "ipsum",Tag "tortor",Tag "lectus",Tag "vehicula",Tag "bibendum",Tag "condimentum",Tag "tellus",Tag "faucibus",Tag "cursus",Tag "commodo",Tag "vestibulum",Tag "lobortis",Tag "fermentum",Tag "maximus",Tag "venenatis",Tag "sagittis",Tag "vitae",Tag "rhoncus"]      describe "toText" $         it "returns the template as it is" $