UNPKG

6.3 kBJavaScriptView Raw
1import { isBigNumber, isString, typeOf } from './is.js';
2import { format as formatNumber } from './number.js';
3import { format as formatBigNumber } from './bignumber/formatter.js';
4/**
5 * Check if a text ends with a certain string.
6 * @param {string} text
7 * @param {string} search
8 */
9
10export function endsWith(text, search) {
11 var start = text.length - search.length;
12 var end = text.length;
13 return text.substring(start, end) === search;
14}
15/**
16 * Format a value of any type into a string.
17 *
18 * Usage:
19 * math.format(value)
20 * math.format(value, precision)
21 * math.format(value, options)
22 *
23 * When value is a function:
24 *
25 * - When the function has a property `syntax`, it returns this
26 * syntax description.
27 * - In other cases, a string `'function'` is returned.
28 *
29 * When `value` is an Object:
30 *
31 * - When the object contains a property `format` being a function, this
32 * function is invoked as `value.format(options)` and the result is returned.
33 * - When the object has its own `toString` method, this method is invoked
34 * and the result is returned.
35 * - In other cases the function will loop over all object properties and
36 * return JSON object notation like '{"a": 2, "b": 3}'.
37 *
38 * Example usage:
39 * math.format(2/7) // '0.2857142857142857'
40 * math.format(math.pi, 3) // '3.14'
41 * math.format(new Complex(2, 3)) // '2 + 3i'
42 * math.format('hello') // '"hello"'
43 *
44 * @param {*} value Value to be stringified
45 * @param {Object | number | Function} [options]
46 * Formatting options. See src/utils/number.js:format for a
47 * description of the available options controlling number output.
48 * This generic "format" also supports the option property `truncate: NN`
49 * giving the maximum number NN of characters to return (if there would
50 * have been more, they are deleted and replaced by an ellipsis).
51 * @return {string} str
52 */
53
54export function format(value, options) {
55 var result = _format(value, options);
56
57 if (options && typeof options === 'object' && 'truncate' in options && result.length > options.truncate) {
58 return result.substring(0, options.truncate - 3) + '...';
59 }
60
61 return result;
62}
63
64function _format(value, options) {
65 if (typeof value === 'number') {
66 return formatNumber(value, options);
67 }
68
69 if (isBigNumber(value)) {
70 return formatBigNumber(value, options);
71 } // note: we use unsafe duck-typing here to check for Fractions, this is
72 // ok here since we're only invoking toString or concatenating its values
73
74
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 (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 === 'object') {
98 if (typeof value.format === 'function') {
99 return value.format(options);
100 } else if (value && value.toString(options) !== {}.toString()) {
101 // this object has a non-native toString method, use that one
102 return value.toString(options);
103 } else {
104 var entries = Object.keys(value).map(key => {
105 return '"' + key + '": ' + format(value[key], options);
106 });
107 return '{' + entries.join(', ') + '}';
108 }
109 }
110
111 return String(value);
112}
113/**
114 * Stringify a value into a string enclosed in double quotes.
115 * Unescaped double quotes and backslashes inside the value are escaped.
116 * @param {*} value
117 * @return {string}
118 */
119
120
121export function stringify(value) {
122 var text = String(value);
123 var escaped = '';
124 var i = 0;
125
126 while (i < text.length) {
127 var c = text.charAt(i);
128
129 if (c === '\\') {
130 escaped += c;
131 i++;
132 c = text.charAt(i);
133
134 if (c === '' || '"\\/bfnrtu'.indexOf(c) === -1) {
135 escaped += '\\'; // no valid escape character -> escape it
136 }
137
138 escaped += c;
139 } else if (c === '"') {
140 escaped += '\\"';
141 } else {
142 escaped += c;
143 }
144
145 i++;
146 }
147
148 return '"' + escaped + '"';
149}
150/**
151 * Escape special HTML characters
152 * @param {*} value
153 * @return {string}
154 */
155
156export function escape(value) {
157 var text = String(value);
158 text = text.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
159 return text;
160}
161/**
162 * Recursively format an n-dimensional matrix
163 * Example output: "[[1, 2], [3, 4]]"
164 * @param {Array} array
165 * @param {Object | number | Function} [options] Formatting options. See
166 * lib/utils/number:format for a
167 * description of the available
168 * options.
169 * @returns {string} str
170 */
171
172function formatArray(array, options) {
173 if (Array.isArray(array)) {
174 var str = '[';
175 var len = array.length;
176
177 for (var i = 0; i < len; i++) {
178 if (i !== 0) {
179 str += ', ';
180 }
181
182 str += formatArray(array[i], options);
183 }
184
185 str += ']';
186 return str;
187 } else {
188 return format(array, options);
189 }
190}
191/**
192 * Check whether a value looks like a Fraction (unsafe duck-type check)
193 * @param {*} value
194 * @return {boolean}
195 */
196
197
198function looksLikeFraction(value) {
199 return value && typeof value === 'object' && typeof value.s === 'number' && typeof value.n === 'number' && typeof value.d === 'number' || false;
200}
201/**
202 * Compare two strings
203 * @param {string} x
204 * @param {string} y
205 * @returns {number}
206 */
207
208
209export function compareText(x, y) {
210 // we don't want to convert numbers to string, only accept string input
211 if (!isString(x)) {
212 throw new TypeError('Unexpected type of argument in function compareText ' + '(expected: string or Array or Matrix, actual: ' + typeOf(x) + ', index: 0)');
213 }
214
215 if (!isString(y)) {
216 throw new TypeError('Unexpected type of argument in function compareText ' + '(expected: string or Array or Matrix, actual: ' + typeOf(y) + ', index: 1)');
217 }
218
219 return x === y ? 0 : x > y ? 1 : -1;
220}
\No newline at end of file