-- 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.13.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
--
--
-- {-# 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
-- | Typeclass for types that can be used as the key of a map-like or
-- list-like container.
--
-- For example, since String and Integral datatypes are
-- instance of FromArgKey and Double is an instance of
-- FormatArg, we can format a value of type Map
-- String Double.
class FromArgKey a
fromArgKey :: FromArgKey a => ArgKey -> Maybe a
-- | 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 -> {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
--
--
--
-- 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
--
--
-- 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. -- --
-- 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>
--
--
--
-- -- >>> read "*<30s" :: ArgFmt -- -- >>> read "<10.20s" :: ArgFmt -- -- >>> read "0=10_.20d" :: ArgFmt -- -- >>> read "#010_.20b" :: ArgFmt ---- --
-- s -- default s -- ---- --
-- 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 -- ---- --
-- 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