UNPKG

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