From 8d6630c4477c75c5f8bc8b68e1cfcd8876f8ad85 Mon Sep 17 00:00:00 2001 From: Alexei Date: Mon, 11 Sep 2023 14:40:54 +0100 Subject: [PATCH 1/2] feat: add an `n` specifier that prints nothing --- README.md | 1 + src/sprintf.js | 11 +++++++++-- test/test.js | 6 ++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ef74f5..61d0114 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ The placeholders in the format string are marked by `%` and are followed by one * `u` — yields an integer as an unsigned decimal number * `f` — yields a float as is; see notes on precision above * `g` — yields a float as is; see notes on precision above + * `n` — yields nothing * `o` — yields an integer as an octal number * `s` — yields a string as is * `t` — yields `true` or `false` diff --git a/src/sprintf.js b/src/sprintf.js index 65d6324..d92d130 100644 --- a/src/sprintf.js +++ b/src/sprintf.js @@ -8,13 +8,14 @@ not_bool: /[^t]/, not_type: /[^T]/, not_primitive: /[^v]/, + nothing: /[n]/, number: /[diefg]/, numeric_arg: /[bcdiefguxX]/, json: /[j]/, not_json: /[^j]/, text: /^[^\x25]+/, modulo: /^\x25{2}/, - placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/, + placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijnostTuvxX])/, key: /^([a-z_][a-z_\d]*)/i, key_access: /^\.([a-z_][a-z_\d]*)/i, index_access: /^\[(\d+)\]/, @@ -89,6 +90,9 @@ case 'g': arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg) break + case 'n': + arg = '' + break case 'o': arg = (parseInt(arg, 10) >>> 0).toString(8) break @@ -118,7 +122,10 @@ arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase() break } - if (re.json.test(ph.type)) { + if (re.nothing.test(ph.type)) { + output += arg + } + else if (re.json.test(ph.type)) { output += arg } else { diff --git a/test/test.js b/test/test.js index 9588da6..ce00e29 100644 --- a/test/test.js +++ b/test/test.js @@ -58,6 +58,10 @@ describe('sprintfjs', function() { assert.equal('1,2,3', sprintf('%v', [1, 2, 3])) assert.equal('[object Object]', sprintf('%v', {foo: 'bar'})) assert.equal('/<("[^"]*"|\'[^\']*\'|[^\'">])*>/', sprintf('%v', /<("[^"]*"|'[^']*'|[^'">])*>/)) + + assert.equal('', sprintf('%n', 42)) + assert.equal('', sprintf('%2$n', 'foo', 'bar', 'baz')) + assert.equal('Hello !', sprintf('Hello %(name)n!', {name: 'world'})) }) it('should return formated strings for complex placeholders', function() { @@ -104,6 +108,8 @@ describe('sprintfjs', function() { assert.equal('xxxxx', sprintf('%5.5s', 'xxxxxx')) assert.equal(' x', sprintf('%5.1s', 'xxxxxx')) + // mixed nothing + assert.equal('', sprintf("%+'#10n", -123)) }) it('should return formated strings for callbacks', function() { From d9733d9b18ed31c2b1b8f2d05e213c0a993f1346 Mon Sep 17 00:00:00 2001 From: Alexei Date: Mon, 11 Sep 2023 14:48:06 +0100 Subject: [PATCH 2/2] test: add a new test to make sure `%n` moves the cursor --- test/test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test.js b/test/test.js index ce00e29..61c2f28 100644 --- a/test/test.js +++ b/test/test.js @@ -110,6 +110,7 @@ describe('sprintfjs', function() { // mixed nothing assert.equal('', sprintf("%+'#10n", -123)) + assert.equal('foobaz', sprintf('%s%n%s', 'foo', 'bar', 'baz')) }) it('should return formated strings for callbacks', function() {