packages feed

stache 2.2.1 → 2.3.0

raw patch · 10 files changed

+79/−73 lines, 10 filesdep ~optparse-applicative

Dependency ranges changed: optparse-applicative

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+## Stache 2.3.0++* Allowed parsing a wider range of keys in the templates thus making the+  library's behavior closer to other existing implementations.+ ## Stache 2.2.1  * Works with GHC 9.0.1, dropped support for GHC 8.6.x and older.
README.md view
@@ -8,22 +8,20 @@  This is a Haskell implementation of Mustache templates. The implementation conforms to the version 1.1.3 of the official [Mustache-specification](https://github.com/mustache/spec). It is extremely simple and-straightforward to use with minimal but complete API—three functions to-compile templates (from directory, from file, and from lazy text) and one to-render them.+specification](https://github.com/mustache/spec). It has a minimal but+complete API—three functions to compile templates (from directory, from+file, and from lazy text) and one to render them.  The implementation uses the Megaparsec parsing library to parse the-templates which results in superior quality of error messages.+templates which results in high-quality error messages. -For rendering you only need to create Aeson's `Value` where you put the data-to interpolate. Since the library re-uses Aeson's instances and most data-types in the Haskell ecosystem are instances of classes like-`Data.Aeson.ToJSON`, the whole process is very simple for the end user.+For rendering one only needs to create Aeson's `Value` that is used for+interpolation of template variables. Since the library re-uses Aeson's+instances and most data types in the Haskell ecosystem are instances of+classes like `Data.Aeson.ToJSON`, the process is simple for the end user.  Template Haskell helpers for compilation of templates at compile time are-available in the `Text.Mustache.Compile.TH` module. The helpers currently-work only with GHC 8 and later.+available in the `Text.Mustache.Compile.TH` module.  One feature that is not currently supported is lambdas. The feature is marked as optional in the spec and can be emulated via processing of parsed
Text/Mustache.hs view
@@ -8,24 +8,22 @@ -- Portability :  portable -- -- This is a Haskell implementation of Mustache templates. The--- implementation conforms to the version 1.1.3 of official Mustache--- specification <https://github.com/mustache/spec>. It is extremely simple--- and straightforward to use with minimal but complete API—three functions--- to compile templates (from directory, from file, and from lazy text) and--- one to render them.+-- implementation conforms to the version 1.1.3 of the official Mustache+-- specification <https://github.com/mustache/spec>. It has a minimal but+-- complete API—three functions to compile templates (from directory, from+-- file, and from lazy text) and one to render them. -- -- The implementation uses Megaparsec parsing library to parse the templates--- which results in superior quality of error messages.+-- which results in high-quality error messages. ----- For rendering you only need to create Aeson's 'Data.Aeson.Value' where--- you put the data to interpolate. Since the library re-uses Aeson's--- instances and most data types in the Haskell ecosystem are instances of--- classes like 'Data.Aeson.ToJSON', the whole process is very simple for+-- For rendering you only need to create Aeson's 'Data.Aeson.Value' that is+-- used for interpolation of template variables. Since the library re-uses+-- Aeson's instances and most data types in the Haskell ecosystem are+-- instances of classes like 'Data.Aeson.ToJSON', the process is simple for -- the end user. -- -- Template Haskell helpers for compilation of templates at compile time are--- available in the "Text.Mustache.Compile.TH" module. The helpers currently--- work only with GHC 8 and later.+-- available in the "Text.Mustache.Compile.TH" module. -- -- One feature that is not currently supported is lambdas. The feature is -- marked as optional in the spec and can be emulated via processing of
Text/Mustache/Compile.hs view
@@ -34,9 +34,10 @@ import Text.Mustache.Parser import Text.Mustache.Type --- | Compile all templates in specified directory and select one. Template--- files should have the extension @mustache@, (e.g. @foo.mustache@) to be--- recognized. This function /does not/ scan the directory recursively.+-- | Compile all templates in the specified directory and select one.+-- Template files should have the extension @mustache@, (e.g.+-- @foo.mustache@) to be recognized. This function /does not/ scan the+-- directory recursively. -- -- Note that each template\/partial will get an identifier which consists of -- the name of corresponding template file with extension @.mustache@@@ -80,8 +81,8 @@       Template _ new <- compileMustacheFile fp       return (Template undefined (M.union new old)) --- | Return a list of templates found in given directory. The returned paths--- are absolute.+-- | Return a list of templates found in given a directory. The returned+-- paths are absolute. -- -- @since 0.2.2 getMustacheFilesInDir ::@@ -91,8 +92,8 @@   m [FilePath] getMustacheFilesInDir = getMustacheFilesInDir' isMustacheFile --- | Return a list of templates found via a predicate in given directory.--- The returned paths are absolute.+-- | Return a list of templates that satisfy a predicate in a given+-- directory. The returned paths are absolute. -- -- @since 1.2.0 getMustacheFilesInDir' ::@@ -116,7 +117,7 @@ isMustacheFile :: FilePath -> Bool isMustacheFile path = F.takeExtension path == ".mustache" --- | Compile a single Mustache template and select it.+-- | Compile a Mustache template and select it. -- -- The action can throw 'MustacheParserException' and the same exceptions as -- 'T.readFile'.@@ -132,7 +133,7 @@     pname = pathToPName path     compile = fmap (Template pname . M.singleton pname) . parseMustache path --- | Compile Mustache template from a lazy 'Text' value. The cache will+-- | Compile a Mustache template from a lazy 'Text' value. The cache will -- contain only this template named according to given 'PName'. compileMustacheText ::   -- | How to name the template?@@ -147,12 +148,12 @@ ---------------------------------------------------------------------------- -- Helpers --- | Build a 'PName' from given 'FilePath'.+-- | Build a 'PName' from a given 'FilePath'. pathToPName :: FilePath -> PName pathToPName = PName . T.pack . F.takeBaseName --- | Throw 'MustacheException' if argument is 'Left' or return the result--- inside 'Right'.+-- | Throw 'MustacheException' if the argument is 'Left' or return the+-- result inside 'Right'. withException ::   -- | Value to process   Either (ParseErrorBundle Text Void) Template ->
Text/Mustache/Compile/TH.hs view
@@ -14,9 +14,6 @@ -- Template Haskell helpers to compile Mustache templates at compile time. -- This module is not imported as part of "Text.Mustache", so you need to -- import it yourself. Qualified import is recommended, but not necessary.------ At the moment, functions in this module only work with GHC 8 (they--- require at least @template-haskell-2.11@). module Text.Mustache.Compile.TH   ( compileMustacheDir,     compileMustacheDir',@@ -36,9 +33,10 @@ import qualified Text.Mustache.Compile as C import Text.Mustache.Type --- | Compile all templates in specified directory and select one. Template--- files should have the extension @mustache@, (e.g. @foo.mustache@) to be--- recognized. This function /does not/ scan the directory recursively.+-- | Compile all templates in the specified directory and select one.+-- Template files should have the extension @mustache@, (e.g.+-- @foo.mustache@) to be recognized. This function /does not/ scan the+-- directory recursively. -- -- This version compiles the templates at compile time. --@@ -71,7 +69,7 @@   runIO (C.getMustacheFilesInDir' predicate path) >>= mapM_ addDependentFile   (runIO . try) (C.compileMustacheDir' predicate pname path) >>= handleEither --- | Compile single Mustache template and select it.+-- | Compile a Mustache template and select it. -- -- This version compiles the template at compile time. compileMustacheFile ::@@ -82,7 +80,7 @@   runIO (makeAbsolute path) >>= addDependentFile   (runIO . try) (C.compileMustacheFile path) >>= handleEither --- | Compile Mustache template from 'Text' value. The cache will contain+-- | Compile a Mustache template from 'Text' value. The cache will contain -- only this template named according to given 'Key'. -- -- This version compiles the template at compile time.@@ -96,7 +94,7 @@   (handleEither . either (Left . MustacheParserException) Right)     (C.compileMustacheText pname text) --- | Compile Mustache using QuasiQuoter. Usage:+-- | Compile a Mustache using a QuasiQuoter. Usage: -- -- > {-# LANGUAGE QuasiQuotes #-} -- > import Text.Mustache.Compile.TH (mustache)@@ -126,10 +124,6 @@     Left err -> (fail . indentNicely . displayException) err     Right template -> lift template   where-    -- NOTE Since the feature requires GHC 8 anyway, we follow the-    -- indentation style of that version of compiler. This makes it look-    -- consistent with other error messages and allows Emacs and similar-    -- tools to parse the errors correctly.     indentNicely x' =       case lines x' of         [] -> ""
Text/Mustache/Parser.hs view
@@ -19,9 +19,9 @@  import Control.Monad import Control.Monad.State.Strict-import Data.Char (isAlphaNum, isSpace)+import Data.Char (isSpace) import Data.Maybe (catMaybes)-import Data.Text (Text)+import Data.Text (Text, stripEnd) import qualified Data.Text as T import Data.Void import Text.Megaparsec@@ -155,9 +155,14 @@ pKey = (fmap Key . lexeme . label "key") (implicit <|> other)   where     implicit = [] <$ char '.'-    other = sepBy1 (takeWhile1P (Just lbl) f) (char '.')-    lbl = "alphanumeric char or '-' or '_'"-    f x = isAlphaNum x || x == '-' || x == '_'+    other = do+      end <- gets closingDel+      let f x = x `notElem` ('.' : '}' : T.unpack end)+          lbl = "key-constituent characters"+      stripLast <$> sepBy1 (takeWhile1P (Just lbl) f) (char '.')+    stripLast [] = []+    stripLast [x] = [stripEnd x]+    stripLast (x0 : x1 : xs) = x0 : stripLast (x1 : xs) {-# INLINE pKey #-}  pDelimiter :: Parser Text
Text/Mustache/Render.hs view
@@ -39,9 +39,9 @@ ---------------------------------------------------------------------------- -- The rendering monad --- | Synonym for the monad we use for rendering. It allows to share context--- and accumulate the result as 'B.Builder' data which is then turned into a--- lazy 'TL.Text'.+-- | Synonym for the monad we use for rendering. It allows us to share+-- context and accumulate the result as 'B.Builder' data which is then+-- turned into a lazy 'TL.Text'. type Render a = ReaderT RenderContext (State S) a  data S = S ([MustacheWarning] -> [MustacheWarning]) B.Builder
Text/Mustache/Type.hs view
@@ -43,17 +43,17 @@ import qualified Language.Haskell.TH.Syntax as TH import Text.Megaparsec --- | Mustache template as name of “top-level” template and a collection of--- all available templates (partials).+-- | Mustache template as the name of the “top-level” template and a+-- collection of all available templates (partials). -- -- 'Template' is a 'Semigroup'. This means that you can combine 'Template's -- (and their caches) using the @('<>')@ operator, the resulting 'Template' -- will have the same currently selected template as the left one. Union of -- caches is also left-biased. data Template = Template-  { -- | Name of currently “selected” template (top-level one).+  { -- | The name of the currently “selected” template.     templateActual :: PName,-    -- | Collection of all templates that are available for interpolation+    -- | A collection of all templates that are available for interpolation     -- (as partials). The top-level one is also contained here and the     -- “focus” can be switched easily by modifying 'templateActual'.     templateCache :: Map PName [Node]@@ -73,7 +73,7 @@   liftTyped = TH.unsafeTExpCoerce . TH.lift #endif --- | Structural element of template.+-- | A structural element of a template. data Node   = -- | Plain text contained between tags     TextBlock Text@@ -121,7 +121,7 @@   liftTyped = TH.unsafeTExpCoerce . TH.lift #endif --- | Pretty-print a key, this is helpful, for example, if you want to+-- | Pretty-print a key. This is helpful, for example, if you want to -- display an error message. -- -- @since 0.2.0@@ -167,8 +167,8 @@ -- -- @since 1.1.1 data MustacheWarning-  = -- | The template contained a variable for which there was no data-    -- counterpart in the current context.+  = -- | The template contained a variable for which there was no data in+    -- the current context.     MustacheVariableNotFound Key   | -- | A complex value such as an 'Object' or 'Array' was directly     -- rendered into the template.
stache.cabal view
@@ -1,6 +1,6 @@ cabal-version:   1.18 name:            stache-version:         2.2.1+version:         2.3.0 license:         BSD3 license-file:    LICENSE.md maintainer:      Mark Karpov <markkarpov92@gmail.com>@@ -109,7 +109,7 @@         hspec >=2.0 && <3.0,         hspec-megaparsec >=2.0 && <3.0,         megaparsec >=7.0 && <10.0,-        stache -any,+        stache,         template-haskell >=2.11 && <2.18,         text >=1.2 && <1.3 @@ -129,10 +129,10 @@         base >=4.13 && <5.0,         bytestring >=0.10 && <0.12,         containers >=0.5 && <0.7,-        file-embed -any,+        file-embed,         hspec >=2.0 && <3.0,         megaparsec >=7.0 && <10.0,-        stache -any,+        stache,         text >=1.2 && <1.3,         yaml >=0.8 && <0.12 @@ -153,7 +153,7 @@         criterion >=0.6.2.1 && <1.6,         deepseq >=1.4 && <1.5,         megaparsec >=7.0 && <10.0,-        stache -any,+        stache,         text >=1.2 && <1.3      if flag(dev)
tests/Text/Mustache/ParserSpec.hs view
@@ -30,6 +30,10 @@         p "{{{ name }}}" `shouldParse` [UnescapedVar (key "name")]       it "parses unescaped {{& variable }}" $         p "{{& name }}" `shouldParse` [UnescapedVar (key "name")]+      it "parses escaped {{ nested.variable }}" $+        p "{{ a.b }}" `shouldParse` [EscapedVar (Key ["a", "b"])]+      it "parses escaped {{ nested . variable . with . spaces }}" $+        p "{{   a . b . c   }}" `shouldParse` [EscapedVar (Key ["a ", " b ", " c"])]     context "without white space" $ do       it "parses escaped {{variable}}" $         p "{{name}}" `shouldParse` [EscapedVar (key "name")]@@ -87,9 +91,10 @@       p "{{#section}}{{=<< >>=}}<</section>><<var>>"         `shouldParse` [Section (key "section") [], EscapedVar (key "var")]   context "when given malformed input" $ do+    let keyConstErr = "key-constituent characters"     it "rejects unclosed tags" $ do       let s = "{{ name "-      p s `shouldFailWith` err 8 (ueof <> etoks "}}")-    it "rejects unknown tags" $ do-      let s = "{{? boo }}"-      p s `shouldFailWith` err 2 (utoks "?" <> elabel "key")+      p s `shouldFailWith` err 8 (ueof <> etoks "}}" <> etok '.' <> elabel keyConstErr)+    it "rejects il-formed expressions" $ do+      let s = "{{ foo..bar }}"+      p s `shouldFailWith` err 7 (utoks "." <> elabel keyConstErr)