packages feed

text-format-heavy 0.1.4.0 → 0.1.5.0

raw patch · 10 files changed

+122/−14 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.Text.Format.Heavy.Build: convertText :: Maybe Conversion -> Builder -> Builder
+ Data.Text.Format.Heavy.Formats: LowerCase :: Conversion
+ Data.Text.Format.Heavy.Formats: TitleCase :: Conversion
+ Data.Text.Format.Heavy.Formats: UpperCase :: Conversion
+ Data.Text.Format.Heavy.Formats: [gfConvert] :: GenericFormat -> Maybe Conversion
+ Data.Text.Format.Heavy.Formats: data Conversion
+ Data.Text.Format.Heavy.Formats: instance GHC.Classes.Eq Data.Text.Format.Heavy.Formats.Conversion
+ Data.Text.Format.Heavy.Formats: instance GHC.Show.Show Data.Text.Format.Heavy.Formats.Conversion
+ Data.Text.Format.Heavy.Instances: instance (Data.Text.Format.Heavy.Types.Formatable a, Data.Text.Format.Heavy.Types.Formatable b, Data.Text.Format.Heavy.Types.Formatable c, Data.Text.Format.Heavy.Types.Formatable d, Data.Text.Format.Heavy.Types.Formatable e, Data.Text.Format.Heavy.Types.Formatable f, Data.Text.Format.Heavy.Types.Formatable g, Data.Text.Format.Heavy.Types.Formatable h) => Data.Text.Format.Heavy.Types.VarContainer (a, b, c, d, e, f, g, h)
+ Data.Text.Format.Heavy.Instances: instance (Data.Text.Format.Heavy.Types.Formatable a, Data.Text.Format.Heavy.Types.Formatable b, Data.Text.Format.Heavy.Types.Formatable c, Data.Text.Format.Heavy.Types.Formatable d, Data.Text.Format.Heavy.Types.Formatable e, Data.Text.Format.Heavy.Types.Formatable f, Data.Text.Format.Heavy.Types.Formatable g, Data.Text.Format.Heavy.Types.Formatable h, Data.Text.Format.Heavy.Types.Formatable i) => Data.Text.Format.Heavy.Types.VarContainer (a, b, c, d, e, f, g, h, i)
+ Data.Text.Format.Heavy.Instances: instance (Data.Text.Format.Heavy.Types.Formatable a, Data.Text.Format.Heavy.Types.Formatable b, Data.Text.Format.Heavy.Types.Formatable c, Data.Text.Format.Heavy.Types.Formatable d, Data.Text.Format.Heavy.Types.Formatable e, Data.Text.Format.Heavy.Types.Formatable f, Data.Text.Format.Heavy.Types.Formatable g, Data.Text.Format.Heavy.Types.Formatable h, Data.Text.Format.Heavy.Types.Formatable i, Data.Text.Format.Heavy.Types.Formatable j) => Data.Text.Format.Heavy.Types.VarContainer (a, b, c, d, e, f, g, h, i, j)
+ Data.Text.Format.Heavy.Instances: type WithDefault c = ThenCheck c DefaultValue
+ Data.Text.Format.Heavy.Types: instance GHC.Classes.Eq Data.Text.Format.Heavy.Types.Format
+ Data.Text.Format.Heavy.Types: instance GHC.Classes.Eq Data.Text.Format.Heavy.Types.FormatItem
+ Data.Text.Format.Heavy.Types: instance GHC.Show.Show Data.Text.Format.Heavy.Types.Variable
- Data.Text.Format.Heavy.Formats: GenericFormat :: Char -> Maybe Align -> Sign -> Bool -> Maybe Int -> Maybe Int -> Maybe Radix -> GenericFormat
+ Data.Text.Format.Heavy.Formats: GenericFormat :: Char -> Maybe Align -> Sign -> Bool -> Maybe Int -> Maybe Int -> Maybe Radix -> Maybe Conversion -> GenericFormat
- Data.Text.Format.Heavy.Instances: optional :: VarContainer c => c -> ThenCheck c DefaultValue
+ Data.Text.Format.Heavy.Instances: optional :: VarContainer c => c -> WithDefault c
- Data.Text.Format.Heavy.Instances: withDefault :: VarContainer c => c -> Variable -> ThenCheck c DefaultValue
+ Data.Text.Format.Heavy.Instances: withDefault :: VarContainer c => c -> Variable -> WithDefault c

Files

Data/Text/Format/Heavy.hs view
@@ -38,5 +38,5 @@ import Data.Text.Format.Heavy.Types import Data.Text.Format.Heavy.Formats import Data.Text.Format.Heavy.Build (format)-import Data.Text.Format.Heavy.Instances (Single (..), Shown (..))+import Data.Text.Format.Heavy.Instances hiding (genericIntFormat, genericFloatFormat) 
Data/Text/Format/Heavy/Build.hs view
@@ -4,7 +4,7 @@   (format, formatEither,    makeBuilder,    -- * Formatters building utilities-   align, applySign, applySharp,+   align, applySign, applySharp, convertText,    formatInt, formatStr, formatFloat, formatBool   ) where @@ -77,6 +77,16 @@ applySharp True Decimal text = text applySharp True Hexadecimal text = B.fromLazyText "0x" <> text +-- | Apply text conversion.+convertText :: Maybe Conversion -> B.Builder -> B.Builder+convertText Nothing builder = builder+convertText (Just conv) builder = B.fromLazyText $ converter $ B.toLazyText builder+  where+    converter = case conv of+                  UpperCase -> TL.toUpper+                  LowerCase -> TL.toLower+                  TitleCase -> TL.toTitle+ -- | Format integer number according to GenericFormat formatInt :: Integral a => GenericFormat -> a -> B.Builder formatInt fmt x = align fmt $ applySign (gfSign fmt) x $ applySharp (gfLeading0x fmt) radix $ inRadix@@ -89,11 +99,14 @@ -- | Format floating-point number according to GenericFormat formatFloat :: RealFloat a => GenericFormat -> a -> B.Builder formatFloat fmt x =-  align fmt $ applySign (gfSign fmt) x $ formatRealFloat Fixed (gfPrecision fmt) $ abs x+    align fmt+    $ applySign (gfSign fmt) x+    $ formatRealFloat Fixed (gfPrecision fmt)+    $ abs x  -- | Format Text according to GenericFormat. formatStr :: GenericFormat -> TL.Text -> B.Builder-formatStr fmt text = align fmt $ B.fromLazyText text+formatStr fmt text = convertText (gfConvert fmt) $ align fmt $ B.fromLazyText text  -- | Format boolean value. formatBool :: BoolFormat -> Bool -> B.Builder
Data/Text/Format/Heavy/Formats.hs view
@@ -19,6 +19,13 @@ data Radix = Decimal | Hexadecimal   deriving (Eq, Show) +-- | Supported text conversions+data Conversion =+    UpperCase+  | LowerCase+  | TitleCase+  deriving (Eq, Show)+ -- | Generic format description. This is usable for integers, floats and strings. data GenericFormat = GenericFormat {     gfFillChar :: Char@@ -28,6 +35,7 @@   , gfWidth :: Maybe Int   , gfPrecision :: Maybe Int   , gfRadix :: Maybe Radix+  , gfConvert :: Maybe Conversion   }   deriving (Eq, Show) @@ -40,6 +48,7 @@         , gfWidth = Nothing         , gfPrecision = Nothing         , gfRadix = Nothing+        , gfConvert = Nothing         }  data BoolFormat = BoolFormat {
Data/Text/Format/Heavy/Instances.hs view
@@ -4,7 +4,7 @@   (-- * Utility data types    Single (..), Several (..), Shown (..),    -- * Combinators-   DefaultValue (..), ThenCheck (..),+   DefaultValue (..), ThenCheck (..), WithDefault,    withDefault, optional,    -- * Generic formatters    genericIntFormat, genericFloatFormat@@ -261,6 +261,48 @@   lookupVar "6" (_,_,_,_,_,_,g) = Just $ Variable g   lookupVar _ _ = Nothing +instance (Formatable a, Formatable b, Formatable c, Formatable d, Formatable e, Formatable f, Formatable g,+          Formatable h)+     => VarContainer (a, b, c, d, e, f, g, h) where+  lookupVar "0" (a,_,_,_,_,_,_,_) = Just $ Variable a+  lookupVar "1" (_,b,_,_,_,_,_,_) = Just $ Variable b+  lookupVar "2" (_,_,c,_,_,_,_,_) = Just $ Variable c+  lookupVar "3" (_,_,_,d,_,_,_,_) = Just $ Variable d+  lookupVar "4" (_,_,_,_,e,_,_,_) = Just $ Variable e+  lookupVar "5" (_,_,_,_,_,f,_,_) = Just $ Variable f+  lookupVar "6" (_,_,_,_,_,_,g,_) = Just $ Variable g+  lookupVar "7" (_,_,_,_,_,_,_,h) = Just $ Variable h+  lookupVar _ _ = Nothing++instance (Formatable a, Formatable b, Formatable c, Formatable d, Formatable e, Formatable f, Formatable g,+          Formatable h, Formatable i)+     => VarContainer (a, b, c, d, e, f, g, h, i) where+  lookupVar "0" (a,_,_,_,_,_,_,_,_) = Just $ Variable a+  lookupVar "1" (_,b,_,_,_,_,_,_,_) = Just $ Variable b+  lookupVar "2" (_,_,c,_,_,_,_,_,_) = Just $ Variable c+  lookupVar "3" (_,_,_,d,_,_,_,_,_) = Just $ Variable d+  lookupVar "4" (_,_,_,_,e,_,_,_,_) = Just $ Variable e+  lookupVar "5" (_,_,_,_,_,f,_,_,_) = Just $ Variable f+  lookupVar "6" (_,_,_,_,_,_,g,_,_) = Just $ Variable g+  lookupVar "7" (_,_,_,_,_,_,_,h,_) = Just $ Variable h+  lookupVar "8" (_,_,_,_,_,_,_,_,i) = Just $ Variable i+  lookupVar _ _ = Nothing++instance (Formatable a, Formatable b, Formatable c, Formatable d, Formatable e, Formatable f, Formatable g,+          Formatable h, Formatable i, Formatable j)+     => VarContainer (a, b, c, d, e, f, g, h, i, j) where+  lookupVar "0" (a,_,_,_,_,_,_,_,_,_) = Just $ Variable a+  lookupVar "1" (_,b,_,_,_,_,_,_,_,_) = Just $ Variable b+  lookupVar "2" (_,_,c,_,_,_,_,_,_,_) = Just $ Variable c+  lookupVar "3" (_,_,_,d,_,_,_,_,_,_) = Just $ Variable d+  lookupVar "4" (_,_,_,_,e,_,_,_,_,_) = Just $ Variable e+  lookupVar "5" (_,_,_,_,_,f,_,_,_,_) = Just $ Variable f+  lookupVar "6" (_,_,_,_,_,_,g,_,_,_) = Just $ Variable g+  lookupVar "7" (_,_,_,_,_,_,_,h,_,_) = Just $ Variable h+  lookupVar "8" (_,_,_,_,_,_,_,_,i,_) = Just $ Variable i+  lookupVar "9" (_,_,_,_,_,_,_,_,_,j) = Just $ Variable j+  lookupVar _ _ = Nothing+ instance Formatable a => VarContainer (Several a) where   lookupVar name (Several lst) =     if not $ TL.all isDigit name@@ -286,15 +328,22 @@ -- and if variable is not found there it will check in @c2@. data ThenCheck c1 c2 = ThenCheck c1 c2 +-- | Convenience type synonym.+type WithDefault c = ThenCheck c DefaultValue+ instance (VarContainer c1, VarContainer c2) => VarContainer (ThenCheck c1 c2) where   lookupVar name (ThenCheck c1 c2) =     case lookupVar name c1 of       Just result -> Just result       Nothing -> lookupVar name c2 -withDefault :: VarContainer c => c -> Variable -> ThenCheck c DefaultValue+-- | Use variables from specified container, or use default value if+-- variable is not found in container.+withDefault :: VarContainer c => c -> Variable -> WithDefault c withDefault c value = c `ThenCheck` DefaultValue value -optional :: VarContainer c => c -> ThenCheck c DefaultValue+-- | Use variables from specified container, or use empty string+-- variable is not found in container.+optional :: VarContainer c => c -> WithDefault c optional c = c `withDefault` (Variable TL.empty) 
Data/Text/Format/Heavy/Parse/Braces.hs view
@@ -43,7 +43,7 @@     return $ FVariable (TL.pack name) fmt   where     variable = do-      name <- many alphaNum+      name <- many $ try alphaNum <|> try (char '-') <|> char '.'       mbColon <- optionMaybe $ char ':'       fmt <- case mbColon of                Nothing -> return Nothing
Data/Text/Format/Heavy/Parse/Shell.hs view
@@ -64,7 +64,7 @@     return $ FVariable (TL.pack name) fmt   where     bracedVariable = between (char '{') (char '}') $ do-      name <- many alphaNum+      name <- many $ try alphaNum <|> try (char '-') <|> char '.'       mbColon <- optionMaybe $ char ':'       fmt <- case mbColon of                Nothing -> return Nothing
Data/Text/Format/Heavy/Parse/VarFormat.hs view
@@ -25,6 +25,7 @@     mbWidth <- optionMaybe (pWidth <?> "width specification")     mbPrecision <- optionMaybe (pPrecision <?> "precision specification")     mbRadix <- optionMaybe (pRadix <?> "radix specification")+    mbConvert <- optionMaybe (pConvert <?> "conversion specification")     return $ GenericFormat {                gfFillChar = fill              , gfAlign = align@@ -33,6 +34,7 @@              , gfWidth = mbWidth              , gfPrecision = mbPrecision              , gfRadix = mbRadix+             , gfConvert = mbConvert              }   where     pAlign :: Parsec TL.Text st Align@@ -98,12 +100,21 @@         'h' -> return Hexadecimal         'd' -> return Decimal +    pConvert :: Parsec TL.Text st Conversion+    pConvert = do+      char '~'+      conv <- oneOf "ult"+      case conv of+        'u' -> return UpperCase+        'l' -> return LowerCase+        't' -> return TitleCase+ -- | Parse generic variable format. -- -- Syntax is: -- -- @--- [[fill]align][sign][#][width][.precision][radix]+-- [[fill]align][sign][#][width][.precision][radix][~conversion] -- @ -- -- where:@@ -115,6 +126,8 @@ -- * width - minimum length of the field -- * precision - number of decimal places after point, for floatting-point numbers -- * radix - @h@ or @x@ for hexadecimal, @d@ for decimal (default).+-- * conversion - text conversion symbol. Supported are: @u@ - convert to upper case,+--   @l@ - convert to lower case, @t@ - convert to title case (capitalize all words). -- parseGenericFormat :: TL.Text -> Either ParseError GenericFormat parseGenericFormat text = runParser pGenericFormat () "<variable format specification>" text
Data/Text/Format/Heavy/Types.hs view
@@ -21,12 +21,20 @@       vName :: VarName      -- ^ Variable name     , vFormat :: VarFormat  -- ^ Variable format     }-  deriving (Show)+  deriving (Eq) +instance Show FormatItem where+  show (FString text) = TL.unpack text+  show (FVariable name Nothing) = TL.unpack $ "{" <> name <> "}"+  show (FVariable name (Just fmt)) = TL.unpack $ "{" <> name <> ":" <> fmt <> "}"+ -- | String format data Format = Format [FormatItem]-  deriving (Show)+  deriving (Eq) +instance Show Format where+  show (Format lst) = concat $ map show lst+ instance Monoid Format where   mempty = Format []   mappend (Format xs) (Format ys) = Format (xs ++ ys)@@ -52,6 +60,12 @@ -- This type may be also used to construct heterogeneous lists: -- @[Variable 1, Variable "x"] :: [Variable]@. data Variable = forall a. Formatable a => Variable a++instance Show Variable where+  show (Variable v) = either error toString $ formatVar Nothing v+    where+      toString :: B.Builder -> String+      toString b = TL.unpack $ B.toLazyText b  instance Formatable Variable where   formatVar fmt (Variable x) = formatVar fmt x
examples/test.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings #-}  import Data.Time+import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.IO as TLIO import Data.Text.Format.Heavy import Data.Text.Format.Heavy.Time@@ -13,7 +14,16 @@       xs = (18 :: Int, "hello" :: String, 2.718281828 :: Double, Shown (Just (7 :: Int)), Just (8 :: Int), rt, True)   TLIO.putStrLn $ format template xs   time <- getZonedTime-  TLIO.putStrLn $ format "Hello, {}! It is {:%H:%M:%S} now." $ ("Ilya" :: String, time)+  let vars :: [(TL.Text, Variable)]+      vars = [("name", Variable ("Ilya" :: String)),+              ("time", Variable time),+              ("header.content-type", Variable ("text/json" :: String)),+              ("upper", Variable ("this will be uppercase" :: String)),+              ("lower", Variable ("This will be ALL lower case" :: String)),+              ("title", Variable ("this is the title" :: String)),+              ("noun", Variable ("string" :: String))]+  TLIO.putStrLn $+    format "Hello, {name}! It is {time:%H:%M:%S} now. Test {noun}ification. Content: {header.content-type} x. Upper: <{upper:~u}>, lower <{lower:~l}>, title: <{title:~t}>." vars   let mbX = Nothing :: Maybe Float       mbY = Just 7.37491 :: Maybe Float       mbZ = Nothing :: Maybe Float
text-format-heavy.cabal view
@@ -1,5 +1,5 @@ name:                text-format-heavy-version:             0.1.4.0+version:             0.1.5.0 synopsis:            Full-weight string formatting library, analog of Python's string.format description:         This package contains full-featured string formatting function, similar to                      Python's string.format. Features include: