Initial check-in
[dygraphs.git] / mochikit_v14 / MochiKit / Format.js
1 /***
2
3 MochiKit.Format 1.4
4
5 See <http://mochikit.com/> for documentation, downloads, license, etc.
6
7 (c) 2005 Bob Ippolito. All rights Reserved.
8
9 ***/
10
11 if (typeof(dojo) != 'undefined') {
12 dojo.provide('MochiKit.Format');
13 }
14
15 if (typeof(MochiKit) == 'undefined') {
16 MochiKit = {};
17 }
18
19 if (typeof(MochiKit.Format) == 'undefined') {
20 MochiKit.Format = {};
21 }
22
23 MochiKit.Format.NAME = "MochiKit.Format";
24 MochiKit.Format.VERSION = "1.4";
25 MochiKit.Format.__repr__ = function () {
26 return "[" + this.NAME + " " + this.VERSION + "]";
27 };
28 MochiKit.Format.toString = function () {
29 return this.__repr__();
30 };
31
32 MochiKit.Format._numberFormatter = function (placeholder, header, footer, locale, isPercent, precision, leadingZeros, separatorAt, trailingZeros) {
33 return function (num) {
34 num = parseFloat(num);
35 if (typeof(num) == "undefined" || num === null || isNaN(num)) {
36 return placeholder;
37 }
38 var curheader = header;
39 var curfooter = footer;
40 if (num < 0) {
41 num = -num;
42 } else {
43 curheader = curheader.replace(/-/, "");
44 }
45 var me = arguments.callee;
46 var fmt = MochiKit.Format.formatLocale(locale);
47 if (isPercent) {
48 num = num * 100.0;
49 curfooter = fmt.percent + curfooter;
50 }
51 num = MochiKit.Format.roundToFixed(num, precision);
52 var parts = num.split(/\./);
53 var whole = parts[0];
54 var frac = (parts.length == 1) ? "" : parts[1];
55 var res = "";
56 while (whole.length < leadingZeros) {
57 whole = "0" + whole;
58 }
59 if (separatorAt) {
60 while (whole.length > separatorAt) {
61 var i = whole.length - separatorAt;
62 //res = res + fmt.separator + whole.substring(i, whole.length);
63 res = fmt.separator + whole.substring(i, whole.length) + res;
64 whole = whole.substring(0, i);
65 }
66 }
67 res = whole + res;
68 if (precision > 0) {
69 while (frac.length < trailingZeros) {
70 frac = frac + "0";
71 }
72 res = res + fmt.decimal + frac;
73 }
74 return curheader + res + curfooter;
75 };
76 };
77
78 /** @id MochiKit.Format.numberFormatter */
79 MochiKit.Format.numberFormatter = function (pattern, placeholder/* = "" */, locale/* = "default" */) {
80 // http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html
81 // | 0 | leading or trailing zeros
82 // | # | just the number
83 // | , | separator
84 // | . | decimal separator
85 // | % | Multiply by 100 and format as percent
86 if (typeof(placeholder) == "undefined") {
87 placeholder = "";
88 }
89 var match = pattern.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
90 if (!match) {
91 throw TypeError("Invalid pattern");
92 }
93 var header = pattern.substr(0, match.index);
94 var footer = pattern.substr(match.index + match[0].length);
95 if (header.search(/-/) == -1) {
96 header = header + "-";
97 }
98 var whole = match[1];
99 var frac = (typeof(match[2]) == "string" && match[2] != "") ? match[2] : "";
100 var isPercent = (typeof(match[3]) == "string" && match[3] != "");
101 var tmp = whole.split(/,/);
102 var separatorAt;
103 if (typeof(locale) == "undefined") {
104 locale = "default";
105 }
106 if (tmp.length == 1) {
107 separatorAt = null;
108 } else {
109 separatorAt = tmp[1].length;
110 }
111 var leadingZeros = whole.length - whole.replace(/0/g, "").length;
112 var trailingZeros = frac.length - frac.replace(/0/g, "").length;
113 var precision = frac.length;
114 var rval = MochiKit.Format._numberFormatter(
115 placeholder, header, footer, locale, isPercent, precision,
116 leadingZeros, separatorAt, trailingZeros
117 );
118 var m = MochiKit.Base;
119 if (m) {
120 var fn = arguments.callee;
121 var args = m.concat(arguments);
122 rval.repr = function () {
123 return [
124 self.NAME,
125 "(",
126 map(m.repr, args).join(", "),
127 ")"
128 ].join("");
129 };
130 }
131 return rval;
132 };
133
134 /** @id MochiKit.Format.formatLocale */
135 MochiKit.Format.formatLocale = function (locale) {
136 if (typeof(locale) == "undefined" || locale === null) {
137 locale = "default";
138 }
139 if (typeof(locale) == "string") {
140 var rval = MochiKit.Format.LOCALE[locale];
141 if (typeof(rval) == "string") {
142 rval = arguments.callee(rval);
143 MochiKit.Format.LOCALE[locale] = rval;
144 }
145 return rval;
146 } else {
147 return locale;
148 }
149 };
150
151 /** @id MochiKit.Format.twoDigitAverage */
152 MochiKit.Format.twoDigitAverage = function (numerator, denominator) {
153 if (denominator) {
154 var res = numerator / denominator;
155 if (!isNaN(res)) {
156 return MochiKit.Format.twoDigitFloat(numerator / denominator);
157 }
158 }
159 return "0";
160 };
161
162 /** @id MochiKit.Format.twoDigitFloat */
163 MochiKit.Format.twoDigitFloat = function (someFloat) {
164 var sign = (someFloat < 0 ? '-' : '');
165 var s = Math.floor(Math.abs(someFloat) * 100).toString();
166 if (s == '0') {
167 return s;
168 }
169 if (s.length < 3) {
170 while (s.charAt(s.length - 1) == '0') {
171 s = s.substring(0, s.length - 1);
172 }
173 return sign + '0.' + s;
174 }
175 var head = sign + s.substring(0, s.length - 2);
176 var tail = s.substring(s.length - 2, s.length);
177 if (tail == '00') {
178 return head;
179 } else if (tail.charAt(1) == '0') {
180 return head + '.' + tail.charAt(0);
181 } else {
182 return head + '.' + tail;
183 }
184 };
185
186 /** @id MochiKit.Format.lstrip */
187 MochiKit.Format.lstrip = function (str, /* optional */chars) {
188 str = str + "";
189 if (typeof(str) != "string") {
190 return null;
191 }
192 if (!chars) {
193 return str.replace(/^\s+/, "");
194 } else {
195 return str.replace(new RegExp("^[" + chars + "]+"), "");
196 }
197 };
198
199 /** @id MochiKit.Format.rstrip */
200 MochiKit.Format.rstrip = function (str, /* optional */chars) {
201 str = str + "";
202 if (typeof(str) != "string") {
203 return null;
204 }
205 if (!chars) {
206 return str.replace(/\s+$/, "");
207 } else {
208 return str.replace(new RegExp("[" + chars + "]+$"), "");
209 }
210 };
211
212 /** @id MochiKit.Format.strip */
213 MochiKit.Format.strip = function (str, /* optional */chars) {
214 var self = MochiKit.Format;
215 return self.rstrip(self.lstrip(str, chars), chars);
216 };
217
218 /** @id MochiKit.Format.truncToFixed */
219 MochiKit.Format.truncToFixed = function (aNumber, precision) {
220 aNumber = Math.floor(aNumber * Math.pow(10, precision));
221 var res = (aNumber * Math.pow(10, -precision)).toFixed(precision);
222 if (res.charAt(0) == ".") {
223 res = "0" + res;
224 }
225 return res;
226 };
227
228 /** @id MochiKit.Format.roundToFixed */
229 MochiKit.Format.roundToFixed = function (aNumber, precision) {
230 return MochiKit.Format.truncToFixed(
231 aNumber + 0.5 * Math.pow(10, -precision),
232 precision
233 );
234 };
235
236 /** @id MochiKit.Format.percentFormat */
237 MochiKit.Format.percentFormat = function (someFloat) {
238 return MochiKit.Format.twoDigitFloat(100 * someFloat) + '%';
239 };
240
241 MochiKit.Format.EXPORT = [
242 "truncToFixed",
243 "roundToFixed",
244 "numberFormatter",
245 "formatLocale",
246 "twoDigitAverage",
247 "twoDigitFloat",
248 "percentFormat",
249 "lstrip",
250 "rstrip",
251 "strip"
252 ];
253
254 MochiKit.Format.LOCALE = {
255 en_US: {separator: ",", decimal: ".", percent: "%"},
256 de_DE: {separator: ".", decimal: ",", percent: "%"},
257 fr_FR: {separator: " ", decimal: ",", percent: "%"},
258 "default": "en_US"
259 };
260
261 MochiKit.Format.EXPORT_OK = [];
262 MochiKit.Format.EXPORT_TAGS = {
263 ':all': MochiKit.Format.EXPORT,
264 ':common': MochiKit.Format.EXPORT
265 };
266
267 MochiKit.Format.__new__ = function () {
268 // MochiKit.Base.nameFunctions(this);
269 var base = this.NAME + ".";
270 var k, v, o;
271 for (k in this.LOCALE) {
272 o = this.LOCALE[k];
273 if (typeof(o) == "object") {
274 o.repr = function () { return this.NAME; };
275 o.NAME = base + "LOCALE." + k;
276 }
277 }
278 for (k in this) {
279 o = this[k];
280 if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
281 try {
282 o.NAME = base + k;
283 } catch (e) {
284 // pass
285 }
286 }
287 }
288 };
289
290 MochiKit.Format.__new__();
291
292 if (typeof(MochiKit.Base) != "undefined") {
293 MochiKit.Base._exportSymbols(this, MochiKit.Format);
294 } else {
295 (function (globals, module) {
296 if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined')
297 || (MochiKit.__export__ === false)) {
298 var all = module.EXPORT_TAGS[":all"];
299 for (var i = 0; i < all.length; i++) {
300 globals[all[i]] = module[all[i]];
301 }
302 }
303 })(this, MochiKit.Format);
304 }