UNPKG

5.88 kBJavaScriptView Raw
1'use strict';
2
3var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4
5var formatNumber = require('./number').format;
6var formatBigNumber = require('./bignumber/formatter').format;
7var isBigNumber = require('./bignumber/isBigNumber');
8
9/**
10 * Test whether value is a string
11 * @param {*} value
12 * @return {boolean} isString
13 */
14exports.isString = function (value) {
15 return typeof value === 'string';
16};
17
18/**
19 * Check if a text ends with a certain string.
20 * @param {string} text
21 * @param {string} search
22 */
23exports.endsWith = function (text, search) {
24 var start = text.length - search.length;
25 var end = text.length;
26 return text.substring(start, end) === search;
27};
28
29/**
30 * Format a value of any type into a string.
31 *
32 * Usage:
33 * math.format(value)
34 * math.format(value, precision)
35 *
36 * When value is a function:
37 *
38 * - When the function has a property `syntax`, it returns this
39 * syntax description.
40 * - In other cases, a string `'function'` is returned.
41 *
42 * When `value` is an Object:
43 *
44 * - When the object contains a property `format` being a function, this
45 * function is invoked as `value.format(options)` and the result is returned.
46 * - When the object has its own `toString` method, this method is invoked
47 * and the result is returned.
48 * - In other cases the function will loop over all object properties and
49 * return JSON object notation like '{"a": 2, "b": 3}'.
50 *
51 * Example usage:
52 * math.format(2/7) // '0.2857142857142857'
53 * math.format(math.pi, 3) // '3.14'
54 * math.format(new Complex(2, 3)) // '2 + 3i'
55 * math.format('hello') // '"hello"'
56 *
57 * @param {*} value Value to be stringified
58 * @param {Object | number | Function} [options] Formatting options. See
59 * lib/utils/number:format for a
60 * description of the available
61 * options.
62 * @return {string} str
63 */
64exports.format = function (value, options) {
65 if (typeof value === 'number') {
66 return formatNumber(value, options);
67 }
68
69 if (isBigNumber(value)) {
70 return formatBigNumber(value, options);
71 }
72
73 // note: we use unsafe duck-typing here to check for Fractions, this is
74 // ok here since we're only invoking toString or concatenating its values
75 if (looksLikeFraction(value)) {
76 if (!options || options.fraction !== 'decimal') {
77 // output as ratio, like '1/3'
78 return value.s * value.n + '/' + value.d;
79 } else {
80 // output as decimal, like '0.(3)'
81 return value.toString();
82 }
83 }
84
85 if (Array.isArray(value)) {
86 return formatArray(value, options);
87 }
88
89 if (exports.isString(value)) {
90 return '"' + value + '"';
91 }
92
93 if (typeof value === 'function') {
94 return value.syntax ? String(value.syntax) : 'function';
95 }
96
97 if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
98 if (typeof value.format === 'function') {
99 return value.format(options);
100 } else if (value && value.toString() !== {}.toString()) {
101 // this object has a non-native toString method, use that one
102 return value.toString();
103 } else {
104 var entries = [];
105
106 for (var key in value) {
107 if (value.hasOwnProperty(key)) {
108 entries.push('"' + key + '": ' + exports.format(value[key], options));
109 }
110 }
111
112 return '{' + entries.join(', ') + '}';
113 }
114 }
115
116 return String(value);
117};
118
119/**
120 * Stringify a value into a string enclosed in double quotes.
121 * Unescaped double quotes and backslashes inside the value are escaped.
122 * @param {*} value
123 * @return {string}
124 */
125exports.stringify = function (value) {
126 var text = String(value);
127 var escaped = '';
128 var i = 0;
129 while (i < text.length) {
130 var c = text.charAt(i);
131
132 if (c === '\\') {
133 escaped += c;
134 i++;
135
136 c = text.charAt(i);
137 if (c === '' || '"\\/bfnrtu'.indexOf(c) === -1) {
138 escaped += '\\'; // no valid escape character -> escape it
139 }
140 escaped += c;
141 } else if (c === '"') {
142 escaped += '\\"';
143 } else {
144 escaped += c;
145 }
146 i++;
147 }
148
149 return '"' + escaped + '"';
150};
151
152/**
153 * Escape special HTML characters
154 * @param {*} value
155 * @return {string}
156 */
157exports.escape = function (value) {
158 var text = String(value);
159 text = text.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
160
161 return text;
162};
163
164/**
165 * Recursively format an n-dimensional matrix
166 * Example output: "[[1, 2], [3, 4]]"
167 * @param {Array} array
168 * @param {Object | number | Function} [options] Formatting options. See
169 * lib/utils/number:format for a
170 * description of the available
171 * options.
172 * @returns {string} str
173 */
174function formatArray(array, options) {
175 if (Array.isArray(array)) {
176 var str = '[';
177 var len = array.length;
178 for (var i = 0; i < len; i++) {
179 if (i !== 0) {
180 str += ', ';
181 }
182 str += formatArray(array[i], options);
183 }
184 str += ']';
185 return str;
186 } else {
187 return exports.format(array, options);
188 }
189}
190
191/**
192 * Check whether a value looks like a Fraction (unsafe duck-type check)
193 * @param {*} value
194 * @return {boolean}
195 */
196function looksLikeFraction(value) {
197 return value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && typeof value.s === 'number' && typeof value.n === 'number' && typeof value.d === 'number' || false;
198}
\No newline at end of file