Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: packages/charted/lib/locale/format/number_format.dart

Issue 1521693002: Roll Observatory deps (charted -> ^0.3.0) (Closed) Base URL: https://chromium.googlesource.com/external/github.com/dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. All rights reserved. 2 * Copyright 2014 Google Inc. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style 4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at 5 * license that can be found in the LICENSE file or at
6 * https://developers.google.com/open-source/licenses/bsd 6 * https://developers.google.com/open-source/licenses/bsd
7 */ 7 */
8 part of charted.locale.format; 8 part of charted.locale.format;
9 9
10 /** 10 /**
11 * The number formatter of a given locale. Applying the locale specific 11 * The number formatter of a given locale. Applying the locale specific
12 * number format, number grouping and currency symbol, etc.. The format 12 * number format, number grouping and currency symbol, etc.. The format
13 * function in the NumberFormat class is used to format a number by the given 13 * function in the NumberFormat class is used to format a number by the given
14 * specifier with the number properties of the locale. 14 * specifier with the number properties of the locale.
15 */ 15 */
16 class NumberFormat { 16 class NumberFormat {
17
18 // [[fill]align][sign][symbol][0][width][,][.precision][type] 17 // [[fill]align][sign][symbol][0][width][,][.precision][type]
19 static RegExp FORMAT_REGEX = 18 static RegExp FORMAT_REGEX = new RegExp(
20 new RegExp(r'(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?' 19 r'(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?'
21 r'(\.-?\d+)?([a-z%])?', caseSensitive: false); 20 r'(\.-?\d+)?([a-z%])?',
21 caseSensitive: false);
22 22
23 String localeDecimal; 23 String localeDecimal;
24 String localeThousands; 24 String localeThousands;
25 List localeGrouping; 25 List localeGrouping;
26 List localeCurrency; 26 List localeCurrency;
27 Function formatGroup; 27 Function formatGroup;
28 28
29 NumberFormat(Locale locale) { 29 NumberFormat(Locale locale) {
30 localeDecimal = locale.decimal; 30 localeDecimal = locale.decimal;
31 localeThousands = locale.thousands; 31 localeThousands = locale.thousands;
32 localeGrouping = locale.grouping; 32 localeGrouping = locale.grouping;
33 localeCurrency = locale.currency; 33 localeCurrency = locale.currency;
34 formatGroup = (localeGrouping != null) ? (value) { 34 formatGroup = (localeGrouping != null)
35 var i = value.length, 35 ? (value) {
36 t = [], 36 var i = value.length, t = [], j = 0, g = localeGrouping[0];
37 j = 0, 37 while (i > 0 && g > 0) {
38 g = localeGrouping[0]; 38 if (i - g >= 0) {
39 while (i > 0 && g > 0) { 39 i = i - g;
40 if (i - g >= 0) { 40 } else {
41 i = i - g; 41 g = i;
42 } else { 42 i = 0;
43 g = i; 43 }
44 i = 0; 44 var length = (i + g) < value.length ? (i + g) : value.length;
45 } 45 t.add(value.substring(i, length));
46 var length = (i + g) < value.length ? (i + g) : value.length; 46 g = localeGrouping[j = (j + 1) % localeGrouping.length];
47 t.add(value.substring(i, length)); 47 }
48 g = localeGrouping[j = (j + 1) % localeGrouping.length]; 48 return t.reversed.join(localeThousands);
49 } 49 }
50 return t.reversed.join(localeThousands); 50 : (x) => x;
51 } : (x) => x;
52 } 51 }
53 52
54 /** 53 /**
55 * Returns a new format function with the given string specifier. A format 54 * Returns a new format function with the given string specifier. A format
56 * function takes a number as the only argument, and returns a string 55 * function takes a number as the only argument, and returns a string
57 * representing the formatted number. The format specifier is modeled after 56 * representing the formatted number. The format specifier is modeled after
58 * Python 3.1's built-in format specification mini-language. The general form 57 * Python 3.1's built-in format specification mini-language. The general form
59 * of a specifier is: 58 * of a specifier is:
60 * [​[fill]align][sign][symbol][0][width][,][.precision][type]. 59 * [​[fill]align][sign][symbol][0][width][,][.precision][type].
61 * 60 *
62 * @see <a href="http://docs.python.org/release/3.1.3/library/string.html#form atspec">format specification mini-language</a> 61 * @see <a href="http://docs.python.org/release/3.1.3/library/string.html#form atspec">format specification mini-language</a>
63 */ 62 */
64 FormatFunction format(String specifier) { 63 FormatFunction format(String specifier) {
65 Match match = FORMAT_REGEX.firstMatch(specifier); 64 Match match = FORMAT_REGEX.firstMatch(specifier);
66 var fill = match.group(1) != null ? match.group(1) : ' ', 65 var fill = match.group(1) != null ? match.group(1) : ' ',
67 align = match.group(2) != null ? match.group(2) : '>', 66 align = match.group(2) != null ? match.group(2) : '>',
68 sign = match.group(3) != null ? match.group(3) : '', 67 sign = match.group(3) != null ? match.group(3) : '',
69 symbol = match.group(4) != null ? match.group(4) : '', 68 symbol = match.group(4) != null ? match.group(4) : '',
70 zfill = match.group(5), 69 zfill = match.group(5),
71 width = match.group(6) != null ? int.parse(match.group(6)) : 0, 70 width = match.group(6) != null ? int.parse(match.group(6)) : 0,
72 comma = match.group(7) != null, 71 comma = match.group(7) != null,
73 precision = match.group(8) != null ? 72 precision =
74 int.parse(match.group(8).substring(1)) : null, 73 match.group(8) != null ? int.parse(match.group(8).substring(1)) : null,
75 type = match.group(9), 74 type = match.group(9),
76 scale = 1, 75 scale = 1,
77 prefix = '', 76 prefix = '',
78 suffix = '', 77 suffix = '',
79 integer = false; 78 integer = false;
80 79
81 if (zfill != null || fill == '0' && align == '=') { 80 if (zfill != null || fill == '0' && align == '=') {
82 zfill = fill = '0'; 81 zfill = fill = '0';
83 align = '='; 82 align = '=';
84 if (comma) { 83 if (comma) {
85 width -= ((width - 1) / 4).floor(); 84 width -= ((width - 1) / 4).floor();
86 } 85 }
87 } 86 }
88 87
89 switch (type) { 88 switch (type) {
90 case 'n': comma = true; type = 'g'; break; 89 case 'n':
91 case '%': scale = 100; suffix = '%'; type = 'f'; break; 90 comma = true;
92 case 'p': scale = 100; suffix = '%'; type = 'r'; break; 91 type = 'g';
92 break;
93 case '%':
94 scale = 100;
95 suffix = '%';
96 type = 'f';
97 break;
98 case 'p':
99 scale = 100;
100 suffix = '%';
101 type = 'r';
102 break;
93 case 'b': 103 case 'b':
94 case 'o': 104 case 'o':
95 case 'x': 105 case 'x':
96 case 'X': if (symbol == '#') prefix = '0' + type.toLowerCase(); break; 106 case 'X':
107 if (symbol == '#') prefix = '0' + type.toLowerCase();
108 break;
97 case 'c': 109 case 'c':
98 case 'd': integer = true; precision = 0; break; 110 case 'd':
99 case 's': scale = -1; type = 'r'; break; 111 integer = true;
112 precision = 0;
113 break;
114 case 's':
115 scale = -1;
116 type = 'r';
117 break;
100 } 118 }
101 119
102 if (symbol == '\$') { 120 if (symbol == '\$') {
103 prefix = localeCurrency[0]; 121 prefix = localeCurrency[0];
104 suffix = localeCurrency[1]; 122 suffix = localeCurrency[1];
105 } 123 }
106 124
107 // If no precision is specified for r, fallback to general notation. 125 // If no precision is specified for r, fallback to general notation.
108 if (type == 'r' && precision == null) { 126 if (type == 'r' && precision == null) {
109 type = 'g'; 127 type = 'g';
(...skipping 24 matching lines...) Expand all
134 value = -value; 152 value = -value;
135 negative = '-'; 153 negative = '-';
136 } else { 154 } else {
137 negative = sign; 155 negative = sign;
138 } 156 }
139 157
140 // Apply the scale, computing it from the value's exponent for si 158 // Apply the scale, computing it from the value's exponent for si
141 // format. Preserve the existing suffix, if any, such as the 159 // format. Preserve the existing suffix, if any, such as the
142 // currency symbol. 160 // currency symbol.
143 if (scale < 0) { 161 if (scale < 0) {
144 FormatPrefix unit = new FormatPrefix(value, 162 FormatPrefix unit =
145 (precision != null) ? precision : 0); 163 new FormatPrefix(value, (precision != null) ? precision : 0);
146 value = unit.scale(value); 164 value = unit.scale(value);
147 fullSuffix = unit.symbol + suffix; 165 fullSuffix = unit.symbol + suffix;
148 } else { 166 } else {
149 value *= scale; 167 value *= scale;
150 } 168 }
151 169
152 // Convert to the desired precision. 170 // Convert to the desired precision.
153 if (precision != null) { 171 if (precision != null) {
154 value = formatFunction(value, precision); 172 value = formatFunction(value, precision);
155 } else { 173 } else {
156 value = formatFunction(value); 174 value = formatFunction(value);
157 } 175 }
158 176
159 // Break the value into the integer part (before) and decimal part 177 // Break the value into the integer part (before) and decimal part
160 // (after). 178 // (after).
161 var i = value.lastIndexOf('.'), 179 var i = value.lastIndexOf('.'),
162 before = i < 0 ? value : value.substring(0, i), 180 before = i < 0 ? value : value.substring(0, i),
163 after = i < 0 ? '' : localeDecimal + value.substring(i + 1); 181 after = i < 0 ? '' : localeDecimal + value.substring(i + 1);
164 182
165 // If the fill character is not '0', grouping is applied before 183 // If the fill character is not '0', grouping is applied before
166 //padding. 184 //padding.
167 if (zfill == null && comma) { 185 if (zfill == null && comma) {
168 before = formatGroup(before); 186 before = formatGroup(before);
169 } 187 }
170 188
171 var length = prefix.length + before.length + after.length + 189 var length = prefix.length +
190 before.length +
191 after.length +
172 (zcomma ? 0 : negative.length), 192 (zcomma ? 0 : negative.length),
173 padding = length < width ? new List.filled( 193 padding = length < width
174 (length = width - length + 1), '').join(fill) : ''; 194 ? new List.filled((length = width - length + 1), '').join(fill)
195 : '';
175 196
176 // If the fill character is '0', grouping is applied after padding. 197 // If the fill character is '0', grouping is applied after padding.
177 if (zcomma) { 198 if (zcomma) {
178 before = formatGroup(padding + before); 199 before = formatGroup(padding + before);
179 } 200 }
180 201
181 // Apply prefix. 202 // Apply prefix.
182 negative += prefix; 203 negative += prefix;
183 204
184 // Rejoin integer and decimal parts. 205 // Rejoin integer and decimal parts.
185 value = before + after; 206 value = before + after;
186 207
187 // Apply any padding and alignment attributes before returning the string. 208 // Apply any padding and alignment attributes before returning the string.
188 return (align == '<' ? negative + value + padding 209 return (align == '<'
189 : align == '>' ? padding + negative + value 210 ? negative + value + padding
190 : align == '^' ? padding.substring(0, length >>= 1) + negative + 211 : align == '>'
191 value + padding.substring(length) 212 ? padding + negative + value
192 : negative + (zcomma ? value : padding + value)) + fullSuffix; 213 : align == '^'
214 ? padding.substring(0, length >>= 1) +
215 negative +
216 value +
217 padding.substring(length)
218 : negative + (zcomma ? value : padding + value)) +
219 fullSuffix;
193 }; 220 };
194 } 221 }
195 222
196 // Gets the format function by given type. 223 // Gets the format function by given type.
197 NumberFormatFunction _getFormatFunction(String type) { 224 NumberFormatFunction _getFormatFunction(String type) {
198 switch(type) { 225 switch (type) {
199 case 'b': 226 case 'b':
200 return (num x, [int p = 0]) => x.toInt().toRadixString(2); 227 return (num x, [int p = 0]) => x.toInt().toRadixString(2);
201 case 'c': 228 case 'c':
202 return (num x, [int p = 0]) => new String.fromCharCodes([x]); 229 return (num x, [int p = 0]) => new String.fromCharCodes([x]);
203 case 'o': 230 case 'o':
204 return (num x, [int p = 0]) => x.toInt().toRadixString(8); 231 return (num x, [int p = 0]) => x.toInt().toRadixString(8);
205 case 'x': 232 case 'x':
206 return (num x, [int p = 0]) => x.toInt().toRadixString(16); 233 return (num x, [int p = 0]) => x.toInt().toRadixString(16);
207 case 'X': 234 case 'X':
208 return (num x, [int p = 0]) => 235 return (num x, [int p = 0]) =>
209 x.toInt().toRadixString(16).toUpperCase(); 236 x.toInt().toRadixString(16).toUpperCase();
210 case 'g': 237 case 'g':
211 return (num x, [int p = 1]) => x.toStringAsPrecision(p); 238 return (num x, [int p = 1]) => x.toStringAsPrecision(p);
212 case 'e': 239 case 'e':
213 return (num x, [int p = 0]) => x.toStringAsExponential(p); 240 return (num x, [int p = 0]) => x.toStringAsExponential(p);
214 case 'f': 241 case 'f':
215 return (num x, [int p = 0]) => x.toStringAsFixed(p); 242 return (num x, [int p = 0]) => x.toStringAsFixed(p);
216 case 'r': 243 case 'r':
217 default: 244 default:
218 return (num x, [int p = 0]) => x.toString(); 245 return (num x, [int p = 0]) => x.toString();
219 } 246 }
220 } 247 }
221 } 248 }
OLDNEW
« no previous file with comments | « packages/charted/lib/locale/format.dart ('k') | packages/charted/lib/locale/format/time_format.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698