rsformat 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/format.d.ts +2 -4
- package/lib/format.js +102 -83
- package/lib/index.d.ts +38 -12
- package/lib/index.js +14 -25
- package/lib/print.d.ts +9 -3
- package/lib/print.js +15 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ let number = 14;
|
|
|
43
43
|
let info = rs`${number+1} is ${rs.ref(0)}:x in hex`; // info == '15 is f in hex'
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
> NB: templates tagged with `rs` are instances of a special class `RsString` that extends `String`, rather than a primitive value. This is to enable colors for debug formatting inside the printing functions. This difference should not affect normal usage, but `rs.raw` can be used as an alternative tag to get a primitive `string
|
|
46
|
+
> NB: templates tagged with `rs` are instances of a special class `RsString` that extends `String`, rather than a primitive value. This is to enable colors for debug formatting inside the printing functions. This difference should not affect normal usage, but `rs.raw` can be used as an alternative tag to get a primitive `string`.
|
|
47
47
|
|
|
48
48
|
The printing functions can be called with plain strings, instances of `String` or templates formatted with `rs`:
|
|
49
49
|
|
package/lib/format.d.ts
CHANGED
|
@@ -37,12 +37,10 @@ type FormatSpecifier = {
|
|
|
37
37
|
};
|
|
38
38
|
/**
|
|
39
39
|
* Format a parameter as a string according to a specifier.
|
|
40
|
-
* Will include colors in the output of debug formating
|
|
41
40
|
*
|
|
42
41
|
* @param param parameter to format
|
|
43
42
|
* @param format format specifier object
|
|
44
|
-
* @param
|
|
45
|
-
* @returns `param` as a formatted string
|
|
43
|
+
* @returns `param` as a debug-colored and raw formatted string
|
|
46
44
|
*/
|
|
47
|
-
export declare function formatParam(param: any, format: FormatSpecifier): string;
|
|
45
|
+
export declare function formatParam(param: any, format: FormatSpecifier): [string, string];
|
|
48
46
|
export {};
|
package/lib/format.js
CHANGED
|
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.RsString = void 0;
|
|
7
|
+
exports.buildString = buildString;
|
|
8
|
+
exports.formatParam = formatParam;
|
|
7
9
|
const node_util_1 = __importDefault(require("node:util"));
|
|
8
10
|
const is_digit = (c) => c >= '0' && c <= '9';
|
|
9
11
|
const error = (param, char, reason) => new Error(`rs[param ${param}, char ${char}] ${reason}`);
|
|
@@ -37,7 +39,8 @@ exports.RsString = RsString;
|
|
|
37
39
|
* @returns An object with raw and colored versions of the formatted parameter
|
|
38
40
|
*/
|
|
39
41
|
function buildString(strings, params) {
|
|
40
|
-
let
|
|
42
|
+
let raw = strings[0];
|
|
43
|
+
let colored = strings[0];
|
|
41
44
|
for (let i = 1; i < strings.length; ++i) {
|
|
42
45
|
let string = strings[i];
|
|
43
46
|
let param = params[i - 1];
|
|
@@ -45,7 +48,9 @@ function buildString(strings, params) {
|
|
|
45
48
|
while (typeof param == 'object' && '__rs_param_ref' in param) {
|
|
46
49
|
let ref_number = param.__rs_param_ref;
|
|
47
50
|
if (typeof ref_number != 'number'
|
|
48
|
-
|| ref_number < 0
|
|
51
|
+
|| ref_number < 0
|
|
52
|
+
|| ref_number >= params.length
|
|
53
|
+
|| !Number.isInteger(ref_number)) {
|
|
49
54
|
throw new Error(`Parameter ${i - 1}: Invalid reference`);
|
|
50
55
|
}
|
|
51
56
|
if (ref_number == i - 1)
|
|
@@ -55,14 +60,18 @@ function buildString(strings, params) {
|
|
|
55
60
|
// Parse format specifier
|
|
56
61
|
// If the string starts with a single : it has a format specifier,
|
|
57
62
|
// If it has two the first : is being escaped and can be removed
|
|
63
|
+
let skipParsing = false;
|
|
58
64
|
if (string[0] == ':') {
|
|
59
65
|
if (string[1] == ':') {
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
string = string.substring(1);
|
|
67
|
+
skipParsing = true;
|
|
62
68
|
}
|
|
63
69
|
}
|
|
64
|
-
else
|
|
65
|
-
|
|
70
|
+
else
|
|
71
|
+
skipParsing = true;
|
|
72
|
+
if (skipParsing) {
|
|
73
|
+
raw += param.toString(param instanceof String ? false : undefined) + string;
|
|
74
|
+
colored += param.toString(param instanceof String ? true : undefined) + string;
|
|
66
75
|
continue;
|
|
67
76
|
}
|
|
68
77
|
;
|
|
@@ -142,7 +151,7 @@ function buildString(strings, params) {
|
|
|
142
151
|
throw error(i - 1, idx, `Expected colon (':') or space character (' '/'\\t'/'\\r'/'\\n') at end of formatting specifier (found '${string[idx]}')`);
|
|
143
152
|
}
|
|
144
153
|
// Format parameter according to specifier
|
|
145
|
-
let
|
|
154
|
+
let [formatted_colored, formatted_raw] = formatParam(param, {
|
|
146
155
|
fill,
|
|
147
156
|
align,
|
|
148
157
|
force_sign,
|
|
@@ -152,92 +161,100 @@ function buildString(strings, params) {
|
|
|
152
161
|
precision,
|
|
153
162
|
type: format_type
|
|
154
163
|
});
|
|
155
|
-
|
|
164
|
+
let escaped_string = string.substring(idx);
|
|
165
|
+
colored += formatted_colored + escaped_string;
|
|
166
|
+
raw += formatted_raw + escaped_string;
|
|
156
167
|
}
|
|
157
|
-
return { raw
|
|
168
|
+
return { raw, colored };
|
|
158
169
|
}
|
|
159
|
-
exports.buildString = buildString;
|
|
160
170
|
/**
|
|
161
171
|
* Format a parameter as a string according to a specifier.
|
|
162
|
-
* Will include colors in the output of debug formating
|
|
163
172
|
*
|
|
164
173
|
* @param param parameter to format
|
|
165
174
|
* @param format format specifier object
|
|
166
|
-
* @param
|
|
167
|
-
* @returns `param` as a formatted string
|
|
175
|
+
* @returns `param` as a debug-colored and raw formatted string
|
|
168
176
|
*/
|
|
169
177
|
function formatParam(param, format) {
|
|
170
178
|
let param_type = typeof param;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
179
|
+
let param_colored = "";
|
|
180
|
+
// embed RsStrings directly
|
|
181
|
+
if (param instanceof String && format.type != '?') {
|
|
182
|
+
console.log("rsString passed");
|
|
183
|
+
param_colored = param.toString(true);
|
|
184
|
+
param = param.toString(false);
|
|
185
|
+
}
|
|
186
|
+
else
|
|
187
|
+
switch (format.type) {
|
|
188
|
+
// Process format type
|
|
189
|
+
case 'o':
|
|
190
|
+
param = param.toString(8);
|
|
191
|
+
break;
|
|
192
|
+
case 'x':
|
|
193
|
+
param = param.toString(16);
|
|
194
|
+
break;
|
|
195
|
+
case 'X':
|
|
196
|
+
param = param.toString(16).toUpperCase();
|
|
197
|
+
break;
|
|
198
|
+
case 'b':
|
|
199
|
+
param = param.toString(2);
|
|
200
|
+
break;
|
|
201
|
+
case 'e':
|
|
202
|
+
case 'E':
|
|
203
|
+
if (param_type != 'number' && param_type != 'bigint') {
|
|
204
|
+
param = param.toString();
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
param = param.toLocaleString('en-US', { notation: 'scientific', maximumFractionDigits: 20 });
|
|
208
|
+
if (format.type == 'e')
|
|
209
|
+
param = param.toLowercase();
|
|
210
|
+
break;
|
|
211
|
+
case 'n':
|
|
212
|
+
case 'N':
|
|
213
|
+
if (param_type != 'number' && param_type != 'bigint') {
|
|
214
|
+
param = param.toString();
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
// Round and add suffix
|
|
218
|
+
if (param_type == 'number')
|
|
219
|
+
param = Math.round(param);
|
|
188
220
|
param = param.toString();
|
|
221
|
+
let last_2_digits = param.substring(param.length - 2);
|
|
222
|
+
if (last_2_digits == '11' || last_2_digits == '12' || last_2_digits == '13') {
|
|
223
|
+
param = param + 'th';
|
|
224
|
+
}
|
|
225
|
+
else
|
|
226
|
+
switch (last_2_digits[last_2_digits.length - 1]) {
|
|
227
|
+
case '1':
|
|
228
|
+
param = param + 'st';
|
|
229
|
+
break;
|
|
230
|
+
case '2':
|
|
231
|
+
param = param + 'nd';
|
|
232
|
+
break;
|
|
233
|
+
case '3':
|
|
234
|
+
param = param + 'rd';
|
|
235
|
+
break;
|
|
236
|
+
default: param = param + 'th';
|
|
237
|
+
}
|
|
238
|
+
if (format.type == 'N')
|
|
239
|
+
param = param.toUpperCase();
|
|
240
|
+
// Do not pad with zeroes or align to precision when using ordinal formatting
|
|
241
|
+
format.pad_zeroes = false;
|
|
242
|
+
format.precision = -1;
|
|
189
243
|
break;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
244
|
+
case '?':
|
|
245
|
+
param_colored = node_util_1.default.inspect(param, {
|
|
246
|
+
depth: Infinity,
|
|
247
|
+
colors: true,
|
|
248
|
+
compact: !format.pretty
|
|
249
|
+
});
|
|
250
|
+
param = node_util_1.default.stripVTControlCharacters(param_colored);
|
|
251
|
+
// Do not force sign, pad with zeroes or align to precision when using debug formatting
|
|
252
|
+
param_type = 'string';
|
|
253
|
+
break;
|
|
254
|
+
default:
|
|
198
255
|
param = param.toString();
|
|
199
256
|
break;
|
|
200
|
-
|
|
201
|
-
// Round and add suffix
|
|
202
|
-
if (param_type == 'number')
|
|
203
|
-
param = Math.round(param);
|
|
204
|
-
param = param.toString();
|
|
205
|
-
let last_2_digits = param.substring(param.length - 2);
|
|
206
|
-
if (last_2_digits == '11' || last_2_digits == '12' || last_2_digits == '13') {
|
|
207
|
-
param = param + 'th';
|
|
208
|
-
}
|
|
209
|
-
else
|
|
210
|
-
switch (last_2_digits[last_2_digits.length - 1]) {
|
|
211
|
-
case '1':
|
|
212
|
-
param = param + 'st';
|
|
213
|
-
break;
|
|
214
|
-
case '2':
|
|
215
|
-
param = param + 'nd';
|
|
216
|
-
break;
|
|
217
|
-
case '3':
|
|
218
|
-
param = param + 'rd';
|
|
219
|
-
break;
|
|
220
|
-
default: param = param + 'th';
|
|
221
|
-
}
|
|
222
|
-
if (format.type == 'N')
|
|
223
|
-
param = param.toUpperCase();
|
|
224
|
-
// Do not pad with zeroes or align to precision when using ordinal formatting
|
|
225
|
-
format.pad_zeroes = false;
|
|
226
|
-
format.precision = -1;
|
|
227
|
-
break;
|
|
228
|
-
case '?':
|
|
229
|
-
param = node_util_1.default.inspect(param, {
|
|
230
|
-
depth: Infinity,
|
|
231
|
-
colors: true,
|
|
232
|
-
compact: !format.pretty
|
|
233
|
-
});
|
|
234
|
-
// Do not force sign, pad with zeroes or align to precision when using debug formatting
|
|
235
|
-
param_type = 'string';
|
|
236
|
-
break;
|
|
237
|
-
default:
|
|
238
|
-
param = param.toString();
|
|
239
|
-
break;
|
|
240
|
-
}
|
|
257
|
+
}
|
|
241
258
|
;
|
|
242
259
|
// Compute radix-point precision on numbers
|
|
243
260
|
if (param_type == 'number' && format.precision != -1) {
|
|
@@ -290,7 +307,9 @@ function formatParam(param, format) {
|
|
|
290
307
|
}
|
|
291
308
|
param = maybe_sign + param;
|
|
292
309
|
}
|
|
293
|
-
if (
|
|
310
|
+
if (param_colored == "")
|
|
311
|
+
param_colored = param;
|
|
312
|
+
if (format.width > param.length) {
|
|
294
313
|
// Compute fill/align
|
|
295
314
|
let left = '';
|
|
296
315
|
let right = '';
|
|
@@ -309,7 +328,7 @@ function formatParam(param, format) {
|
|
|
309
328
|
break;
|
|
310
329
|
}
|
|
311
330
|
param = left + param + right;
|
|
331
|
+
param_colored = left + param_colored + right;
|
|
312
332
|
}
|
|
313
|
-
return param;
|
|
333
|
+
return [param_colored, param];
|
|
314
334
|
}
|
|
315
|
-
exports.formatParam = formatParam;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,15 +1,41 @@
|
|
|
1
1
|
import { RsString } from './format';
|
|
2
2
|
export { print, println, eprint, eprintln, dbg } from './print';
|
|
3
|
+
type ParameterReference = {
|
|
4
|
+
__rs_param_ref: number;
|
|
5
|
+
};
|
|
6
|
+
type rs = {
|
|
7
|
+
(strings: TemplateStringsArray, ...params: any[]): RsString;
|
|
8
|
+
/**
|
|
9
|
+
* Tag to use Rust-style formatting in a template literal.
|
|
10
|
+
* Returns a `string` primitive.
|
|
11
|
+
*
|
|
12
|
+
* ```js
|
|
13
|
+
* let number = 14;
|
|
14
|
+
* let info = rs.raw`${number+1} is ${rs.ref(0)}:x in hex`;
|
|
15
|
+
* // info === '15 is f in hex'
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @returns a string primitive of the formatted string
|
|
19
|
+
*/
|
|
20
|
+
raw: (strings: TemplateStringsArray, ...params: any[]) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Reference another parameter in a `rs`-tagged template.
|
|
23
|
+
*
|
|
24
|
+
* @param n Number of parameter to reference
|
|
25
|
+
* @returns A reference to the `n`th parameter
|
|
26
|
+
*/
|
|
27
|
+
ref: (n: number) => ParameterReference;
|
|
28
|
+
};
|
|
3
29
|
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
* Tag to use Rust-style formatting in a template literal.
|
|
31
|
+
* Returns an extended `String` object.
|
|
32
|
+
*
|
|
33
|
+
* ```js
|
|
34
|
+
* let number = 14;
|
|
35
|
+
* let info = rs`${number+1} is ${rs.ref(0)}:x in hex`;
|
|
36
|
+
* // info == '15 is f in hex'
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @returns a String object with the formatted string
|
|
40
|
+
*/
|
|
41
|
+
export declare let rs: rs;
|
package/lib/index.js
CHANGED
|
@@ -9,28 +9,17 @@ Object.defineProperty(exports, "eprint", { enumerable: true, get: function () {
|
|
|
9
9
|
Object.defineProperty(exports, "eprintln", { enumerable: true, get: function () { return print_1.eprintln; } });
|
|
10
10
|
Object.defineProperty(exports, "dbg", { enumerable: true, get: function () { return print_1.dbg; } });
|
|
11
11
|
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*/
|
|
27
|
-
rs.raw = function (strings, ...params) {
|
|
28
|
-
return (0, format_1.buildString)(strings, params).raw;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Reference another parameter in a `rs`-tagged template.
|
|
32
|
-
*
|
|
33
|
-
* @param n Number of parameter to reference
|
|
34
|
-
* @returns A reference to the `n`th parameter
|
|
35
|
-
*/
|
|
36
|
-
rs.ref = (n) => ({ __rs_param_ref: n });
|
|
12
|
+
* Tag to use Rust-style formatting in a template literal.
|
|
13
|
+
* Returns an extended `String` object.
|
|
14
|
+
*
|
|
15
|
+
* ```js
|
|
16
|
+
* let number = 14;
|
|
17
|
+
* let info = rs`${number+1} is ${rs.ref(0)}:x in hex`;
|
|
18
|
+
* // info == '15 is f in hex'
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @returns a String object with the formatted string
|
|
22
|
+
*/
|
|
23
|
+
exports.rs = ((strings, ...params) => new format_1.RsString(strings, params));
|
|
24
|
+
exports.rs.raw = (strings, ...params) => (0, format_1.buildString)(strings, params).raw;
|
|
25
|
+
exports.rs.ref = (n) => ({ __rs_param_ref: n });
|
package/lib/print.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { Writable } from 'node:stream';
|
|
1
|
+
import type { Writable } from 'node:stream';
|
|
3
2
|
/**
|
|
4
|
-
* Print a string (or instance of String/RsString) to a stream.
|
|
3
|
+
* Print a string (or instance of String/RsString) to a `Writable` stream.
|
|
5
4
|
*
|
|
6
5
|
* @param stream Stream to print the string to
|
|
7
6
|
* @param string String to print
|
|
@@ -36,6 +35,13 @@ export declare function eprintln(string: string | String): void;
|
|
|
36
35
|
/**
|
|
37
36
|
* Debug print a value to stderr and return it.
|
|
38
37
|
*
|
|
38
|
+
* ```js
|
|
39
|
+
* let r = Math.random();
|
|
40
|
+
* if(dbg(r < 0.3)) { // prints 'true' or 'false'
|
|
41
|
+
* println("Unlucky!");
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
39
45
|
* @param value Value to debug print
|
|
40
46
|
*/
|
|
41
47
|
export declare function dbg(value: any): any;
|
package/lib/print.js
CHANGED
|
@@ -3,11 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.printToStream = printToStream;
|
|
7
|
+
exports.print = print;
|
|
8
|
+
exports.println = println;
|
|
9
|
+
exports.eprint = eprint;
|
|
10
|
+
exports.eprintln = eprintln;
|
|
11
|
+
exports.dbg = dbg;
|
|
7
12
|
const node_process_1 = __importDefault(require("node:process"));
|
|
8
13
|
const _1 = require(".");
|
|
9
14
|
/**
|
|
10
|
-
* Print a string (or instance of String/RsString) to a stream.
|
|
15
|
+
* Print a string (or instance of String/RsString) to a `Writable` stream.
|
|
11
16
|
*
|
|
12
17
|
* @param stream Stream to print the string to
|
|
13
18
|
* @param string String to print
|
|
@@ -16,13 +21,12 @@ const _1 = require(".");
|
|
|
16
21
|
*/
|
|
17
22
|
function printToStream(stream, string, newline = false, colored = false) {
|
|
18
23
|
if (string instanceof String) {
|
|
19
|
-
string = string.toString(
|
|
24
|
+
string = string.toString(colored);
|
|
20
25
|
}
|
|
21
26
|
if (newline)
|
|
22
27
|
string = string + '\n';
|
|
23
28
|
stream.write(string);
|
|
24
29
|
}
|
|
25
|
-
exports.printToStream = printToStream;
|
|
26
30
|
/**
|
|
27
31
|
* Print a string to stdout.
|
|
28
32
|
*
|
|
@@ -31,7 +35,6 @@ exports.printToStream = printToStream;
|
|
|
31
35
|
function print(string) {
|
|
32
36
|
printToStream(node_process_1.default.stdout, string, false, true);
|
|
33
37
|
}
|
|
34
|
-
exports.print = print;
|
|
35
38
|
/**
|
|
36
39
|
* Print a string to stdout and append a newline.
|
|
37
40
|
*
|
|
@@ -40,7 +43,6 @@ exports.print = print;
|
|
|
40
43
|
function println(string) {
|
|
41
44
|
printToStream(node_process_1.default.stdout, string, true, true);
|
|
42
45
|
}
|
|
43
|
-
exports.println = println;
|
|
44
46
|
/**
|
|
45
47
|
* Print a string to stderr.
|
|
46
48
|
*
|
|
@@ -49,7 +51,6 @@ exports.println = println;
|
|
|
49
51
|
function eprint(string) {
|
|
50
52
|
printToStream(node_process_1.default.stderr, string, false, true);
|
|
51
53
|
}
|
|
52
|
-
exports.eprint = eprint;
|
|
53
54
|
/**
|
|
54
55
|
* Print a string to stderr and append a newline.
|
|
55
56
|
*
|
|
@@ -58,14 +59,19 @@ exports.eprint = eprint;
|
|
|
58
59
|
function eprintln(string) {
|
|
59
60
|
printToStream(node_process_1.default.stderr, string, true, true);
|
|
60
61
|
}
|
|
61
|
-
exports.eprintln = eprintln;
|
|
62
62
|
/**
|
|
63
63
|
* Debug print a value to stderr and return it.
|
|
64
64
|
*
|
|
65
|
+
* ```js
|
|
66
|
+
* let r = Math.random();
|
|
67
|
+
* if(dbg(r < 0.3)) { // prints 'true' or 'false'
|
|
68
|
+
* println("Unlucky!");
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
65
72
|
* @param value Value to debug print
|
|
66
73
|
*/
|
|
67
74
|
function dbg(value) {
|
|
68
75
|
eprintln((0, _1.rs) `${value}:?`);
|
|
69
76
|
return value;
|
|
70
77
|
}
|
|
71
|
-
exports.dbg = dbg;
|