@tannin/sprintf
Advanced tools
Comparing version 1.0.2 to 1.1.0
@@ -6,13 +6,37 @@ 'use strict'; | ||
* | ||
* The pattern for matching named arguments is a naive and incomplete matcher | ||
* against valid JavaScript identifier names. | ||
* | ||
* via Mathias Bynens: | ||
* | ||
* >An identifier must start with $, _, or any character in the Unicode | ||
* >categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase | ||
* >letter (Lt)”, “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter | ||
* >number (Nl)”. | ||
* > | ||
* >The rest of the string can contain the same characters, plus any U+200C zero | ||
* >width non-joiner characters, U+200D zero width joiner characters, and | ||
* >characters in the Unicode categories “Non-spacing mark (Mn)”, “Spacing | ||
* >combining mark (Mc)”, “Decimal digit number (Nd)”, or “Connector | ||
* >punctuation (Pc)”. | ||
* | ||
* If browser support is constrained to those supporting ES2015, this could be | ||
* made more accurate using the `u` flag: | ||
* | ||
* ``` | ||
* /^[$_\p{L}\p{Nl}][$_\p{L}\p{Nl}\u200C\u200D\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/u; | ||
* ``` | ||
* | ||
* @see http://www.pixelbeat.org/programming/gcc/format_specs.html | ||
* @see https://mathiasbynens.be/notes/javascript-identifiers#valid-identifier-names | ||
* | ||
* @type {RegExp} | ||
*/ | ||
var PATTERN = /%((\d+)\$)?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g; | ||
// ▲ ▲ ▲ ▲ ▲ ▲ type | ||
// │ │ │ │ └ Length (unsupported) | ||
// │ │ │ └ Precision / max width | ||
// │ │ └ Min width (unsupported) | ||
// │ └ Flags (unsupported) | ||
// └ Index | ||
var PATTERN = /%(((\d+)\$)|(\(([$_a-zA-Z][$_a-zA-Z0-9]*)\)))?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g; | ||
// ▲ ▲ ▲ ▲ ▲ ▲ ▲ type | ||
// │ │ │ │ │ └ Length (unsupported) | ||
// │ │ │ │ └ Precision / max width | ||
// │ │ │ └ Min width (unsupported) | ||
// │ │ └ Flags (unsupported) | ||
// └ Index └ Name (for named arguments) | ||
@@ -36,3 +60,3 @@ /** | ||
* @param {string} string printf format string | ||
* @param {?Array} args String arguments. | ||
* @param {Array} [args] String arguments. | ||
* | ||
@@ -56,7 +80,8 @@ * @return {string} Formatted string. | ||
return string.replace( PATTERN, function() { | ||
var index, precision, type, value; | ||
var index, name, precision, type, value; | ||
index = arguments[ 2 ]; | ||
precision = arguments[ 4 ]; | ||
type = arguments[ 6 ]; | ||
index = arguments[ 3 ]; | ||
name = arguments[ 5 ]; | ||
precision = arguments[ 7 ]; | ||
type = arguments[ 9 ]; | ||
@@ -75,10 +100,19 @@ // There's no placeholder substitution in the explicit "%", meaning it | ||
// If not a positional argument, use counter value. | ||
if ( index === undefined ) { | ||
index = i; | ||
} | ||
if ( name !== undefined ) { | ||
// If it's a named argument, use name. | ||
if ( args[ 0 ] && typeof args[ 0 ] === 'object' && | ||
args[ 0 ].hasOwnProperty( name ) ) { | ||
value = args[ 0 ][ name ]; | ||
} | ||
} else { | ||
// If not a positional argument, use counter value. | ||
if ( index === undefined ) { | ||
index = i; | ||
} | ||
i++; | ||
i++; | ||
value = args[ index - 1 ]; | ||
// Positional argument. | ||
value = args[ index - 1 ]; | ||
} | ||
@@ -103,3 +137,3 @@ // Parse as type. | ||
// placeholder substitution can be performed. | ||
return value || ''; | ||
return value !== undefined && value !== null ? value : ''; | ||
} ); | ||
@@ -106,0 +140,0 @@ } |
@@ -1,3 +0,13 @@ | ||
## 1.0.2 (Unreleased) | ||
## 1.1.0 (2019-11-27) | ||
New Features | ||
- Add support for named arguments | ||
Bugfix | ||
- Fix handling of falsy values, notably 0 | ||
## 1.0.2 (2019-03-07) | ||
Internal | ||
@@ -4,0 +14,0 @@ |
@@ -7,13 +7,37 @@ var sprintf = (function () { | ||
* | ||
* The pattern for matching named arguments is a naive and incomplete matcher | ||
* against valid JavaScript identifier names. | ||
* | ||
* via Mathias Bynens: | ||
* | ||
* >An identifier must start with $, _, or any character in the Unicode | ||
* >categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase | ||
* >letter (Lt)”, “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter | ||
* >number (Nl)”. | ||
* > | ||
* >The rest of the string can contain the same characters, plus any U+200C zero | ||
* >width non-joiner characters, U+200D zero width joiner characters, and | ||
* >characters in the Unicode categories “Non-spacing mark (Mn)”, “Spacing | ||
* >combining mark (Mc)”, “Decimal digit number (Nd)”, or “Connector | ||
* >punctuation (Pc)”. | ||
* | ||
* If browser support is constrained to those supporting ES2015, this could be | ||
* made more accurate using the `u` flag: | ||
* | ||
* ``` | ||
* /^[$_\p{L}\p{Nl}][$_\p{L}\p{Nl}\u200C\u200D\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/u; | ||
* ``` | ||
* | ||
* @see http://www.pixelbeat.org/programming/gcc/format_specs.html | ||
* @see https://mathiasbynens.be/notes/javascript-identifiers#valid-identifier-names | ||
* | ||
* @type {RegExp} | ||
*/ | ||
var PATTERN = /%((\d+)\$)?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g; | ||
// ▲ ▲ ▲ ▲ ▲ ▲ type | ||
// │ │ │ │ └ Length (unsupported) | ||
// │ │ │ └ Precision / max width | ||
// │ │ └ Min width (unsupported) | ||
// │ └ Flags (unsupported) | ||
// └ Index | ||
var PATTERN = /%(((\d+)\$)|(\(([$_a-zA-Z][$_a-zA-Z0-9]*)\)))?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g; | ||
// ▲ ▲ ▲ ▲ ▲ ▲ ▲ type | ||
// │ │ │ │ │ └ Length (unsupported) | ||
// │ │ │ │ └ Precision / max width | ||
// │ │ │ └ Min width (unsupported) | ||
// │ │ └ Flags (unsupported) | ||
// └ Index └ Name (for named arguments) | ||
@@ -37,3 +61,3 @@ /** | ||
* @param {string} string printf format string | ||
* @param {?Array} args String arguments. | ||
* @param {Array} [args] String arguments. | ||
* | ||
@@ -57,7 +81,8 @@ * @return {string} Formatted string. | ||
return string.replace( PATTERN, function() { | ||
var index, precision, type, value; | ||
var index, name, precision, type, value; | ||
index = arguments[ 2 ]; | ||
precision = arguments[ 4 ]; | ||
type = arguments[ 6 ]; | ||
index = arguments[ 3 ]; | ||
name = arguments[ 5 ]; | ||
precision = arguments[ 7 ]; | ||
type = arguments[ 9 ]; | ||
@@ -76,10 +101,19 @@ // There's no placeholder substitution in the explicit "%", meaning it | ||
// If not a positional argument, use counter value. | ||
if ( index === undefined ) { | ||
index = i; | ||
} | ||
if ( name !== undefined ) { | ||
// If it's a named argument, use name. | ||
if ( args[ 0 ] && typeof args[ 0 ] === 'object' && | ||
args[ 0 ].hasOwnProperty( name ) ) { | ||
value = args[ 0 ][ name ]; | ||
} | ||
} else { | ||
// If not a positional argument, use counter value. | ||
if ( index === undefined ) { | ||
index = i; | ||
} | ||
i++; | ||
i++; | ||
value = args[ index - 1 ]; | ||
// Positional argument. | ||
value = args[ index - 1 ]; | ||
} | ||
@@ -104,3 +138,3 @@ // Parse as type. | ||
// placeholder substitution can be performed. | ||
return value || ''; | ||
return value !== undefined && value !== null ? value : ''; | ||
} ); | ||
@@ -107,0 +141,0 @@ } |
@@ -1,1 +0,1 @@ | ||
var sprintf=function(){"use strict";var t=/%((\d+)\$)?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g;return function(r,a){var i;if(!Array.isArray(a))for(a=new Array(arguments.length-1),i=1;i<arguments.length;i++)a[i-1]=arguments[i];return i=1,r.replace(t,function(){var r,t,n,e;return r=arguments[2],t=arguments[4],"%"===(n=arguments[6])?"%":("*"===t&&(t=a[i-1],i++),void 0===r&&(r=i),i++,e=a[r-1],"f"===n?e=parseFloat(e)||0:"d"===n&&(e=parseInt(e)||0),void 0!==t&&("f"===n?e=e.toFixed(t):"s"===n&&(e=e.substr(0,t))),e||"")})}}(); | ||
var sprintf=function(){"use strict";var t=/%(((\d+)\$)|(\(([$_a-zA-Z][$_a-zA-Z0-9]*)\)))?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g;return function(r,o){var i;if(!Array.isArray(o))for(o=new Array(arguments.length-1),i=1;i<arguments.length;i++)o[i-1]=arguments[i];return i=1,r.replace(t,function(){var r,t,e,n,a;return r=arguments[3],t=arguments[5],e=arguments[7],"%"===(n=arguments[9])?"%":("*"===e&&(e=o[i-1],i++),void 0!==t?o[0]&&"object"==typeof o[0]&&o[0].hasOwnProperty(t)&&(a=o[0][t]):(void 0===r&&(r=i),i++,a=o[r-1]),"f"===n?a=parseFloat(a)||0:"d"===n&&(a=parseInt(a)||0),void 0!==e&&("f"===n?a=a.toFixed(e):"s"===n&&(a=a.substr(0,e))),null!=a?a:"")})}}(); |
72
index.js
/** | ||
* Regular expression matching format placeholder syntax. | ||
* | ||
* The pattern for matching named arguments is a naive and incomplete matcher | ||
* against valid JavaScript identifier names. | ||
* | ||
* via Mathias Bynens: | ||
* | ||
* >An identifier must start with $, _, or any character in the Unicode | ||
* >categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase | ||
* >letter (Lt)”, “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter | ||
* >number (Nl)”. | ||
* > | ||
* >The rest of the string can contain the same characters, plus any U+200C zero | ||
* >width non-joiner characters, U+200D zero width joiner characters, and | ||
* >characters in the Unicode categories “Non-spacing mark (Mn)”, “Spacing | ||
* >combining mark (Mc)”, “Decimal digit number (Nd)”, or “Connector | ||
* >punctuation (Pc)”. | ||
* | ||
* If browser support is constrained to those supporting ES2015, this could be | ||
* made more accurate using the `u` flag: | ||
* | ||
* ``` | ||
* /^[$_\p{L}\p{Nl}][$_\p{L}\p{Nl}\u200C\u200D\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/u; | ||
* ``` | ||
* | ||
* @see http://www.pixelbeat.org/programming/gcc/format_specs.html | ||
* @see https://mathiasbynens.be/notes/javascript-identifiers#valid-identifier-names | ||
* | ||
* @type {RegExp} | ||
*/ | ||
var PATTERN = /%((\d+)\$)?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g; | ||
// ▲ ▲ ▲ ▲ ▲ ▲ type | ||
// │ │ │ │ └ Length (unsupported) | ||
// │ │ │ └ Precision / max width | ||
// │ │ └ Min width (unsupported) | ||
// │ └ Flags (unsupported) | ||
// └ Index | ||
var PATTERN = /%(((\d+)\$)|(\(([$_a-zA-Z][$_a-zA-Z0-9]*)\)))?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g; | ||
// ▲ ▲ ▲ ▲ ▲ ▲ ▲ type | ||
// │ │ │ │ │ └ Length (unsupported) | ||
// │ │ │ │ └ Precision / max width | ||
// │ │ │ └ Min width (unsupported) | ||
// │ │ └ Flags (unsupported) | ||
// └ Index └ Name (for named arguments) | ||
@@ -33,3 +57,3 @@ /** | ||
* @param {string} string printf format string | ||
* @param {?Array} args String arguments. | ||
* @param {Array} [args] String arguments. | ||
* | ||
@@ -53,7 +77,8 @@ * @return {string} Formatted string. | ||
return string.replace( PATTERN, function() { | ||
var index, precision, type, value; | ||
var index, name, precision, type, value; | ||
index = arguments[ 2 ]; | ||
precision = arguments[ 4 ]; | ||
type = arguments[ 6 ]; | ||
index = arguments[ 3 ]; | ||
name = arguments[ 5 ]; | ||
precision = arguments[ 7 ]; | ||
type = arguments[ 9 ]; | ||
@@ -72,10 +97,19 @@ // There's no placeholder substitution in the explicit "%", meaning it | ||
// If not a positional argument, use counter value. | ||
if ( index === undefined ) { | ||
index = i; | ||
} | ||
if ( name !== undefined ) { | ||
// If it's a named argument, use name. | ||
if ( args[ 0 ] && typeof args[ 0 ] === 'object' && | ||
args[ 0 ].hasOwnProperty( name ) ) { | ||
value = args[ 0 ][ name ]; | ||
} | ||
} else { | ||
// If not a positional argument, use counter value. | ||
if ( index === undefined ) { | ||
index = i; | ||
} | ||
i++; | ||
i++; | ||
value = args[ index - 1 ]; | ||
// Positional argument. | ||
value = args[ index - 1 ]; | ||
} | ||
@@ -100,4 +134,4 @@ // Parse as type. | ||
// placeholder substitution can be performed. | ||
return value || ''; | ||
return value !== undefined && value !== null ? value : ''; | ||
} ); | ||
} |
{ | ||
"name": "@tannin/sprintf", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "printf string formatter", | ||
@@ -31,3 +31,3 @@ "main": "build/index.js", | ||
}, | ||
"gitHead": "32fce6eeefdc3db7819004e9044e707604af4cd9" | ||
"gitHead": "0e72800b6a32ef0bd82cb6d14c156bfa4093dc2c" | ||
} |
@@ -11,2 +11,3 @@ `@tannin/sprintf` | ||
- Positional index | ||
- Named arguments | ||
- Precision / maximum width (including `*` precision) | ||
@@ -42,6 +43,23 @@ - Type (only the behaviors of `f`, `d`, `s`, and `%` are applied) | ||
## Type coercions and default values | ||
When replacing numeric types (`%d` and `%f`), values will be coerced to numeric values, and default to 0: | ||
- `sprintf( '%d', 123 )` returns `'123'` | ||
- `sprintf( '%d', '123' )` returns `'123'` | ||
- `sprintf( '%d', 'string' )` returns `'0'` | ||
- `sprintf( '%d', false )` returns `'0'` | ||
- `sprintf( '%d', null )` returns `'0'` | ||
- `sprintf( '%d', undefined )` returns `'0'` | ||
When replacing string types (`%s`), values will be coerced to strings, and nullish values will be replaced with `''`: | ||
- `sprintf( '%s', 'string' )` returns `'string'` | ||
- `sprintf( '%s', 0 )` returns `'0'` | ||
- `sprintf( '%s', false )` returns `'false'` | ||
- `sprintf( '%s', null )` returns `''` | ||
- `sprintf( '%s', undefined )` returns `''` | ||
## License | ||
Copyright 2018 Andrew Duthie | ||
Copyright 2019 Andrew Duthie | ||
Released under the [MIT License](https://opensource.org/licenses/MIT). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17495
369
64