-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A Python str.format() like formatter -- -- Please see the http://hackage.haskell.org/package/vformat @package vformat @version 0.12.0.0 -- | This library is inspired by Python's str.format and Haskell's -- Text.Printf, and most of the features are copied from these two -- libraries. module Text.Format -- | Format a variable number of arguments with Python-style format string -- --
--   >>> format "{:s}, {:d}, {:.4f}" "hello" 123 pi
--   "hello, 123, 3.1416"
--   
--   >>> format "{1:s}, {0:d}, {2:.4f}" 123 "hello" pi
--   "hello, 123, 3.1416"
--   
--   >>> format "{:s} {:d} {pi:.4f}" "hello" 123 ("pi" := pi)
--   "hello, 123, 3.1416"
--   
-- -- See Format to learn more about format string syntax. -- -- See FormatArg to learn how to derive FormatArg for your own -- data types. format :: FormatType r => Format -> r -- | A variant of format, it takes only one positional argument -- --
--   >>> :set -XDeriveGeneric
--   
--   >>> import GHC.Generics
--   
--   >>> data Triple = Triple String Int Double deriving Generic
--   
--   >>> instance FormatArg Triple
--   
--   >>> format "{0!0:s} {0!1:d} {0!2:.4f}" $ Triple "hello" 123 pi
--   "hello, 123, 3.1416"
--   
--   >>> format1 "{0:s} {1:d} {2:.4f}" $ Triple "hello" 123 pi
--   "hello, 123, 3.1416"
--   
format1 :: FormatArg a => Format1 -> a -> String -- | Typeclass of formatable values. -- -- The formatArg method takes a value, a key and a field format -- descriptor and either fails due to a ArgError or produce a -- string as the result. There is a default formatArg for -- Generic instances, which applies defaultOptions to -- genericFormatArg. -- -- There are two reasons may cause formatting fail -- --
    --
  1. Can not find argument for the given key.
  2. --
  3. The field format descriptor does not match the argument.
  4. --
-- --

Extending to new types

-- -- Those format functions can be extended to format types other than -- those provided by default. This is done by instantiating -- FormatArg. -- -- Examples -- --
--   {-# LANGUAGE DeriveGeneric     #-}
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import           Control.Exception
--   import           GHC.Generics
--   import           Text.Format
--   
--   -- Manually extend to ()
--   instance FormatArg () where
--     formatArg x k fmt@(ArgFmt{fmtSpecs="U"}) =
--       let fmt' = fmt{fmtSpecs = ""}
--       in  formatArg (show x) k fmt'
--     formatArg _ _ _ = Left $ toException ArgFmtError
--   
--   -- Use default generic implementation for type with nullary data constructors.
--   data Color = Red | Yellow | Blue deriving Generic
--   
--   instance FormatArg Color
--   
--   -- Use default generic implementation for type with non-nullary data constructor.
--   data Triple = Triple String Int Double deriving Generic
--   
--   instance FormatArg Triple
--   
--   -- Use default generic implementation for type using record syntax.
--   data Student = Student { no   :: Int
--                          , name :: String
--                          , age  :: Int
--                          } deriving Generic
--   
--   instance FormatArg Student
--   
--   -- Customize field names
--   data Book = Book { bookName   :: String
--                    , bookAuthor :: String
--                    , bookPrice  :: Double
--                    }
--   
--   instance FormatArg Book where
--     formatArg x k fmt
--       | k == mempty = return $ format1 "{name} {author} {price:.2f}" x
--       | k == Name "name" = formatArg (bookName x) mempty fmt
--       | k == Name "author" = formatArg (bookAuthor x) mempty fmt
--       | k == Name "price" = formatArg (bookPrice x) mempty fmt
--       | otherwise = Left $ toException $ ArgKeyError
--   
--   -- A better way to customize field names
--   -- instance FormatArg Book where
--   --   formatArg = genericFormatArg $
--   --     defaultOptions { fieldLabelModifier = drop 4 }
--   
--   main :: IO ()
--   main = do
--     putStrLn $ format "A unit {:U}" ()
--     putStrLn $ format "I like {}." Blue
--     putStrLn $ format "Triple {0!0} {0!1} {0!2}" $ Triple "Hello" 123 pi
--     putStrLn $ format1 "Student: {no} {name} {age}" $ Student 1 "neo" 30
--     putStrLn $ format "A book: {}" $ Book "Math" "nobody" 99.99
--     putStrLn $ format1 "Book: {name}, Author: {author}, Price: {price:.2f}" $
--       Book "Math" "nobody" 99.99
--   
-- -- Note: Since v0.12.0, FormatTime instance has been remove, use -- vformat-time instead. class FormatArg a formatArg :: FormatArg a => a -> Formatter formatArg :: (FormatArg a, Generic a, GFormatArg (Rep a)) => a -> Formatter -- | A typeclass provides the variable arguments magic for format class FormatType t sfmt :: FormatType t => Format -> Map ArgKey Formatter -> t -- | Options that specify how to format your datatype -- -- Options can be set using record syntax on defaultOptions with the -- fields below. data Options -- | Default format options -- --
--   Options
--   { fieldLabelModifier = id
--   }
--   
defaultOptions :: Options fieldLabelModifier :: Options -> String -> String -- | A configurable generic Formatter creator. genericFormatArg :: (Generic a, GFormatArg (Rep a)) => Options -> a -> Formatter type Formatter = ArgKey -> ArgFmt -> Either SomeException String -- | A data type indicates a format string -- -- Format string contains "replacement fields" surrounded by curly braces -- {}. Anything that is not contained in braces is considered literal -- text, which is copied unchanged to the output. If you need to include -- a brace character in the literal text, it can be escaped by doubling -- {{ and }}. -- --

Format string syntax

-- --
--   format -> {chars | ("{" [key][":"fmt] "}")}
--   key    -> <see ArgKey>
--   fmt    -> <see ArgFmt>
--   
--   
-- -- Note: This library use a description language to describe syntax, see -- next section. -- -- Note: A key can be omitted only if there is no explict index key -- before it, it will be automatically caculated and inserted to the -- format string according to its position in the omitted key sequence. -- -- Examples -- --
--   >>> "I like {coffee}, I drink it everyday." :: Format
--   
--   >>> "{no:<20}    {name:<20}    {age}" :: Format
--   
--   >>> "{{\"no\": {no}, \"name\": \"{name}\"}}" :: Format
--   
-- --

Syntax description language

-- -- A syntax expr may contain a list of fields as followings -- --
--   identifier                       identifier of an expr
--   <description>                    use natural language as an expr
--   ->                               use right hand expr to describe identifier
--   ()                               a required field, may be omitted
--   []                               an optional field
--   {}                               repeat any times of the field
--   |                                logical or, choice between left and right
--   ""                               literal text
--   
--   
-- -- Built-in exprs -- --
--   char  -> <any character>
--   chars -> {char}
--   int   -> <integer without sign>
--   
--   
data Format -- | A variant of Format, it transforms all argument's key to -- Nest (Index 0) key data Format1 -- | A data type indicates key of format argument -- --

The key syntax

-- --
--   key -> [(int | chars) {"!" (int | chars)}]
--   
--   
-- -- Since the "!" is used to seprate keys, if you need to include a "!" in -- a named key, it can be escaped by doubling "!!". -- -- Note: See Format to learn more about syntax description -- language -- -- Examples -- --
--   >>> read "0" :: ArgKey
--   
--   >>> read "country" :: ArgKey
--   
--   >>> read "coun!!try" :: ArgKey
--   
--   >>> read "country!name" :: ArgKey
--   
--   >>> read "country!cities!10!name" :: ArgKey
--   
data ArgKey -- | Refers to a top-level positional argument or an element in an -- list-like data type. Index :: Int -> ArgKey -- | Refers to a top-level named argument or a field of a record data type. Name :: String -> ArgKey -- | For Nest k1 k2, k1 refers to a top-level argument or an -- attribute (element or field) of a data type, k2 refers an attribute of -- the data referenced by k1. Nest :: ArgKey -> ArgKey -> ArgKey -- | Extract the topmost indexed or named key from a key -- --
--   >>> topKey (read "k1!k2!k3") == Name "k1"
--   True
--   
--   >>> topKey (read "name") == Name "name"
--   True
--   
--   >>> topKey (read "123") == Index 123
--   True
--   
--   >>> topKey mempty
--   *** Exception: vformat: empty arg key
--   
topKey :: ArgKey -> ArgKey -- | Remove the topmost indexed or named key from a key -- --
--   >>> popKey (read "k1!k2!k3") == read "k2!k3"
--   True
--   
--   >>> popKey (read "name") == mempty
--   True
--   
--   >>> popKey (read "123") == mempty
--   True
--   
--   >>> popKey mempty
--   *** Exception: vformat: empty arg key
--   
popKey :: ArgKey -> ArgKey -- | A data type indicates how to format an argument. -- --

The format syntax

-- --
--   fmt       -> [[pad] align][sign]["#"]["0"][width][sep]["." precision][specs]
--   pad       -> char
--   align     -> "<" | ">" | "^" | "="
--   sign      -> "+" | "-" | " "
--   width     -> int | ("{" key "}")
--   sep       -> "_" | ","
--   precision -> int | ("{" key "}")
--   specs     -> chars
--   key       -> <see ArgKey>
--   
--   
-- -- -- -- Examples -- --
--   >>> read "*<30s" :: ArgFmt
--   
--   >>> read "<10.20s" :: ArgFmt
--   
--   >>> read "0=10_.20d" :: ArgFmt
--   
--   >>> read "#010_.20b" :: ArgFmt
--   
-- --

String specs

-- --
--   s
--   default         s
--   
--   
-- --

Integer specs

-- --
--   b               binary format integer
--   c               char point (Char will be trasformed by ord first)
--   d               decimal format integer
--   o               octal format integer
--   x               hex format integer (use lower-case letters)
--   X               hex format integer (use upper-case letters)
--   default         d
--   
--   
-- --

Floating point number specs

-- --
--   e               exponent notation, see showEFloat
--   E               same as "e", but use upper-case E as separator
--   f               fixed-point notation see showFFloat
--   F               same as "f", but converts nan to NAN and inf to INF
--   g               general format, see showGFloat
--   G               same as "g", but use upper-case E as separator and
--                   converts nan to NAN and inf to INF
--   %               percentage, same as "f" except multiplies 100 first and
--                   followed by a percent sign
--   default         g
--   
--   
-- -- See FormatArg to learn how to define specs for your own types. data ArgFmt ArgFmt :: FmtAlign -> Char -> FmtSign -> Bool -> Bool -> Either Int ArgKey -> FmtNumSep -> Either Int ArgKey -> String -> String -> ArgFmt [fmtAlign] :: ArgFmt -> FmtAlign [fmtPad] :: ArgFmt -> Char [fmtSign] :: ArgFmt -> FmtSign [fmtAlternate] :: ArgFmt -> Bool [fmtSignAware] :: ArgFmt -> Bool [fmtWidth] :: ArgFmt -> Either Int ArgKey [fmtNumSep] :: ArgFmt -> FmtNumSep [fmtPrecision] :: ArgFmt -> Either Int ArgKey [fmtSpecs] :: ArgFmt -> String -- | When reading from a string, different strings may produce the same -- ArgFmt, this field keeps the original string here in case it is -- use later. [fmtRaw] :: ArgFmt -> String -- | Pretty showing ArgFmt -- -- Note: Don't create ArgFmt manually, read from a string, -- see ArgFmt. prettyArgFmt :: ArgFmt -> String -- | A data type indicates how to align arguments data FmtAlign -- | Not specified, equivalent to AlignLeft unless number's sign -- aware enabled. AlignNone :: FmtAlign -- | Forces the argument to be left-aligned within the available space. AlignLeft :: FmtAlign -- | Forces the field to be right-aligned within the available space. AlignRight :: FmtAlign -- | Forces the field to be centered within the available space. AlignCenter :: FmtAlign -- | Number specified, forces the padding to be placed after the sign (if -- any) but before the digits. AlignSign :: FmtAlign -- | A data type indicates how to show number's sign data FmtSign -- | Not specified, equivalent to SignMinus for signed numbers. SignNone :: FmtSign -- | Sign should be used for both positive as well as negative numbers. SignPlus :: FmtSign -- | Sign should be used only for negative numbers SignMinus :: FmtSign -- | A leading space should be used on positive numbers, and a minus sign -- on negative numbers. SignSpace :: FmtSign -- | A data type indicates number separator -- -- e.g. 20,200,101 20_200_202 data FmtNumSep -- | Don't separate number NumSepNone :: FmtNumSep -- | Use dash as number separator NumSepDash :: FmtNumSep -- | Use comma as number separator NumSepComma :: FmtNumSep -- | A type represents the top-level named key argument. data (:=) a (:=) :: String -> a -> (:=) a infixr 6 := infixr 6 := -- | Formatter for string values formatString :: String -> Formatter -- | Formatter for Char values formatChar :: Char -> Formatter -- | Formatter for Int values formatInt :: (Integral a, Bounded a) => a -> Formatter -- | Formatter for Word values formatWord :: (Integral a, Bounded a) => a -> Formatter -- | Formatter for Integer values formatInteger :: Integer -> Formatter -- | Formatter for RealFloat values formatRealFloat :: RealFloat a => a -> Formatter -- | Use a default specs for the given formatter defaultSpecs :: String -> (a -> Formatter) -> a -> Formatter -- | A data type indicates an arg error data ArgError -- | Can not find argument for the given key ArgKeyError :: ArgError -- | The field format descriptor does not match the argument ArgFmtError :: ArgError -- | Calls vferror to indicate an arg key error for a given type. errorArgKey :: String -> a -- | Calls vferror to indicate an arg format error for a given type. errorArgFmt :: String -> a -- | Raises an error with a vformat-specific prefix on the message string. vferror :: String -> a