@@ -7,6 +7,7 @@ module Text.Format
7
7
, zeroFill
8
8
, signed
9
9
, precision
10
+ , decimalMark
10
11
, class Format
11
12
, format
12
13
) where
@@ -18,7 +19,7 @@ import Data.Unfoldable (replicate)
18
19
import Data.Int as Int
19
20
import Data.Maybe (Maybe (..), fromMaybe )
20
21
import Data.Monoid (class Monoid )
21
- import Data.String (length , fromCharArray , dropWhile )
22
+ import Data.String (length , fromCharArray , dropWhile , singleton , replace , Pattern (..), Replacement (..) )
22
23
import Math (round , pow , abs )
23
24
24
25
-- | Pad a string on the left up to a given maximum length. The padding
@@ -32,6 +33,7 @@ type PropertiesRecord =
32
33
, padChar :: Maybe Char
33
34
, signed :: Maybe Boolean
34
35
, precision :: Maybe Int
36
+ , decimalMark :: Maybe Char
35
37
}
36
38
37
39
default :: PropertiesRecord
@@ -40,6 +42,7 @@ default =
40
42
, padChar: Nothing
41
43
, signed: Nothing
42
44
, precision: Nothing
45
+ , decimalMark: Nothing
43
46
}
44
47
45
48
data Properties = Properties PropertiesRecord
@@ -49,17 +52,19 @@ instance eqProperties :: Eq Properties where
49
52
rec1.width == rec2.width &&
50
53
rec1.padChar == rec2.padChar &&
51
54
rec1.signed == rec2.signed &&
52
- rec1.precision == rec2.precision
55
+ rec1.precision == rec2.precision &&
56
+ rec1.decimalMark == rec2.decimalMark
53
57
54
58
instance semigroupProperties :: Semigroup Properties where
55
59
append (Properties rec1) (Properties rec2) = Properties rec
56
60
where
57
61
-- These are combined such that options to the right take precedence:
58
62
-- width 3 <> width 4 == width 4
59
- rec = { width: rec2.width <|> rec1.width
60
- , padChar: rec2.padChar <|> rec1.padChar
61
- , signed: rec2.signed <|> rec1.signed
62
- , precision: rec2.precision <|> rec1.precision
63
+ rec = { width: rec2.width <|> rec1.width
64
+ , padChar: rec2.padChar <|> rec1.padChar
65
+ , signed: rec2.signed <|> rec1.signed
66
+ , precision: rec2.precision <|> rec1.precision
67
+ , decimalMark: rec2.decimalMark <|> rec1.decimalMark
63
68
}
64
69
65
70
instance monoidProperties :: Monoid Properties where
@@ -82,6 +87,10 @@ signed = Properties (default { signed = Just true })
82
87
precision :: Int -> Properties
83
88
precision digits = Properties (default { precision = Just digits })
84
89
90
+ -- | Delimiter character. Gets ignored for non-numeric types.
91
+ decimalMark :: Char -> Properties
92
+ decimalMark char = Properties (default { decimalMark = Just char })
93
+
85
94
-- | A class for types that can be formatted using the specified properties.
86
95
class Format a where
87
96
format :: Properties -> a -> String
@@ -141,11 +150,15 @@ instance formatNumber :: Format Number where
141
150
isSigned = fromMaybe false rec.signed
142
151
padChar = fromMaybe ' ' rec.padChar
143
152
nonNegative = num >= 0.0
144
- numAbsStr' = show (abs num)
153
+ numAbsStr'' = show (abs num)
154
+ numAbsStr' = case rec.decimalMark of
155
+ Nothing -> numAbsStr''
156
+ Just d -> replace (Pattern " ." ) (Replacement (singleton d)) numAbsStr''
145
157
numAbsStr = case rec.precision of
146
158
Nothing -> numAbsStr'
147
159
Just p -> numAbsStr' <> paddedZeros p
148
- paddedZeros p = let d = length (dropWhile (_ /= ' .' ) numAbsStr') - 1
160
+ usedDelimiter = fromMaybe ' .' rec.decimalMark
161
+ paddedZeros p = let d = length (dropWhile (_ /= usedDelimiter) numAbsStr') - 1
149
162
in fromCharArray (replicate (p - d) ' 0' )
150
163
numSgn = if nonNegative
151
164
then (if isSigned then " +" else " " )
0 commit comments