diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2016, Michel Boucey
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of glabrous nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/glabrous.cabal b/glabrous.cabal
new file mode 100644
--- /dev/null
+++ b/glabrous.cabal
@@ -0,0 +1,47 @@
+name:                glabrous
+version:             0.1.0.0
+synopsis:            A template library
+description:         A minimalistic, Mustache-like syntax, truly logic-less,
+                     pure Text template library
+homepage:            https://github.com/MichelBoucey/glabrous
+license:             BSD3
+license-file:        LICENSE
+author:              Michel Boucey
+maintainer:          michel.boucey@gmail.com
+copyright:           2016 (c) Michel Boucey
+category:            Text, Web
+build-type:          Simple
+cabal-version:       >=1.10
+
+source-repository head
+  type:     git
+  location: https://github.com/MichelBoucey/glabrous
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Text.Glabrous, Text.Glabrous.Types
+  other-modules:       Text.Glabrous.Internal
+  build-depends:       aeson >= 0.11
+                     , aeson-pretty >= 0.7
+                     , attoparsec >= 0.13
+                     , base >= 4.7 && < 5
+                     , bytestring >= 0.10.6
+                     , either >= 4.4
+                     , text >= 1.2
+                     , unordered-containers >= 0.2
+  default-language:    Haskell2010
+  GHC-options:       -Wall
+
+test-suite tests
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      tests
+  main-is:             hspec.hs
+  build-depends:       hspec >= 2.2.3
+                     , base >= 4.7 && < 5
+                     , directory >= 1.2
+                     , either >= 4.4
+                     , glabrous
+                     , text >= 1.2
+                     , unordered-containers >= 0.2
+  default-language:    Haskell2010
+
diff --git a/src/Text/Glabrous.hs b/src/Text/Glabrous.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Glabrous.hs
@@ -0,0 +1,212 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | A minimalistic Mustache-like syntax, truly logic-less,
+-- pure 'T.Text' template library
+--
+--    * Use only the simplest Mustache tag {{name}} called a variable.
+--    * HTML agnostic
+--
+
+module Text.Glabrous
+    (
+    -- * Template
+      Template (..)
+    , Tag
+    -- ** Get a 'Template'
+    , fromText
+    , readTemplateFile
+    -- ** 'Template' operations
+    , toText
+    , tagsOf
+    , isFinal
+    , writeTemplateFile
+    -- * Context
+    , Context (..)
+    -- ** Get a 'Context'
+    , initContext
+    , fromList
+    , fromTemplate
+    -- ** 'Context' operations
+    , setVariables
+    , deleteVariables
+    , unsetContext
+    -- ** JSON 'Context' file
+    , readContextFile
+    , writeContextFile
+    , initContextFile
+    -- * Processing
+    , process
+    , processWithDefault
+    , partialProcess
+    , G.Result (..)
+    , partialProcess'
+    ) where
+
+import           Data.Aeson
+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 qualified Data.Text                as T
+import qualified Data.Text.IO             as I
+
+import           Text.Glabrous.Internal
+import           Text.Glabrous.Types      as G
+
+-- | Build an empty 'Context'.
+initContext :: Context
+initContext = Context { variables = H.empty }
+
+-- | Populate with variables and/or update variables in the given 'Context'.
+--
+-- >λ>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
+
+-- | 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
+
+-- | Build a 'Context' from a list of 'Tag's and replacement 'T.Text's.
+--
+-- >λ>fromList [("something","something else"), ("etc.","...")]
+-- >Context {variables = fromList [("etc.","..."),("something","something else")]}
+--
+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 empty variables.
+fromTemplate :: Template -> Context
+fromTemplate t = setVariables ((\e -> (e,T.empty)) <$> tagsOf t) initContext
+
+-- | Get a 'Context' from a file.
+readContextFile :: FilePath -> IO (Maybe Context)
+readContextFile f = decode <$> L.readFile f
+
+-- | Write a 'Context' to a file.
+writeContextFile :: FilePath -> Context -> IO ()
+writeContextFile f c = L.writeFile f $ encodePretty c
+
+-- | Based on the given 'Context', write a
+-- 'Context' file with all its variables empty.
+initContextFile :: FilePath -> Context -> IO ()
+initContextFile f Context{..} = L.writeFile f $
+    encodePretty Context { variables = H.map (const T.empty) variables }
+
+-- | Build 'Just' a (sub)'Context' made of unset variables
+-- of the given context, or 'Nothing'.
+--
+-- >λ>unsetContext context
+-- >Just (Context {variables = fromList [("name","")]})
+--
+unsetContext :: Context -> Maybe Context
+unsetContext Context{..} = do
+    let vs = H.filter (== T.empty) variables
+    if vs /= H.empty
+       then Just Context { variables = vs }
+       else Nothing
+
+-- | Get a 'Template' from a file.
+readTemplateFile :: FilePath -> IO (Either String Template)
+readTemplateFile f = fromText <$> I.readFile f
+
+-- | Write a 'Template' to a file.
+writeTemplateFile :: FilePath -> Template -> IO ()
+writeTemplateFile f t = I.writeFile f $ toText t
+
+-- | Output the content of the given 'Template'
+-- as it is, with its 'Tag's, if they exist (no
+-- 'Context' is processed).
+toText :: Template -> T.Text
+toText t =
+    T.concat $ trans <$> content t
+  where
+    trans (Literal c) = c
+    trans (Tag k)     = T.concat ["{{",k,"}}"]
+
+-- | 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
+
+-- | 'True' if a 'Template' has no more 'Tag'
+-- inside and can be used as a final 'T.Text'.
+isFinal :: Template -> Bool
+isFinal Template{..} =
+    allLiteral content
+  where
+    allLiteral t =
+        case uncons t of
+            Just (t',ts) ->
+                case t' of
+                    Literal _ -> allLiteral ts
+                    Tag _     -> False
+            Nothing      -> True
+
+-- | Process, discard 'Tag's which are not in the 'Context'
+-- and leave them without replacement text in the final 'T.Text'.
+process :: Template -> Context -> T.Text
+process = processWithDefault T.empty
+
+-- | Process and replace missing variables in 'Context'
+-- with the given default replacement 'T.Text'.
+processWithDefault :: T.Text    -- ^ Default replacement text
+                   -> Template
+                   -> Context
+                   -> T.Text
+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 =
+    Template { content = transTags content c }
+  where
+    transTags ts Context{..} =
+        trans <$> ts
+      where
+        trans i@(Tag k) =
+            case H.lookup k variables of
+                Just v  -> Literal v
+                Nothing -> i
+        trans t = t
+
+-- | Process a (sub)'Context' present in the given template, and
+-- get either a 'Final' 'T.Text' or a new 'Template' with the list
+-- of its 'Tag's.
+--
+-- >λ>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'
+  where
+    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] }
+
diff --git a/src/Text/Glabrous/Internal.hs b/src/Text/Glabrous/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Glabrous/Internal.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
+
+module Text.Glabrous.Internal where
+
+import           Control.Applicative  ((<|>))
+import           Data.Attoparsec.Text
+import qualified Data.HashMap.Strict  as H
+import           Data.Maybe           (fromMaybe)
+import qualified Data.Text            as T
+
+import           Text.Glabrous.Types  as G
+
+toTextWithContext :: (T.Text -> T.Text) -> Context -> [Token] -> T.Text
+toTextWithContext tagDefault Context{..} ts =
+    T.concat $ trans <$> ts
+  where
+    trans (Tag k)     = fromMaybe (tagDefault k) (H.lookup k variables)
+    trans (Literal c) = c
+
+-- | Build a 'Template' from a 'T.Text'.
+--
+-- >λ>fromText "Glabrous templates use only the simplest Mustache tag: {{name}}."
+-- >Right (Template {content = [Literal "Glabrous templates use only the simplest Mustache tag: ",Tag "name",Literal "."]})
+--
+fromText :: T.Text -> Either String Template
+fromText t =
+    case parseOnly tokens t of
+        Right ts -> Right Template { content = ts }
+        Left e   -> Left e
+
+tokens :: Parser [Token]
+tokens =
+    many' token
+  where
+    token = literal <|> tag <|> leftover
+    leftover = do
+        c <- takeWhile1 $ not . content
+        return (Literal c)
+    literal = do
+        c <- takeWhile1 content
+        return (Literal c)
+    tag = do
+        _ <- string "{{"
+        Literal t <- literal
+        _ <- string "}}"
+        return (Tag t)
+    content '}' = False
+    content '{' = False
+    content _   = True
+
diff --git a/src/Text/Glabrous/Types.hs b/src/Text/Glabrous/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Glabrous/Types.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Text.Glabrous.Types where
+
+import           Data.Aeson
+import qualified Data.HashMap.Strict as H
+import qualified Data.Text           as T
+
+data Token = Tag T.Text | Literal T.Text deriving (Show,Eq)
+
+data Template = Template { content :: [Token] } deriving (Show,Eq)
+
+data Context = Context { variables :: H.HashMap T.Text T.Text } deriving (Show,Eq)
+
+instance ToJSON Context where
+    toJSON (Context h) = object $ (\(k,v) -> (k,String v)) <$> H.toList h
+
+instance FromJSON Context where
+    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 | Partial { template :: Template, tags :: [Tag]}  deriving (Show,Eq)
+
diff --git a/tests/hspec.hs b/tests/hspec.hs
new file mode 100644
--- /dev/null
+++ b/tests/hspec.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE BangPatterns #-}
+
+import           Data.Either.Combinators (fromRight')
+import qualified Data.HashMap.Strict     as H
+import           Data.Maybe
+import           Data.Text
+import           System.Directory        (removeFile)
+import           Test.Hspec
+import           Text.Glabrous
+import           Text.Glabrous.Types
+
+variablesList :: [(Text,Text)]
+variablesList = [("ipsum","IPSUM"),("lobortis","LOBORTIS"),("condimentum","CONDIMENTUM"),("maximus","MAXIMUS"),("sagittis","SAGITTIS"),("vestibulum","VESTIBULUM"),("cursus","CURSUS"),("vehicula","VEHICULA"),("faucibus","FAUCILUS"),("vitae","VITAE"),("tellus","TELLUS"),("lectus","LECTUS")]
+
+templateFile :: FilePath
+templateFile = "./tests/template"
+
+template' :: Template
+template' = fromRight' $ fromText "Affirmanti incumbit probatio. Lorem {{dolor}} sit amet, {{consectetur}} adipiscing elit. Proin bibendum mauris {{vitae}} dui venenatis pretium. Maecenas vestibulum justo at accumsan {{mattis}}. Nulla id finibus sem. Cras dolor nunc, consectetur in tincidunt id, facilisis in lorem. Nullam sed eros venenatis, tempor felis in, ultrices enim. Donec sit amet ligula ac orci cursus finibus ut eget lectus. Praesent feugiat massa non mi venenatis {{faucibus}}. Fabricando fit faber."
+
+context' :: Context
+context' = fromList [("dolor"," Dolor! "),("consectetur"," Consectetur! "),("vitae"," Vitae! "),("mattis"," Mattis! "),("faucibus"," Faucibus! ")]
+
+pcontext :: Context
+pcontext = fromList [("dolor"," Dolor! "),("vitae"," Vitae! "),("faucibus"," Faucibus! ")]
+
+contextFile :: FilePath
+contextFile = "./tests/template.json"
+
+clean :: IO ()
+clean = removeFile contextFile
+
+main :: IO ()
+main = hspec $ do
+
+    describe "readTemplateFile" $
+        it "loads a template from a file" $ do
+            readTemplateFile "./tests/template" `shouldReturn` Right (Template {content = [Literal "Affirmanti incumbit probatio. Lorem ",Tag "ipsum",Literal " dolor sit amet, consectetur adipiscing elit. Proin bibendum mauris vitae dui venenatis pretium. Maecenas vestibulum justo at accumsan mattis. Nulla id finibus sem. Cras dolor nunc, consectetur in tincidunt id, facilisis in lorem. Nullam sed eros venenatis, tempor felis in, ultrices enim. Donec sit amet ligula ac orci cursus finibus ut eget lectus. Praesent feugiat massa non mi venenatis faucibus. Proin sollicitudin ultrices sapien, eu venenatis purus sollicitudin vel. Donec maximus id ligula in ",Literal "{",Literal "congue",Literal "}",Literal ". Ut neque erat, dictum vehicula justo vel, dapibus facilisis est. Proin elementum finibus magna. Maecenas varius ultrices arcu, et auctor lectus egestas nec. Nulla facilisi. Donec eros urna, mattis viverra dapibus et, aliquet vel ",Tag "tortor",Literal ". Etiam rutrum lacinia turpis, vitae faucibus nibh pharetra gravida.\n\nVivamus venenatis nec sapien eu rutrum. Mauris ",Tag "lectus",Literal " tortor, suscipit eget tristique in, finibus a augue. Nulla euismod fermentum ligula, eget viverra eros porttitor eget. Integer lacinia id libero vitae laoreet. Vivamus sit amet molestie mi, in posuere diam. Nulla ornare luctus diam, at sodales neque porta ac. Nunc mi lectus, imperdiet in lorem pretium, volutpat ",Tag "vehicula",Literal " sem. Aliquam quis orci eu nisl consequat bibendum. Fusce efficitur ",Tag "bibendum",Literal " tristique. Integer lacinia turpis sit amet neque imperdiet tempor. Aenean ",Literal "{",Literal "dolor",Literal "}}",Literal " odio, congue sed lorem nec, ",Tag "condimentum",Literal " tempor lorem. Ut maximus lorem in augue tincidunt, nec dapibus erat luctus. Vivamus varius vitae lacus sed elementum. Nulla feugiat porttitor dictum. Donec posuere nisl at tincidunt gravida. Fusce semper maximus metus sit amet tempus. Quisque tempus neque ligula, efficitur molestie quam convallis vel. Donec porttitor rutrum ",Tag "tellus",Literal ", vel faucibus felis dapibus at. Mauris id tortor ",Tag "faucibus",Literal ", tempus velit sit amet, pretium tellus. Aliquam luctus mauris dui,",Tag "cursus",Literal " volutpat quam egestas vel. In vel neque eu eros efficitur aliquam. Donec efficitur tortor massa. Praesent molestie enim justo, ac gravida enim tristique nec. In non rutrum mi. Morbi viverra, mi vestibulum gravida iaculis, nulla ipsum fringilla nisl, at vestibulum nisl neque at est. Proin viverra varius nisi, quis tincidunt odio suscipit nec. Vestibulum nisi justo, fermentum ",Tag "commodo",Literal " accumsan id, dictum dictum felis. Fusce rutrum suscipit urna in ornare. Duis volutpat arcu et rutrum pulvinar. Vestibulum mattis scelerisque ligula, ut fermentum ligula. Fusce ut semper ipsum, at ",Tag "vestibulum",Literal " felis. Ut semper turpis sit amet diam commodo bibendum. Ut vulputate quam nec massa pretium, vitae sodales quam ultrices. Fusce imperdiet mi sed maximus ",Tag "lobortis",Literal ". Donec nulla quam, luctus a placerat vel, scelerisque et lacus. Nulla sagittis ipsum ac viverra eleifend. Praesent et sem ut erat ornare rutrum. Praesent ullamcorper dolor nunc, nec aliquam massa varius sed.\n\nUt luctus ante ut venenatis blandit. Aenean cursus leo non finibus cursus. Suspendisse sed enim hendrerit neque ",Tag "fermentum",Literal " rutrum eu ut nulla. Curabitur consequat orci quam, et condimentum lacus rutrum interdum. In in ",Tag "maximus",Literal " eros. Duis rhoncus nisi at volutpat aliquam. Quisque vestibulum ",Tag "venenatis",Literal " nisi, sed ",Tag "sagittis",Literal " est ultrices ut. Morbi quis ipsum ",Tag "vitae",Literal " erat mollis egestas nec viverra diam. Aenean imperdiet vestibulum risus vel bibendum. Aenean eget augue luctus, congue erat vel, hendrerit nunc. Ut metus risus, viverra non varius in, ",Tag "rhoncus",Literal " sed. Fabricando fit faber.\n"]})
+
+    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"]
+
+    describe "fromTemplate" $
+        it "builds a Context from a template" $
+            fromTemplate <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` Context {variables = H.fromList [("ipsum",""),("lobortis",""),("condimentum",""),("maximus",""),("sagittis",""),("vestibulum",""),("cursus",""),("vehicula",""),("faucibus",""),("vitae",""),("tellus",""),("lectus",""),("tortor",""),("commodo",""),("fermentum",""),("ipsum",""),("rhoncus",""),("bibendum",""),("venenatis","")]}
+
+    describe "setVariables" $
+        it "populates and/or updates a Context" $
+            setVariables variablesList <$> fromTemplate <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` Context {variables = H.fromList [("ipsum","IPSUM"),("lobortis","LOBORTIS"),("condimentum","CONDIMENTUM"),("maximus","MAXIMUS"),("sagittis","SAGITTIS"),("vestibulum","VESTIBULUM"),("cursus","CURSUS"),("vehicula","VEHICULA"),("faucibus","FAUCILUS"),("vitae","VITAE"),("tellus","TELLUS"),("lectus","LECTUS"),("tortor",""),("commodo",""),("fermentum",""),("rhoncus",""),("bibendum",""),("venenatis","")]}
+
+    describe "initContextFile" $
+        it "creates an empty of value context file" $
+            fromTemplate <$> fromRight' <$> readTemplateFile templateFile >>= initContextFile contextFile
+
+    describe "readContextFile" $
+        it "gets a context from a file" $
+            readContextFile contextFile `shouldReturn` Just (Context {variables = H.fromList [("lobortis",""),("condimentum",""),("maximus",""),("sagittis",""),("vestibulum",""),("cursus",""),("vehicula",""),("faucibus",""),("vitae",""),("tellus",""),("lectus",""),("tortor",""),("commodo",""),("fermentum",""),("ipsum",""),("rhoncus",""),("bibendum",""),("venenatis","")]})
+
+    describe "unsetContext" $
+        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 "writeContextFile" $ afterAll_ clean $
+        it "writes a context to a file" $ do
+            !acontext <- fromJust <$> readContextFile contextFile
+            writeContextFile contextFile acontext
+
+    describe "process" $
+        it "apply to a template a context to output a text" $
+            (return $ process template' context') `shouldReturn` "Affirmanti incumbit probatio. Lorem  Dolor!  sit amet,  Consectetur!  adipiscing elit. Proin bibendum mauris  Vitae!  dui venenatis pretium. Maecenas vestibulum justo at accumsan  Mattis! . Nulla id finibus sem. Cras dolor nunc, consectetur in tincidunt id, facilisis in lorem. Nullam sed eros venenatis, tempor felis in, ultrices enim. Donec sit amet ligula ac orci cursus finibus ut eget lectus. Praesent feugiat massa non mi venenatis  Faucibus! . Fabricando fit faber."
+
+    describe "partialProcess" $
+        it "apply to a template a context to output a template" $
+            (return $ partialProcess template' pcontext) `shouldReturn` Template {content = [Literal "Affirmanti incumbit probatio. Lorem ",Literal " Dolor! ",Literal " sit amet, ",Tag "consectetur",Literal " adipiscing elit. Proin bibendum mauris ",Literal " Vitae! ",Literal " dui venenatis pretium. Maecenas vestibulum justo at accumsan ",Tag "mattis",Literal ". Nulla id finibus sem. Cras dolor nunc, consectetur in tincidunt id, facilisis in lorem. Nullam sed eros venenatis, tempor felis in, ultrices enim. Donec sit amet ligula ac orci cursus finibus ut eget lectus. Praesent feugiat massa non mi venenatis ",Literal " Faucibus! ",Literal ". Fabricando fit faber."]}
+
+    describe "partialProcess'" $
+        it "apply to a template with a subcontext outputs a template with its tags" $
+            (return $ partialProcess' template' pcontext) `shouldReturn` Partial {template = Template {content = [Literal "Affirmanti incumbit probatio. Lorem ",Literal " Dolor! ",Literal " sit amet, ",Tag "consectetur",Literal " adipiscing elit. Proin bibendum mauris ",Literal " Vitae! ",Literal " dui venenatis pretium. Maecenas vestibulum justo at accumsan ",Tag "mattis",Literal ". Nulla id finibus sem. Cras dolor nunc, consectetur in tincidunt id, facilisis in lorem. Nullam sed eros venenatis, tempor felis in, ultrices enim. Donec sit amet ligula ac orci cursus finibus ut eget lectus. Praesent feugiat massa non mi venenatis ",Literal " Faucibus! ",Literal ". Fabricando fit faber."]}, tags = ["consectetur","mattis"]}
+
+    describe "partialProcess'" $
+        it "apply to a template with a context outputs a final text" $
+            (return $ partialProcess' template' context') `shouldReturn` Final "Affirmanti incumbit probatio. Lorem  Dolor!  sit amet,  Consectetur!  adipiscing elit. Proin bibendum mauris  Vitae!  dui venenatis pretium. Maecenas vestibulum justo at accumsan  Mattis! . Nulla id finibus sem. Cras dolor nunc, consectetur in tincidunt id, facilisis in lorem. Nullam sed eros venenatis, tempor felis in, ultrices enim. Donec sit amet ligula ac orci cursus finibus ut eget lectus. Praesent feugiat massa non mi venenatis  Faucibus! . Fabricando fit faber."
