marvin-interpolate 0.1.0 → 0.2.0
raw patch · 7 files changed
+162/−37 lines, 7 filesdep ~marvin-interpolatePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: marvin-interpolate
API changes (from Hackage documentation)
- Marvin.Interpolate: i :: QuasiQuoter
- Marvin.Interpolate.String: iS :: QuasiQuoter
- Marvin.Interpolate.Text: iT :: QuasiQuoter
- Marvin.Interpolate.Text.Lazy: iLT :: QuasiQuoter
+ Marvin.Interpolate: iq :: QuasiQuoter
+ Marvin.Interpolate.String: iqS :: QuasiQuoter
+ Marvin.Interpolate.Text: iqT :: QuasiQuoter
+ Marvin.Interpolate.Text.Lazy: iqLT :: QuasiQuoter
Files
- marvin-interpolate.cabal +3/−3
- src/Marvin/Interpolate.hs +39/−9
- src/Marvin/Interpolate/All.hs +11/−0
- src/Marvin/Interpolate/String.hs +31/−3
- src/Marvin/Interpolate/Text.hs +31/−3
- src/Marvin/Interpolate/Text/Lazy.hs +31/−3
- test/Spec.hs +16/−16
marvin-interpolate.cabal view
@@ -1,5 +1,5 @@ name: marvin-interpolate-version: 0.1.0+version: 0.2.0 cabal-version: >=1.10 build-type: Simple license: BSD3@@ -9,7 +9,7 @@ homepage: http://marvin.readthedocs.io/en/latest/interpolation.html synopsis: Compile time string interpolation a la Scala and CoffeeScript description:- The official documentation can be found on readthedocs https://marvin.readthedocs.io/en/latest/interpolation.html+ The official documentation can be found on readthedocs <https://marvin.readthedocs.io/en/latest/interpolation.html> category: Text author: JustusAdam extra-source-files:@@ -43,7 +43,7 @@ main-is: Spec.hs build-depends: base >=4.9.0.0 && <4.10,- marvin-interpolate >=0.1.0 && <0.2,+ marvin-interpolate >=0.2.0 && <0.3, hspec >=2.2.4 && <2.3 default-language: Haskell2010 hs-source-dirs: test
src/Marvin/Interpolate.hs view
@@ -1,10 +1,20 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE MultiWayIf #-}+{-|+Module : $Header$+Description : Interpolation core module+Copyright : (c) Justus Adam, 2016+License : BSD3+Maintainer : dev@justus.science+Stability : experimental+Portability : POSIX++Please refer to the documentation at https://marvin.readthedocs.io/en/latest/interpolation.html for examples and explanations on how to use this library.+-} {-# LANGUAGE TemplateHaskell #-} module Marvin.Interpolate- ( interpolateInto- , is- , i+ ( is+ , iq+ -- * Internals/extension points+ , interpolateInto ) where @@ -39,7 +49,7 @@ parseTillEscape :: String -> Bool -> Parsec String () String parseTillEscape endSeq@(endChar:_) allowEOF = do chunk <- many $ noneOf [escapeChar, endChar]- !rest <- eofEND+ rest <- eofEND <|> (char escapeChar >> parseEscaped) <|> (lookAhead (try $ string endSeq) >> return "") <|> (return <$> char endChar)@@ -77,6 +87,17 @@ return $ Left name +-- | Common core of all interpolators.+--+-- @interpolateInto exp str@ parses @str@ as the interpolated string and returns an 'Exp' which looks like +-- +-- @+-- "str" \`mappend\` exp1 \`mappend\` "str" \`mappend\` exp2 \`mappend\` "str"+-- @ +-- +-- where @exp1@ and @exp2@ are the interpolated expressions with @exp@ prepended.+-- The intended use of @exp@ is to unifomly convert the interpolated expressions into a desired string type.+-- Typically @exp@ will be something like @('VarE' \'convert)@ were @convert@ is some member function of a conversion type class. interpolateInto :: Exp -> String -> Exp interpolateInto converter str = foldl f (LitE (StringL "")) interleaved@@ -91,10 +112,19 @@ Right str -> LitE (StringL str) Left expr2 -> AppE converter expr2 -+-- | __i__nterpolate __s__plice +--+-- Template Haskell splice function, used like @$(is "my str %{expr}")@+-- +-- Performs no conversion on interpolated expressions like @expr@. is :: String -> Q Exp is = return . interpolateInto (VarE 'id) -i :: QuasiQuoter-i = mqq { quoteExp = is }+-- | __i__nterpolate __q__uoter+--+-- QuasiQuoter, used like @[i|my str %{expr}|]@+--+-- Performs no conversion on interpolated expressions like @expr@.+iq :: QuasiQuoter+iq = mqq { quoteExp = is }
src/Marvin/Interpolate/All.hs view
@@ -1,3 +1,14 @@+{-|+Module : $Header$+Description : Combined interpolators+Copyright : (c) Justus Adam, 2016+License : BSD3+Maintainer : dev@justus.science+Stability : experimental+Portability : POSIX++Please refer to the documentation at https://marvin.readthedocs.io/en/latest/interpolation.html for examples and explanations on how to use this library.+-} module Marvin.Interpolate.All ( module Marvin.Interpolate , module Marvin.Interpolate.String
src/Marvin/Interpolate/String.hs view
@@ -1,8 +1,23 @@+{-|+Module : $Header$+Description : Interpolation and automatic conversion to String+Copyright : (c) Justus Adam, 2016+License : BSD3+Maintainer : dev@justus.science+Stability : experimental+Portability : POSIX++Please refer to the documentation at https://marvin.readthedocs.io/en/latest/interpolation.html for examples and explanations on how to use this library.+-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UndecidableInstances #-}-module Marvin.Interpolate.String where+module Marvin.Interpolate.String+ ( isS, iqS+ -- * Conversion class+ , ShowStr(..)+ ) where import Data.List@@ -15,6 +30,9 @@ import Util +-- | A type class for converting things to 'String'+--+-- Leaves string likes ('String', 'T.Text' and 'L.Text') unchanged, and tries 'Show' (overlappable) on all others. class ShowStr a where showStr :: a -> String showListStr :: [a] -> String@@ -34,9 +52,19 @@ showStr = show +-- | __i__nterpolate __s__plice to __S__tring+--+-- Template Haskell splice function, used like @$(isS "my str %{expr}")@+-- +-- converts all expressions to 'String' by calling 'showStr' on the result. isS :: String -> Q Exp isS = return . interpolateInto (VarE 'show) -iS :: QuasiQuoter-iS = mqq { quoteExp = isS }+-- | __i__nterpolate __q__uoter to __S__tring+--+-- QuasiQuoter, used like @[iS|my str %{expr}|]@+--+-- converts all expressions to 'String' by calling 'showStr' on the result.+iqS :: QuasiQuoter+iqS = mqq { quoteExp = isS }
src/Marvin/Interpolate/Text.hs view
@@ -1,8 +1,23 @@+{-|+Module : $Header$+Description : Interpolation and automatic conversion to Text+Copyright : (c) Justus Adam, 2016+License : BSD3+Maintainer : dev@justus.science+Stability : experimental+Portability : POSIX++Please refer to the documentation at https://marvin.readthedocs.io/en/latest/interpolation.html for examples and explanations on how to use this library.+-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UndecidableInstances #-}-module Marvin.Interpolate.Text where+module Marvin.Interpolate.Text + ( isT, iqT+ -- * Conversion class+ , ShowT(..)+ ) where import Data.Monoid@@ -14,6 +29,9 @@ import Util +-- | A type class for converting things to 'Text'+--+-- Leaves string likes ('String', 'Text' and 'L.Text') unchanged, tries 'Show' (overlappable) on all others. class ShowT a where showT :: a -> Text showListT :: [a] -> Text@@ -33,9 +51,19 @@ showT = pack . show +-- | __i__nterpolate __s__plice to __T__ext+--+-- Template Haskell splice function, used like @$(isT "my str %{expr}")@+-- +-- converts all expressions to 'Text' by calling 'showT' on the result. isT :: String -> Q Exp isT = return . interpolateInto (VarE 'showT) -iT :: QuasiQuoter-iT = mqq { quoteExp = isT }+-- | __i__nterpolate __q__uoter to __T__ext+--+-- QuasiQuoter, used like @[iT|my str %{expr}|]@+--+-- converts all expressions to 'Text' by calling 'showT' on the result.+iqT :: QuasiQuoter+iqT = mqq { quoteExp = isT }
src/Marvin/Interpolate/Text/Lazy.hs view
@@ -1,8 +1,23 @@+{-|+Module : $Header$+Description : Interpolation and automatic conversion to lazy Text+Copyright : (c) Justus Adam, 2016+License : BSD3+Maintainer : dev@justus.science+Stability : experimental+Portability : POSIX++Please refer to the documentation at https://marvin.readthedocs.io/en/latest/interpolation.html for examples and explanations on how to use this library.+-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UndecidableInstances #-}-module Marvin.Interpolate.Text.Lazy where+module Marvin.Interpolate.Text.Lazy+ ( isLT, iqLT+ -- * Conversion class+ , ShowLT(..)+ ) where import Data.Monoid@@ -14,6 +29,9 @@ import Util +-- | A type class for converting things to 'L.Text'+--+-- Leaves string likes ('String', 'T.Text' and 'L.Text') unchanged, tries 'Show' (overlappable) on all others. class ShowLT a where showLT :: a -> L.Text showListLT :: [a] -> L.Text@@ -33,9 +51,19 @@ showLT = L.pack . show +-- | __i__nterpolate __s__plice to __L__azy __T__ext+--+-- Template Haskell splice function, used like @$(isLT "my str %{expr}")@+-- +-- converts all expressions to 'L.Text' by calling 'showLT' on the result. isLT :: String -> Q Exp isLT = return . interpolateInto (VarE 'showLT) -iLT :: QuasiQuoter-iLT = mqq { quoteExp = isLT }+-- | __i__nterpolate __q__uoter to __L__azy __T__ext+--+-- QuasiQuoter, used like @[iLT|my str %{expr}|]@+--+-- converts all expressions to 'L.Text' by calling 'showLT' on the result.+iqLT :: QuasiQuoter+iqLT = mqq { quoteExp = isLT }
test/Spec.hs view
@@ -11,53 +11,53 @@ formatSpec = do describe "parsing to itself" $ do it "%" $- [i|%|] `shouldBe` "%"+ [iq|%|] `shouldBe` "%" it "%anything" $- [i|%anything|] `shouldBe` "%anything"+ [iq|%anything|] `shouldBe` "%anything" it "~" $- [i|~|] `shouldBe` "~"+ [iq|~|] `shouldBe` "~" it "~anything" $ $(is "~anything") `shouldBe` "~anything" describe "parsing escape sequences" $ do it "parses ~% as %" $- [i|~%|] `shouldBe` "%"+ [iq|~%|] `shouldBe` "%" it "parses ~] as ]" $- [i|~]|] `shouldBe` "]"+ [iq|~]|] `shouldBe` "]" it "parses ~%{} as %{}" $- [i|~%{}|] `shouldBe` "%{}"+ [iq|~%{}|] `shouldBe` "%{}" it "parses |~] as |]" $- [i||~]|] `shouldBe` "|]"+ [iq||~]|] `shouldBe` "|]" it "parses ~~ as ~" $- [i|~~|] `shouldBe` "~"+ [iq|~~|] `shouldBe` "~" describe "interpolation substitution" $ do it "leaves an empty string" $- [i||] `shouldBe` ""+ [iq||] `shouldBe` "" it "returns a string unchanged if no variable is in it" $- [i|this is not changed|] `shouldBe` "this is not changed"+ [iq|this is not changed|] `shouldBe` "this is not changed" it "interpolates just an external variable" $ let y = "str" in- [i|%{y}|] `shouldBe` y+ [iq|%{y}|] `shouldBe` y it "interpolates an external variable" $- let y = "str2" in [i| hello you %{y} end|] `shouldBe` " hello you " ++ y ++ " end"+ let y = "str2" in [iq| hello you %{y} end|] `shouldBe` " hello you " ++ y ++ " end" it "interpolates the variable x (used to be special)" $- let x = "str" in [i| hello x: %{x}|] `shouldBe` " hello x: " ++ x+ let x = "str" in [iq| hello x: %{x}|] `shouldBe` " hello x: " ++ x it "interpolates infix with $" $- [i|str %{show $ 4 + (5 :: Int)} str|] `shouldBe` "str 9 str"+ [iq|str %{show $ 4 + (5 :: Int)} str|] `shouldBe` "str 9 str" it "interpolates multiple bindings" $ let x = "multiple" y = "can" z = "local scope"- in [i|We %{y} interpolate %{x} bindings from %{z}|]+ in [iq|We %{y} interpolate %{x} bindings from %{z}|] `shouldBe` "We can interpolate multiple bindings from local scope" it "interpolates complex expressions" $ let x = ["haskell", "expression"] y = " can be"- in [i|Any %{intercalate " " x ++ y} interpolated|]+ in [iq|Any %{intercalate " " x ++ y} interpolated|] `shouldBe` "Any haskell expression can be interpolated"