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 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` with ANSI control characters escaped.
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 debugColors whether to use colors in debug formatting
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.formatParam = exports.buildString = exports.RsString = void 0;
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 out = strings[0];
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 || ref_number >= params.length) {
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
- out += param.toString() + string.substring(1);
61
- continue;
66
+ string = string.substring(1);
67
+ skipParsing = true;
62
68
  }
63
69
  }
64
- else {
65
- out += param.toString() + string;
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 formatted = formatParam(param, {
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
- out += formatted + string.substring(idx);
164
+ let escaped_string = string.substring(idx);
165
+ colored += formatted_colored + escaped_string;
166
+ raw += formatted_raw + escaped_string;
156
167
  }
157
- return { raw: node_util_1.default.stripVTControlCharacters(out), colored: out };
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 debugColors whether to use colors in debug formatting
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
- // Process parameter type
172
- switch (format.type) {
173
- case 'o':
174
- param = param.toString(8);
175
- break;
176
- case 'x':
177
- param = param.toString(16);
178
- break;
179
- case 'X':
180
- param = param.toString(16).toUpperCase();
181
- break;
182
- case 'b':
183
- param = param.toString(2);
184
- break;
185
- case 'e':
186
- case 'E':
187
- if (param_type != 'number' && param_type != 'bigint') {
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
- param = param.toLocaleString('en-US', { notation: 'scientific', maximumFractionDigits: 20 });
192
- if (format.type == 'e')
193
- param = param.toLowercase();
194
- break;
195
- case 'n':
196
- case 'N':
197
- if (param_type != 'number' && param_type != 'bigint') {
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 ( /*!filled && */format.width > param.length) {
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
- * Tag to use Rust-style formatting in a template literal.
5
- * Returns an extended `String` object.
6
- *
7
- * @returns a String object with the formatted string
8
- */
9
- export declare function rs(strings: TemplateStringsArray, ...params: any[]): RsString;
10
- export declare namespace rs {
11
- var raw: (strings: TemplateStringsArray, ...params: any[]) => string;
12
- var ref: (n: number) => {
13
- __rs_param_ref: number;
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
- * Tag to use Rust-style formatting in a template literal.
13
- * Returns an extended `String` object.
14
- *
15
- * @returns a String object with the formatted string
16
- */
17
- function rs(strings, ...params) {
18
- return new format_1.RsString(strings, params);
19
- }
20
- exports.rs = rs;
21
- /**
22
- * Tag to use Rust-style formatting in a template literal.
23
- * Returns a `string` primitive.
24
- *
25
- * @returns a string primitive of the formatted string
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
- /// <reference types="node" />
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.dbg = exports.eprintln = exports.eprint = exports.println = exports.print = exports.printToStream = void 0;
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(true);
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsformat",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Formatting/printing library for JavaScript that takes after rust's string formatting ",
5
5
  "files": [
6
6
  "lib",