-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Combinator-based type-safe formatting (like printf() or FORMAT) -- -- Combinator-based type-safe formatting (like printf() or FORMAT), -- modelled from the HoleyMonoids package. -- -- See the README at -- https://github.com/AJChapman/formatting#readme for more info. @package formatting @version 7.1.2 -- | Types that can be rendered to a Builder. module Formatting.Buildable -- | The class of types that can be rendered to a Builder. class Buildable p build :: Buildable p => p -> Builder instance Formatting.Buildable.Buildable Data.Text.Internal.Builder.Builder instance Formatting.Buildable.Buildable Data.Void.Void instance Formatting.Buildable.Buildable Data.Text.Internal.Lazy.Text instance Formatting.Buildable.Buildable Data.Text.Internal.Text instance Formatting.Buildable.Buildable GHC.Types.Char instance Formatting.Buildable.Buildable [GHC.Types.Char] instance GHC.Real.Integral a => Formatting.Buildable.Buildable (Data.Text.Format.Types.Hex a) instance Formatting.Buildable.Buildable GHC.Int.Int8 instance Formatting.Buildable.Buildable GHC.Int.Int16 instance Formatting.Buildable.Buildable GHC.Int.Int32 instance Formatting.Buildable.Buildable GHC.Types.Int instance Formatting.Buildable.Buildable GHC.Int.Int64 instance Formatting.Buildable.Buildable GHC.Integer.Type.Integer instance Data.Fixed.HasResolution a => Formatting.Buildable.Buildable (Data.Fixed.Fixed a) instance Formatting.Buildable.Buildable GHC.Word.Word8 instance Formatting.Buildable.Buildable GHC.Word.Word16 instance Formatting.Buildable.Buildable GHC.Word.Word32 instance Formatting.Buildable.Buildable GHC.Types.Word instance Formatting.Buildable.Buildable GHC.Word.Word64 instance Formatting.Buildable.Buildable a => Formatting.Buildable.Buildable (GHC.Real.Ratio a) instance Formatting.Buildable.Buildable GHC.Types.Float instance Formatting.Buildable.Buildable GHC.Types.Double instance Formatting.Buildable.Buildable Data.Time.Clock.Internal.DiffTime.DiffTime instance Formatting.Buildable.Buildable Data.Time.Clock.Internal.NominalDiffTime.NominalDiffTime instance Formatting.Buildable.Buildable Data.Time.Clock.Internal.UTCTime.UTCTime instance Formatting.Buildable.Buildable Data.Time.Clock.Internal.UniversalTime.UniversalTime instance Formatting.Buildable.Buildable Data.Time.Calendar.Days.Day instance GHC.Show.Show a => Formatting.Buildable.Buildable (Data.Text.Format.Types.Shown a) instance Formatting.Buildable.Buildable a => Formatting.Buildable.Buildable (GHC.Maybe.Maybe a) instance Formatting.Buildable.Buildable Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay instance Formatting.Buildable.Buildable Data.Time.LocalTime.Internal.TimeZone.TimeZone instance Formatting.Buildable.Buildable Data.Time.LocalTime.Internal.LocalTime.LocalTime instance Formatting.Buildable.Buildable Data.Time.LocalTime.Internal.ZonedTime.ZonedTime instance Formatting.Buildable.Buildable Foreign.Ptr.IntPtr instance Formatting.Buildable.Buildable Foreign.Ptr.WordPtr instance Formatting.Buildable.Buildable (GHC.Ptr.Ptr a) instance Formatting.Buildable.Buildable GHC.Types.Bool instance Formatting.Buildable.Buildable a => Formatting.Buildable.Buildable [a] -- | Internal format starters. module Formatting.Internal -- | A formatter. When you construct formatters the first type parameter, -- r, will remain polymorphic. The second type parameter, -- a, will change to reflect the types of the data that will be -- formatted. For example, in -- --
-- myFormat :: Format r (Text -> Int -> r) -- myFormat = "Person's name is " % text % ", age is " % hex ---- -- the first type parameter remains polymorphic, and the second type -- parameter is Text -> Int -> r, which indicates that it -- formats a Text and an Int. -- -- When you run the Format, for example with format, you -- provide the arguments and they will be formatted into a string. -- --
-- > format ("Person's name is " % text % ", age is " % hex) "Dave" 54
-- "Person's name is Dave, age is 36"
--
newtype Format r a
Format :: ((Builder -> r) -> a) -> Format r a
[runFormat] :: Format r a -> (Builder -> r) -> a
-- | Concatenate two formatters.
--
-- formatter1 % formatter2 is a formatter that accepts arguments
-- for formatter1 and formatter2 and concatenates their
-- results. For example
--
-- -- format1 :: Format r (Text -> r) -- format1 = "Person's name is " % text ---- --
-- format2 :: Format r r -- format2 = ", " ---- --
-- format3 :: Format r (Int -> r) -- format3 = "age is " % hex ---- --
-- myFormat :: Format r (Text -> Int -> r) -- myFormat = format1 % format2 % format3 ---- -- Notice how the argument types of format1 and format3 -- are gathered into the type of myFormat. -- -- (This is actually the composition operator for Formats -- Category instance, but that is (at present) inconvenient to use -- with regular Prelude. So this function is provided as a -- convenience.) (%) :: Format r a -> Format r' r -> Format r' a infixr 9 % -- | Function compose two formatters. Will feed the result of one formatter -- into another. (%.) :: Format r (Builder -> r') -> Format r' a -> Format r a infixr 8 %. -- | Don't format any data, just output a constant Builder. now :: Builder -> Format r r -- | Monadic indexed bind for holey monoids. bind :: Format r a -> (Builder -> Format r' r) -> Format r' a -- | Functorial map over a formatter's input. Example: format (mapf -- (drop 1) string) "hello" mapf :: (a -> b) -> Format r (b -> t) -> Format r (a -> t) -- | Format a value of type a using a function of type a -> -- Builder. For example, later (f :: Int -> -- Builder) produces Format r (Int -> r). later :: (a -> Builder) -> Format r (a -> r) -- | Run the formatter and return a lazy Text value. format :: Format Text a -> a -- | Run the formatter and return a strict Text value. sformat :: Format Text a -> a -- | Run the formatter and return a Builder value. bprint :: Format Builder a -> a -- | Run the formatter and return a Builder value. -- -- This is a newer synonym for bprint, following the naming -- convention set by format and sformat. bformat :: Format Builder a -> a -- | Run the formatter and print out the text to stdout. fprint :: Format (IO ()) a -> a -- | Run the formatter and print out the text to stdout, followed by a -- newline. fprintLn :: Format (IO ()) a -> a -- | Run the formatter and put the output onto the given Handle. hprint :: Handle -> Format (IO ()) a -> a -- | Run the formatter and put the output and a newline onto the given -- Handle. hprintLn :: Handle -> Format (IO ()) a -> a -- | Run the formatter and return a list of characters. formatToString :: Format String a -> a instance GHC.Base.Functor (Formatting.Internal.Format r) instance GHC.Base.Semigroup (Formatting.Internal.Format r (a -> r)) instance GHC.Base.Monoid (Formatting.Internal.Format r (a -> r)) instance (a GHC.Types.~ r) => Data.String.IsString (Formatting.Internal.Format r a) instance Control.Category.Category Formatting.Internal.Format -- | Formatting functions. module Formatting.Formatters -- | Output a lazy text. text :: Format r (Text -> r) -- | Output a strict text. stext :: Format r (Text -> r) -- | Output a string. string :: Format r (String -> r) -- | Output a showable value (instance of Show) by turning it into -- Text: -- --
-- >>> format ("Value number " % shown % " is " % shown % ".") 42 False
-- "Value number 42 is False."
--
shown :: Show a => Format r (a -> r)
-- | Output a character.
char :: Format r (Char -> r)
-- | Build a builder.
builder :: Format r (Builder -> r)
-- | Like const but for formatters.
fconst :: Builder -> Format r (a -> r)
-- | Render an integral e.g. 123 -> "123", 0 -> "0".
int :: Integral a => Format r (a -> r)
-- | Render some floating point with the usual notation, e.g. 123.32 =>
-- "123.32"
float :: Real a => Format r (a -> r)
-- | Render a floating point number using normal notation, with the given
-- number of decimal places.
fixed :: Real a => Int -> Format r (a -> r)
-- | Render a scientific number.
sci :: Format r (Scientific -> r)
-- | Render a scientific number with options.
scifmt :: FPFormat -> Maybe Int -> Format r (Scientific -> r)
-- | Render a floating point number using the smallest number of digits
-- that correctly represent it. Note that in the case of whole numbers it
-- will still add one decimal place, e.g. "1.0".
shortest :: Real a => Format r (a -> r)
-- | Group integral numbers, e.g. groupInt 2 . on 123456 ->
-- "12.34.56".
groupInt :: (Buildable n, Integral n) => Int -> Char -> Format r (n -> r)
-- | Add commas to an integral, e.g 12000 -> "12,000".
commas :: (Buildable n, Integral n) => Format r (n -> r)
-- | Add a suffix to an integral, e.g. 1st, 2nd, 3rd, 21st.
ords :: Integral n => Format r (n -> r)
-- | English plural suffix for an integral.
--
-- For example:
--
-- -- >>> set -XOverloadedStrings -- -- >>> formatPeople = format (int % " " <> plural "person" "people" % ".") :: Int -> Data.Text.Lazy.Text -- -- >>> formatPeople 1 -- "1 person." -- -- >>> formatPeople 3 -- "3 people." --plural :: (Num a, Eq a) => Text -> Text -> Format r (a -> r) -- | Shows the Int value of Enum instances using fromEnum. -- --
-- >>> format ("Got: " % char % " (" % asInt % ")") 'a' 'a'
-- "Got: a (97)"
--
asInt :: Enum a => Format r (a -> r)
-- | Pad the left hand side of a string until it reaches k characters wide,
-- if necessary filling with character c.
left :: Buildable a => Int -> Char -> Format r (a -> r)
-- | Pad the right hand side of a string until it reaches k characters
-- wide, if necessary filling with character c.
right :: Buildable a => Int -> Char -> Format r (a -> r)
-- | Pad the left & right hand side of a string until it reaches k
-- characters wide, if necessary filling with character c.
center :: Buildable a => Int -> Char -> Format r (a -> r)
-- | Fit in the given length, truncating on the left.
fitLeft :: Buildable a => Int -> Format r (a -> r)
-- | Fit in the given length, truncating on the right.
fitRight :: Buildable a => Int -> Format r (a -> r)
-- | Render an integral at base n.
base :: Integral a => Int -> Format r (a -> r)
-- | Render an integer using binary notation. (No leading 0b is added.)
-- Defined as bin = base 2.
bin :: Integral a => Format r (a -> r)
-- | Render an integer using octal notation. (No leading 0o is added.)
-- Defined as oct = base 8.
oct :: Integral a => Format r (a -> r)
-- | Render an integer using hexadecimal notation. (No leading 0x is
-- added.) Has a specialized implementation.
hex :: Integral a => Format r (a -> r)
-- | Render an integer using binary notation with a leading 0b.
--
-- See also binPrefix for fixed-width formatting.
prefixBin :: Integral a => Format r (a -> r)
-- | Render an integer using octal notation with a leading 0o.
--
-- See also octPrefix for fixed-width formatting.
prefixOct :: Integral a => Format r (a -> r)
-- | Render an integer using hexadecimal notation with a leading 0x.
--
-- See also hexPrefix for fixed-width formatting.
prefixHex :: Integral a => Format r (a -> r)
-- | Renders a given byte count using an appropiate decimal binary suffix:
--
-- -- >>> format (bytes shortest) 1024 -- "1KB" ---- --
-- >>> format (bytes (fixed 2 % " ")) (1024*1024*5) -- "5.00 MB" --bytes :: (Ord f, Integral a, Fractional f) => Format Builder (f -> Builder) -> Format r (a -> r) -- | Build anything that implements the Buildable class. build :: Buildable a => Format r (a -> r) -- | The class of types that can be rendered to a Builder. class Buildable p -- | A formatting combinator takes a Format and returns another Format. -- Generally we want to change what the original format takes as its -- *input*, leaving the output polymorphic. Many of these combinators can -- be chained together to form a single Format. -- -- Implementation detail: in order to be able to chain multiple -- combinators to make a single Format we need them all to use the -- same intermediate string type, and we have chosen Builder. This -- does not tie you to using Builders, because the final output -- string type r is still polymorphic. module Formatting.Combinators -- | Render a Maybe value either as a default (if Nothing) or using the -- given formatter: -- --
-- >>> format (maybed "Goodbye" text) Nothing -- "Goodbye" ---- --
-- >>> format (maybed "Goodbye" text) (Just "Hello") -- "Hello" --maybed :: Builder -> Format Builder (a -> Builder) -> Format r (Maybe a -> r) -- | Render the value in a Maybe using the given formatter, or produce an -- empty string: -- --
-- >>> format (optioned text) Nothing -- "" ---- --
-- >>> format (optioned text) (Just "Hello") -- "Hello" --optioned :: Format Builder (a -> Builder) -> Format r (Maybe a -> r) -- | Render the value in an Either: -- --
-- >>> format (eithered text int) (Left "Error!" -- "Error!" ---- --
-- >>> format (eithered text int) (Right 69) -- "69" --eithered :: Format Builder (a -> Builder) -> Format Builder (b -> Builder) -> Format r (Either a b -> r) -- | Render the value in a Left with the given formatter, rendering a Right -- as an empty string: -- --
-- >>> format (lefted text) (Left "bingo") -- "bingo" ---- --
-- >>> format (lefted text) (Right 16) -- "" --lefted :: Format Builder (a -> Builder) -> Format r (Either a x -> r) -- | Render the value in a Right with the given formatter, rendering a Left -- as an empty string: -- --
-- >>> format (righted text) (Left 16) -- "" ---- --
-- >>> format (righted text) (Right "bingo") -- "bingo" --righted :: Format Builder (a -> Builder) -> Format r (Either x a -> r) -- | Format each value in a list and concatenate them all: -- --
-- >>> format (concatenated text) ["one", "two", "three"] -- "onetwothree" ---- --
-- >>> format (took 15 (concatenated bin)) [1..] -- "1101110010111011110001001101010111100110111101111" --concatenated :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Use the given text-joining function to join together the individually -- rendered items of a list. -- --
-- >>> format (joinedWith (mconcat . reverse) int) [123, 456, 789] -- "789456123" --joinedWith :: Foldable t => ([Text] -> Text) -> Format Builder (a -> Builder) -> Format r (t a -> r) -- | Format each value in a list and place the given string between each: -- --
-- >>> fprintLn (intercalated "||" int) [1, 2, 3] -- 1||2||3 --intercalated :: Foldable t => Text -> Format Builder (a -> Builder) -> Format r (t a -> r) -- | Format each value in a list with spaces in between: -- --
-- >>> format (unworded int) [1, 2, 3] -- "1 2 3" --unworded :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Format each value in a list, placing each on its own line: -- --
-- >>> fprint (unlined char) ['a'..'c'] -- a -- b -- c --unlined :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Separate the formatted items of the Foldable (e.g. list) with spaces: -- --
-- >>> format (spaced int) [1, 2, 3] -- "1 2 3" ---- -- Note that this behaviour is identical to unworded, it's just a -- different way of thinking about it. spaced :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Separate the formatted items of the Foldable (e.g. list) with commas: -- --
-- >>> format (commaSep stext) ["one", "two", "three", "four", "five"] -- "one,two,three,four,five" ---- --
-- >>> format (took 5 (commaSep int)) [1..] -- "1,2,3,4,5" --commaSep :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Separate the formatted items of the Foldable (e.g. list) with commas -- and spaces: -- --
-- >>> format (took 3 (commaSpaceSep ords)) [1..] -- "1st, 2nd, 3rd" --commaSpaceSep :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Add square brackets around the Foldable (e.g. a list), and separate -- each formatted item with a comma and space. -- --
-- >>> format (list stext) ["one", "two", "three"] -- "[one, two, three]" ---- --
-- >>> format (list shown) ["one", "two", "three"] -- "[\"one\", \"two\", \"three\"]" --list :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Like list, but also put double quotes around each rendered -- item: -- --
-- >>> fprintLn (qlist stext) ["one", "two", "three"] -- ["one", "two", "three"] --qlist :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r) -- | Take only the first n items from the list of items. -- --
-- >>> format (took 7 (list bin)) [1..] -- "[1, 10, 11, 100, 101, 110, 111]" ---- --
-- >>> format (list bin) (take 7 [1..]) -- "[1, 10, 11, 100, 101, 110, 111]" --took :: Int -> Format r ([a] -> r) -> Format r ([a] -> r) -- | Drop the first n items from the list of items. -- --
-- >>> format (dropped 3 (list int) [1..6] -- "[4, 5, 6]" --dropped :: Int -> Format r ([a] -> r) -> Format r ([a] -> r) -- | Split the formatted item in places the given predicated matches, and -- use the given list combinator to render the resultant list of strings -- (this function was sent to us from a parallel universe in which splat -- is the past participle of split, e.g. "whoops, I splat my pants"). -- --
-- >>> format (splat Data.Char.isSpace commaSpaceSep stext) "This\t is\n\t\t poorly formatted " -- "This, , , is, , , , , poorly, formatted, , , " --splat :: (Char -> Bool) -> (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -> Format r a -> Format r a -- | Utility for taking a text-splitting function and turning it into a -- formatting combinator. -- --
-- >>> format (splatWith (TL.chunksOf 3) list int) 1234567890 -- "[123, 456, 789, 0]" --splatWith :: (Text -> [Text]) -> (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -> Format r a -> Format r a -- | Split the formatted item at instances of the given string, and use the -- given list combinator to render the resultant list of strings. -- --
-- >>> fprint (splatOn "," unlined text) "one,two,three" -- one -- two -- three ---- --
-- >>> fprint (splatOn "," indentedLines text) "one,two,three" -- one -- two -- three --splatOn :: Text -> (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -> Format r a -> Format r a -- | Split the formatted item into words and use the given list combinator -- to render the resultant list of strings. -- --
-- >>> format (worded list text) "one two three " -- "[one, two, three]" --worded :: (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -> Format r a -> Format r a -- | Split the formatted item into lines and use the given list combinator -- to render the resultant list of strings. -- --
-- >>> fprintLn (lined qlist text) "one two three\n\nfour five six\nseven eight nine\n\n" -- ["one two three", "", "four five six", "seven eight nine", ""] --lined :: (Format Builder (Builder -> Builder) -> Format Builder ([Builder] -> Builder)) -> Format r a -> Format r a -- | Alter the formatted string with the given function. -- --
-- >>> format (alteredWith Data.Text.Lazy.reverse int) 123456 -- "654321" --alteredWith :: (Text -> Text) -> Format r a -> Format r a -- | Filter the formatted string to contain only characters which pass the -- given predicate: -- --
-- >>> format (charsKeptIf Data.Char.isUpper text) "Data.Char.isUpper" -- "DCU" --charsKeptIf :: (Char -> Bool) -> Format r a -> Format r a -- | Filter the formatted string to not contain characters which pass the -- given predicate: -- --
-- >>> format (charsRemovedIf Data.Char.isUpper text) "Data.Char.isUpper" -- "ata.har.ispper" --charsRemovedIf :: (Char -> Bool) -> Format r a -> Format r a -- | Take a formatter and replace the given needle with the given -- replacement in its output. -- --
-- >>> format (replaced "Bruce" "<redacted>" stext) "Bruce replied that Bruce's name was, in fact, '<redacted>'." -- "<redacted> replied that <redacted>'s name was, in fact, '<redacted>'." --replaced :: Text -> Text -> Format r a -> Format r a -- | Convert any letters in the output of the given formatter to -- upper-case. -- --
-- >>> format (uppercased text) "I'm not shouting, you're shouting." -- "I'M NOT SHOUTING, YOU'RE SHOUTING." --uppercased :: Format r a -> Format r a -- | Convert any letters in the output of the given formatter to -- lower-case. -- --
-- >>> format (lowercased text) "Cd SrC/; Rm -Rf *" -- "cd src/; rm -rf *" --lowercased :: Format r a -> Format r a -- | Convert the formatted string to title case, or something like it: -- --
-- >>> format (titlecased string) "the life of brian" -- "The Life Of Brian" --titlecased :: Format r a -> Format r a -- | Truncate the formatted string at the end so that it is no more than -- the given number of characters in length, placing an ellipsis at the -- end such that it does not exceed this length. -- --
-- >>> format (truncated 5 text) "hello" -- "hello" ---- --
-- >>> format (truncated 5 text) "hellos" -- "he..." --ltruncated :: Int64 -> Format r a -> Format r a -- | Truncate the formatted string in the center, leaving the given number -- of characters at the start and end, and placing an ellipsis in -- between. The length will be no longer than `start + end + 3` -- characters long. -- --
-- >>> format (ctruncated 15 4 text) "The quick brown fox jumps over the lazy dog." -- "The quick brown...dog." ---- --
-- >>> format (ctruncated 15 4 text) "The quick brown fox" -- "The quick brown fox" --ctruncated :: Int64 -> Int64 -> Format r a -> Format r a -- | Truncate the formatted string at the start so that it is no more than -- the given number of characters in length, placing an ellipsis at the -- start such that it does not exceed this length. -- --
-- >>> format (rtruncated 5 text) "hello" -- "hello" ---- --
-- >>> format (rtruncated 5 text) "hellos" -- "...os" --rtruncated :: Int64 -> Format r a -> Format r a -- | Pad the formatted string on the left with the given character to give -- it the given minimum width: -- --
-- >>> format (lpadded 7 ' ' int) 1 -- " 1" ---- --
-- >>> format (lpadded 7 ' ' int) 123456789 -- "123456789" --lpadded :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r) -- | Pad the formatted string on the right with the given character to give -- it the given minimum width: -- --
-- >>> format (rpadded 7 ' ' int) 1 -- "1 " --rpadded :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r) -- | Pad the formatted string on the left and right with the given -- character to center it, giving it the given minimum width: -- --
-- >>> format (cpadded 7 ' ' int) 1 -- " 1 " --cpadded :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r) -- | Format the item with a fixed width, padding with the given character -- on the left to extend, adding an ellipsis on the right to shorten: -- --
-- >>> format (lfixed 10 ' ' int) 123 -- "123 " ---- --
-- >>> format (lfixed 10 ' ' int) 1234567890 -- "1234567890" ---- --
-- >>> format (lfixed 10 ' ' int) 123456789012345 -- "1234567..." --lfixed :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r) -- | Format the item with a fixed width, padding with the given character -- on the right to extend, adding an ellipsis on the right to shorten: -- --
-- >>> format (rfixed 10 ' ' int) 123 -- " 123" ---- --
-- >>> format (rfixed 10 ' ' int) 1234567890 -- "1234567890" ---- --
-- >>> format (rfixed 10 ' ' int) 123456789012345 -- "...9012345" --rfixed :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r) -- | Format the item with a fixed width, padding with the given character -- on either side to extend, adding an ellipsis in the center to shorten. -- -- The total length will be `l + r + 3` characters. -- --
-- >>> format (cfixed 4 3 ' ' int) 123 -- " 123 " ---- --
-- >>> format (cfixed 4 3 ' ' int) 1234567890 -- "1234567890" ---- --
-- >>> format (cfixed 4 3 ' ' int) 123456789012345 -- "1234...345" --cfixed :: Int64 -> Int64 -> Char -> Format r (a -> r) -> Format r (a -> r) -- | Add the given prefix to the formatted item: -- --
-- >>> format ("The answer is: " % prefixed "wait for it... " int) 42
-- "The answer is: wait for it... 42"
--
--
-- -- >>> fprint (unlined (indented 4 (prefixed "- " int))) [1, 2, 3] -- - 1 -- - 2 -- - 3 --prefixed :: Builder -> Format r a -> Format r a -- | Add the given suffix to the formatted item. suffixed :: Builder -> Format r a -> Format r a -- | Surround the output string with the given string: -- --
-- >>> format (surrounded "***" string) "glue" -- "***glue***" --surrounded :: Builder -> Format r a -> Format r a -- | Enclose the output string with the given strings: -- --
-- >>> format (enclosed "<!--" "-->" text) "an html comment" -- "<!--an html comment-->" --enclosed :: Builder -> Builder -> Format r a -> Format r a -- | Add single quotes around the formatted item: -- --
-- >>> let obj = Just Nothing in format ("The object is: " % squoted shown % ".") obj
-- "The object is: 'Just Nothing'."
--
squoted :: Format r a -> Format r a
-- | Add double quotes around the formatted item:
--
--
-- >>> fprintLn ("He said it was based on " % dquoted stext % ".") "science"
-- He said it was based on "science".
--
dquoted :: Format r a -> Format r a
-- | Add parentheses around the formatted item:
--
--
-- >>> format ("We found " % parenthesised int % " discrepancies.") 17
-- "We found (17) discrepancies."
--
--
-- -- >>> fprintLn (took 5 (list (parenthesised int))) [1..] -- [(1), (2), (3), (4), (5)] --parenthesised :: Format r a -> Format r a -- | Add square brackets around the formatted item: -- --
-- >>> format (squared int) 7 -- "[7]" --squared :: Format r a -> Format r a -- | Add curly brackets around the formatted item: -- --
-- >>> format ("\\begin" % braced text) "section"
-- "\\begin{section}"
--
braced :: Format r a -> Format r a
-- | Add angle brackets around the formatted item:
--
-- -- >>> format (angled int) 7 -- "<7>" ---- --
-- >>> format (list (angled text)) ["html", "head", "title", "body", "div", "span"] -- "[<html>, <head>, <title>, <body>, <div>, <span>]" --angled :: Format r a -> Format r a -- | Add backticks around the formatted item: -- --
-- >>> format ("Be sure to run " % backticked builder % " as root.") ":(){:|:&};:"
-- "Be sure to run `:(){:|:&};:` as root."
--
backticked :: Format r a -> Format r a
-- | Insert the given number of spaces at the start of the rendered text:
--
-- -- >>> format (indented 4 int) 7 -- " 7" ---- -- Note that this only indents the first line of a multi-line string. To -- indent all lines see reindented. indented :: Int -> Format r a -> Format r a -- | Format a list of items, placing one per line, indented by the given -- number of spaces. -- --
-- >>> fprintLn ("The lucky numbers are:\n" % indentedLines 4 int) [7, 13, 1, 42]
-- The lucky numbers are:
-- 7
-- 13
-- 1
-- 42
--
indentedLines :: Foldable t => Int -> Format Builder (a -> Builder) -> Format r (t a -> r)
-- | Indent each line of the formatted string by the given number of
-- spaces:
--
-- -- >>> fprint (reindented 2 text) "one\ntwo\nthree" -- one -- two -- three --reindented :: Int -> Format r a -> Format r a -- | Take a fractional number and round it before formatting it as the -- given Format: -- --
-- >>> format (roundedTo int) 6.66 -- "7" -- -- >>> format (list (roundedTo int)) [10.66, 6.66, 1.0, 3.4] -- "[11, 7, 1, 3]" ---- -- Note: the type variable f will almost always be 'Format r', -- so the type of this function can be thought of as: -- --
-- roundedTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r) --roundedTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r) -- | Take a fractional number and truncate it before formatting it as the -- given Format: -- --
-- >>> format (truncatedTo int) 6.66 -- "6" -- -- >>> format (list (truncatedTo int)) [10.66, 6.66, 1.0, 3.4] -- "[10, 6, 1, 3]" ---- -- Note: the type variable f will almost always be 'Format r', -- so the type of this function can be thought of as: -- --
-- truncatedTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r) --truncatedTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r) -- | Take a fractional number and ceiling it before formatting it as the -- given Format: -- --
-- >>> format (ceilingedTo int) 6.66 -- "7" -- -- >>> format (list (ceilingedTo int)) [10.66, 6.66, 1.0, 3.4] -- "[11, 7, 1, 4]" ---- -- Note: the type variable f will almost always be 'Format r', -- so the type of this function can be thought of as: -- --
-- ceilingedTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r) --ceilingedTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r) -- | Take a fractional number and floor it before formatting it as the -- given Format: -- --
-- >>> format (flooredTo int) 6.66 -- "6" -- -- >>> format (list (flooredTo int)) [10.66, 6.66, 1.0, 3.4] -- "[10, 6, 1, 3]" ---- -- Note: the type variable f will almost always be 'Format r', -- so the type of this function can be thought of as: -- --
-- flooredTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r) --flooredTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r) -- | Use the given lens to view an item, formatting it with the given -- formatter. -- -- You can think of this as having the type: -- --
-- viewed :: Lens' s a -> Format r (a -> r) -> Format r (s -> r) ---- --
-- >>> format (viewed _1 int) (1, "hello") -- "1" ---- -- This is useful when combined with the Monoid instance for Format, -- because it allows us to give a data structure as an argument only -- once, and deconstruct it with the formatters: -- --
-- data Person = Person
-- { _personName :: Text
-- , _personAge :: Int
-- }
-- makeLenses ''Person
--
-- me :: Person
-- me = Person Alex 38
--
-- format ("The person's name is " % squoted (viewed personName text) % ", and their age is " <> viewed personAge int) me
-- "The person's name is Alex, and their age is 38"
--
viewed :: ((a -> Const a b) -> s -> Const a t) -> Format r (a -> r) -> Format r (s -> r)
-- | Access an element of the structure and format it with the given
-- formatter.
--
-- -- >>> format (accessed fst int) (1, "hello") -- "1" ---- -- Repeating the example from viewed: -- -- format ("The person's name is " % squoted (accessed _personName text) -- % ", and their age is " <> accessed _personAge int) me "The -- person's name is Alex, and their age is 38" accessed :: (s -> a) -> Format r (a -> r) -> Format r (s -> r) -- | Render an integer using binary notation with a leading 0b, padding -- with zeroes to the given width: -- --
-- >>> format (binPrefix 16) 4097 -- "0b0001000000000001" --binPrefix :: Integral a => Int64 -> Format r (a -> r) -- | Render an integer using octal notation with a leading 0o, padding with -- zeroes to the given width: -- --
-- >>> format (octPrefix 16) 4097 -- "0o0000000000010001" --octPrefix :: Integral a => Int64 -> Format r (a -> r) -- | Render an integer using octal notation with a leading 0x, padding with -- zeroes to the given width: -- --
-- >>> format (hexPrefix 16) 4097 -- "0x0000000000001001" --hexPrefix :: Integral a => Int64 -> Format r (a -> r) -- | Combinator-based type-safe formatting (like printf() or FORMAT) for -- Text. -- -- Example: -- --
-- >>> format ("Person's name is " % text % ", age is " % hex) "Dave" 54
--
--
-- See Formatting.Formatters for a list of formatters. See
-- Formatting.Combinators for a list of formatting combinators,
-- for combining and altering formatters.
module Formatting
-- | A formatter. When you construct formatters the first type parameter,
-- r, will remain polymorphic. The second type parameter,
-- a, will change to reflect the types of the data that will be
-- formatted. For example, in
--
-- -- myFormat :: Format r (Text -> Int -> r) -- myFormat = "Person's name is " % text % ", age is " % hex ---- -- the first type parameter remains polymorphic, and the second type -- parameter is Text -> Int -> r, which indicates that it -- formats a Text and an Int. -- -- When you run the Format, for example with format, you -- provide the arguments and they will be formatted into a string. -- --
-- > format ("Person's name is " % text % ", age is " % hex) "Dave" 54
-- "Person's name is Dave, age is 36"
--
data Format r a
-- | Concatenate two formatters.
--
-- formatter1 % formatter2 is a formatter that accepts arguments
-- for formatter1 and formatter2 and concatenates their
-- results. For example
--
-- -- format1 :: Format r (Text -> r) -- format1 = "Person's name is " % text ---- --
-- format2 :: Format r r -- format2 = ", " ---- --
-- format3 :: Format r (Int -> r) -- format3 = "age is " % hex ---- --
-- myFormat :: Format r (Text -> Int -> r) -- myFormat = format1 % format2 % format3 ---- -- Notice how the argument types of format1 and format3 -- are gathered into the type of myFormat. -- -- (This is actually the composition operator for Formats -- Category instance, but that is (at present) inconvenient to use -- with regular Prelude. So this function is provided as a -- convenience.) (%) :: Format r a -> Format r' r -> Format r' a infixr 9 % -- | Function compose two formatters. Will feed the result of one formatter -- into another. (%.) :: Format r (Builder -> r') -> Format r' a -> Format r a infixr 8 %. -- | Don't format any data, just output a constant Builder. now :: Builder -> Format r r -- | Format a value of type a using a function of type a -> -- Builder. For example, later (f :: Int -> -- Builder) produces Format r (Int -> r). later :: (a -> Builder) -> Format r (a -> r) -- | Functorial map over a formatter's input. Example: format (mapf -- (drop 1) string) "hello" mapf :: (a -> b) -> Format r (b -> t) -> Format r (a -> t) runFormat :: Format r a -> (Builder -> r) -> a -- | Run the formatter and return a lazy Text value. format :: Format Text a -> a -- | Run the formatter and return a strict Text value. sformat :: Format Text a -> a -- | Run the formatter and return a Builder value. bprint :: Format Builder a -> a -- | Run the formatter and return a Builder value. -- -- This is a newer synonym for bprint, following the naming -- convention set by format and sformat. bformat :: Format Builder a -> a -- | Run the formatter and print out the text to stdout. fprint :: Format (IO ()) a -> a -- | Run the formatter and print out the text to stdout, followed by a -- newline. fprintLn :: Format (IO ()) a -> a -- | Run the formatter and put the output onto the given Handle. hprint :: Handle -> Format (IO ()) a -> a -- | Run the formatter and put the output and a newline onto the given -- Handle. hprintLn :: Handle -> Format (IO ()) a -> a -- | Run the formatter and return a list of characters. formatToString :: Format String a -> a -- | Examples that should always compile. If reading on Haddock, you can -- view the sources to each of these. module Formatting.Examples -- | Simple hello, world! hello :: Text -- | Printing strings. strings :: Text -- | Printing texts. texts :: Text -- | Printing builders. builders :: Text -- | Printing integers. integers :: Text -- | Printing floating points. floats :: Text -- | Printing integrals in hex (base-16). hexes :: Text -- | Padding. padding :: Text -- | Formatters for high-res, real-time and timer clock values from -- System.Clock. module Formatting.Clock -- | Same as durationNS but works on TimeSpec from the -- clock package. timeSpecs :: Format r (TimeSpec -> TimeSpec -> r) -- | Reexports of things that were previously in the text-format -- package. module Formatting.Internal.Raw -- | Pad the left hand side of a string until it reaches k -- characters wide, if necessary filling with character c. left :: Buildable a => Int -> Char -> a -> Builder -- | Pad the right hand side of a string until it reaches k -- characters wide, if necessary filling with character c. right :: Buildable a => Int -> Char -> a -> Builder -- | Render an integer using hexadecimal notation. (No leading "0x" is -- added.) hex :: Integral a => a -> Builder -- | Render a floating point number using normal notation, with the given -- number of decimal places. fixed :: Real a => Int -> a -> Builder -- | Render a floating point number using the smallest number of digits -- that correctly represent it. shortest :: Real a => a -> Builder -- | The normal mappend function with right associativity instead of -- left. (<>) :: Builder -> Builder -> Builder infixr 4 <> -- | Unsafe conversion for decimal digits. i2d :: Int -> Char -- | Render a value using its Show instance. newtype Shown a Shown :: a -> Shown a [shown] :: Shown a -> a -- | Render an integral type in hexadecimal. newtype Hex a Hex :: a -> Hex a -- | Single letters for short formatting. module Formatting.ShortFormatters -- | Output a lazy text. t :: Format r (Text -> r) -- | Render an integral e.g. 123 -> "123", 0 -> "0". d :: Integral a => Format r (a -> r) -- | Render an integer using binary notation. (No leading 0b is added.) b :: Integral a => Format r (a -> r) -- | Render an integer using octal notation. (No leading 0o is added.) o :: Integral a => Format r (a -> r) -- | Render an integer using hexadecimal notation. (No leading 0x is -- added.) x :: Integral a => Format r (a -> r) -- | Output a strict text. st :: Format r (Text -> r) -- | Output a string. s :: Format r (String -> r) -- | Output a showable value (instance of Show) by turning it into -- Text. sh :: Show a => Format r (a -> r) -- | Output a character. c :: Format r (Char -> r) -- | Render a floating point number using normal notation, with the given -- number of decimal places. f :: Real a => Int -> Format r (a -> r) -- | Render a floating point number using the smallest number of digits -- that correctly represent it. sf :: Real a => Format r (a -> r) -- | Pad the left hand side of a string until it reaches k -- characters wide, if necessary filling with character ch. l :: Buildable a => Int -> Char -> Format r (a -> r) -- | Pad the right hand side of a string until it reaches k -- characters wide, if necessary filling with character ch. r :: Buildable a => Int -> Char -> Format r (a -> r) -- | Formatters for time. module Formatting.Time -- | Timezone offset on the format -HHMM. tz :: FormatTime a => Format r (a -> r) -- | Timezone name. tzName :: FormatTime a => Format r (a -> r) -- | As dateTimeFmt locale (e.g. %a %b %e %H:%M:%S %Z -- %Y). datetime :: FormatTime a => Format r (a -> r) -- | Same as %H:%M. hm :: FormatTime a => Format r (a -> r) -- | Same as %H:%M:%S. hms :: FormatTime a => Format r (a -> r) -- | As timeFmt locale (e.g. %H:%M:%S). hmsL :: FormatTime a => Format r (a -> r) -- | As time12Fmt locale (e.g. %I:%M:%S %p). hmsPL :: FormatTime a => Format r (a -> r) -- | Day half from (amPm locale), converted to lowercase, -- am, pm. dayHalf :: FormatTime a => Format r (a -> r) -- | Day half from (amPm locale), AM, -- PM. dayHalfU :: FormatTime a => Format r (a -> r) -- | Hour, 24-hour, leading 0 as needed, 00 - 23. hour24 :: FormatTime a => Format r (a -> r) -- | Hour, 12-hour, leading 0 as needed, 01 - 12. hour12 :: FormatTime a => Format r (a -> r) -- | Hour, 24-hour, leading space as needed, 0 - 23. hour24S :: FormatTime a => Format r (a -> r) -- | Hour, 12-hour, leading space as needed, 1 - 12. hour12S :: FormatTime a => Format r (a -> r) -- | Minute, 00 - 59. minute :: FormatTime a => Format r (a -> r) -- | Second, without decimal part, 00 - 60. second :: FormatTime a => Format r (a -> r) -- | Picosecond, including trailing zeros, 000000000000 - -- 999999999999. pico :: FormatTime a => Format r (a -> r) -- | Decimal point and up to 12 second decimals, without trailing zeros. -- For a whole number of seconds, this produces the empty string. decimals :: FormatTime a => Format r (a -> r) epoch :: FormatTime a => Format r (a -> r) -- | Same as %m/%d/%y. dateSlash :: FormatTime a => Format r (a -> r) -- | Same as %Y-%m-%d. dateDash :: FormatTime a => Format r (a -> r) -- | As dateFmt locale (e.g. %m/%d/%y). dateSlashL :: FormatTime a => Format r (a -> r) -- | Year. year :: FormatTime a => Format r (a -> r) -- | Last two digits of year, 00 - 99. yy :: FormatTime a => Format r (a -> r) -- | Century (being the first two digits of the year), 00 - -- 99. century :: FormatTime a => Format r (a -> r) -- | Month name, long form (fst from months -- locale), January - December. monthName :: FormatTime a => Format r (a -> r) -- | %H] month name, short form (snd from months -- locale), Jan - Dec@. monthNameShort :: FormatTime a => Format r (a -> r) -- | Month of year, leading 0 as needed, 01 - 12. month :: FormatTime a => Format r (a -> r) -- | Day of month, leading 0 as needed, 01 - 31. dayOfMonth :: FormatTime a => Format r (a -> r) -- | Day of month, 1st, 2nd, 25th, etc. dayOfMonthOrd :: FormatTime a => Format r (a -> r) -- | Day of month, leading space as needed, 1 - 31. dayOfMonthS :: FormatTime a => Format r (a -> r) -- | Day of year for Ordinal Date format, 001 - 366. day :: FormatTime a => Format r (a -> r) -- | Year for Week Date format e.g. 2013. weekYear :: FormatTime a => Format r (a -> r) -- | Last two digits of year for Week Date format, 00 - -- 99. weekYY :: FormatTime a => Format r (a -> r) -- | Century (first two digits of year) for Week Date format, 00 - -- 99. weekCentury :: FormatTime a => Format r (a -> r) -- | Week for Week Date format, 01 - 53. week :: FormatTime a => Format r (a -> r) -- | Day for Week Date format, 1 - 7. dayOfWeek :: FormatTime a => Format r (a -> r) -- | Day of week, short form (snd from wDays -- locale), Sun - Sat. dayNameShort :: FormatTime a => Format r (a -> r) -- | Day of week, long form (fst from wDays -- locale), Sunday - Saturday. dayName :: FormatTime a => Format r (a -> r) -- | Week number of year, where weeks start on Sunday (as -- sundayStartWeek), 00 - 53. weekFromZero :: FormatTime a => Format r (a -> r) -- | Day of week number, 0 (= Sunday) - 6 (= Saturday). dayOfWeekFromZero :: FormatTime a => Format r (a -> r) -- | Week number of year, where weeks start on Monday (as -- mondayStartWeek), 00 - 53. weekOfYearMon :: FormatTime a => Format r (a -> r) -- | Display a time span as one time relative to another. Input is assumed -- to be seconds. Typical inputs are NominalDiffTime and -- DiffTime. diff :: RealFrac n => Bool -> Format r (n -> r) -- | Display the absolute value time span in years. years :: RealFrac n => Int -> Format r (n -> r) -- | Display the absolute value time span in days. days :: RealFrac n => Int -> Format r (n -> r) -- | Display the absolute value time span in hours. hours :: RealFrac n => Int -> Format r (n -> r) -- | Display the absolute value time span in minutes. minutes :: RealFrac n => Int -> Format r (n -> r) -- | Display the absolute value time span in seconds. seconds :: RealFrac n => Int -> Format r (n -> r) -- | Display seconds in the following pattern: 00:00:00:00, which -- ranges from days to seconds. diffComponents :: RealFrac n => Format r (n -> r) -- | Variation of diffComponents, which lets you explicitly specify -- how to render each component. customDiffComponents :: RealFrac n => (forall r'. Format r' (Integer -> Integer -> Integer -> Integer -> r')) -> Format r (n -> r) -- | Formatter call. Probably don't want to use this. fmt :: FormatTime a => Text -> a -> Text -- | Helper for creating custom time formatters customTimeFmt :: FormatTime a => Text -> Format r (a -> r)