Giter VIP home page Giter VIP logo

sprintf.js's Introduction

sprintf-js

Build Status NPM Version Dependency Status devDependency Status

sprintf-js is a complete open source JavaScript sprintf implementation for the browser and Node.js.

Note: as of v1.1.1 you might need some polyfills for older environments. See Support section below.

Usage

var sprintf = require('sprintf-js').sprintf,
    vsprintf = require('sprintf-js').vsprintf

sprintf('%2$s %3$s a %1$s', 'cracker', 'Polly', 'wants')
vsprintf('The first 4 letters of the english alphabet are: %s, %s, %s and %s', ['a', 'b', 'c', 'd'])

Installation

NPM

npm install sprintf-js

Bower

bower install sprintf

API

sprintf

Returns a formatted string:

string sprintf(string format, mixed arg1?, mixed arg2?, ...)

vsprintf

Same as sprintf except it takes an array of arguments, rather than a variable number of arguments:

string vsprintf(string format, array arguments?)

Format specification

The placeholders in the format string are marked by % and are followed by one or more of these elements, in this order:

  • An optional number followed by a $ sign that selects which argument index to use for the value. If not specified, arguments will be placed in the same order as the placeholders in the input string.
  • An optional + sign that forces to precede the result with a plus or minus sign on numeric values. By default, only the - sign is used on negative numbers.
  • An optional padding specifier that says what character to use for padding (if specified). Possible values are 0 or any other character preceded by a ' (single quote). The default is to pad with spaces.
  • An optional - sign, that causes sprintf to left-align the result of this placeholder. The default is to right-align the result.
  • An optional number, that says how many characters the result should have. If the value to be returned is shorter than this number, the result will be padded. When used with the j (JSON) type specifier, the padding length specifies the tab size used for indentation.
  • An optional precision modifier, consisting of a . (dot) followed by a number, that says how many digits should be displayed for floating point numbers. When used with the g type specifier, it specifies the number of significant digits. When used on a string, it causes the result to be truncated.
  • A type specifier that can be any of:
    • % — yields a literal % character
    • b — yields an integer as a binary number
    • c — yields an integer as the character with that ASCII value
    • d or i — yields an integer as a signed decimal number
    • e — yields a float using scientific notation
    • 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
    • o — yields an integer as an octal number
    • s — yields a string as is
    • t — yields true or false
    • T — yields the type of the argument1
    • v — yields the primitive value of the specified argument
    • x — yields an integer as a hexadecimal number (lower-case)
    • X — yields an integer as a hexadecimal number (upper-case)
    • j — yields a JavaScript object or array as a JSON encoded string

Features

Argument swapping

You can also swap the arguments. That is, the order of the placeholders doesn't have to match the order of the arguments. You can do that by simply indicating in the format string which arguments the placeholders refer to:

sprintf('%2$s %3$s a %1$s', 'cracker', 'Polly', 'wants')

And, of course, you can repeat the placeholders without having to increase the number of arguments.

Named arguments

Format strings may contain replacement fields rather than positional placeholders. Instead of referring to a certain argument, you can now refer to a certain key within an object. Replacement fields are surrounded by rounded parentheses - ( and ) - and begin with a keyword that refers to a key:

var user = {
    name: 'Dolly',
}
sprintf('Hello %(name)s', user) // Hello Dolly

Keywords in replacement fields can be optionally followed by any number of keywords or indexes:

var users = [
    {name: 'Dolly'},
    {name: 'Molly'},
    {name: 'Polly'},
]
sprintf('Hello %(users[0].name)s, %(users[1].name)s and %(users[2].name)s', {users: users}) // Hello Dolly, Molly and Polly

Note: mixing positional and named placeholders is not (yet) supported

Computed values

You can pass in a function as a dynamic value and it will be invoked (with no arguments) in order to compute the value on the fly.

sprintf('Current date and time: %s', function() { return new Date().toString() })

AngularJS

You can use sprintf and vsprintf (also aliased as fmt and vfmt respectively) in your AngularJS projects. See demo/.

Support

Node.js

sprintf-js runs in all active Node versions (4.x+).

Browser

sprintf-js should work in all modern browsers. As of v1.1.1, you might need polyfills for the following:

  • String.prototype.repeat() (any IE)
  • Array.isArray() (IE < 9)
  • Object.create() (IE < 9)

YMMV

License

sprintf-js is licensed under the terms of the BSD 3-Clause License.

Notes

1 sprintf doesn't use the typeof operator. As such, the value null is a null, an array is an array (not an object), a date value is a date etc.

sprintf.js's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sprintf.js's Issues

LICENSE?

license field should be BSD-3-Clause -- BSD defaults to the 2-clause version

Warning on export

Don't know if it is importing, but when uglifying the file with UglifyJs:

Condition always true [./~/sprintf-js/src/sprintf.js:178,0]
Dropping unreachable code [./~/sprintf-js/src/sprintf.js:183,0]

I include your sprintfs into a module and create a webpackage with webpack module bundler.

Support for object values

Maybe I missed it, but it would be super awesome to be able to pass in an object similar to passing in an array for vsprintf.

Expose regex or function to detect presence of placeholders

Hi guys, over at angular-logging, we heavily rely on sprintf to help us provide enhanced logging for angular's $log.

We now run into an issue where we would like to detect whether a string contains placeholders and how many. I see you have a separate regex for placeholders, but it is not exposed.

Would you guys consider either providing a function that returns a count of placeholders or alternatively exposing the placeholders regex? We need to know the number as we dynamically assign arguments to the sprintf invocation.

Integer printing error for small numbers

If the number is floating point number and its exponent is in certain range, sprintf prints wrong number.

var a = 9.9999e-7;

console.log(a);
// ==> 9.9999e-7

console.log(sprintf('%d', a));
// ==> 9 (0 expected)

console.log(sprintf('%d', a + 0.0001));
// ==> 0

console.log(sprintf('%d', a.toFixed()));
// ==> 0

console.log(parseInt(a));
// ==> 9

console.log(parseInt(a.toFixed()));
// ==> 0

To fix this, if the type specifier is integer (/bcdiuxX/), arg must first be converted to the fixed point number using toFixed().
toFixed() also does the rounding which is also desired.

padding does not work correctly

$ nodejs
> var sprintf = require("sprintf-js").sprintf;
undefined
> Math.PI
3.141592653589793
> sprintf("%3.2f", Math.PI)
'3.14'

But it should be

'  3.14'

With 2 spaces padded.

Add %g in the formater

Be able for format a number based on significative digits would be nice. This is as far as I know the "%g" option
Trying in a batch

  • printf '%.4g' 123.12 --> 123.1
  • printf '%.4g' 123123.12123 --> 1.231e-05
  • printf '%.4g' 1223.12123 --> 1223
    The equivalent in javascript would be "toPrecision"
  • (123.12).toPrecision(4)
  • (123123.12123).toPrecision(4)
  • (1223.12123).toPrecision(4)
    And yields the same result

pad character not working properly

The alternate pad character specification does not work properly:

sprintf("%'#10s",'monkey')
--> "####monkey"
sprintf("%'a10s",'monkey')
"%'a10s"
I think the reason is the regexp. Since # is in the part of the pre-precision/padding spec, it works, but no characters other than [-+'#0 ]* are accepted

thousand separator

Hi,
I am not too sure if I missed something or not, but I couldn't find any info on how to get a thousand separator a la #,### working. Is this covered? If yes, can you please explain how it works. If not, can you please add this feature?
Thanks!

Npm update

Would be possible to update npm module? There is 2 years old version on npm.

Thanks!

Configurable errors

It would be great to have possibility to switch off errors for empty placeholders in some cases

Especially in case of named placeholders, since, actually, they are the only one type of placeholders, which throw error:

Error: [sprintf] property 'val' does not exist

It's possible to make it configurable, just like I've described it in my comment here:

#49 (comment)

Or on sprontf() function invocation:

sprintf = require('sprintf-js').sprintf({
  errorOnUndefined: false
})

Missing Semicolon at the end of src/sprintf.js

This is only an issue if the file is concated with a min-cat tool to another file that startes with an IIFE:

(function(window) {
  ...
})(typeof window === "undefined" ? this : window)

... end of file, start of next file...

(function(){
...
})()

This concats to:

    (function(window) { /*...*/ })(typeof window === "undefined" ? this : window)(function(){})()

It tries to execute the next file's IIFE function against the return of the sprintf library code, which is undefined.

Minifiers will add semicolons where needed correctly, but I think maybe they skip end of files. concaters definitely don't add semis. Or maybe they can, optionally. In any case, probably just adding a single semi at the end of this file is a good idea, even though you like ASI elsewhere.

Fix bower component for Angular & Gulp Inject

I can't load automagically the angular sprintf filter.

bower install sprintf --save correctly installs the bower component.

However, my gulp inject task only loads sprintf.js

<script src="../bower_components/sprintf/src/sprintf.js"></script>

instead of both sprintf.js & angular-sprintf.js and by the way, should take the dist & minified ones

<script src="../bower_components/sprintf/dist/sprintf.min.js"></script>
<script src="../bower_components/sprintf/dist/angular-sprintf.min.js"></script>

Any suggestion or workaround?

CDN availability

Hi. Like the title says, are there any plans to host sprintf.js as an accessible CDN resource somewhere?

Thanks for your time and help!

Update bower.json

Could you remember to update the version in bower.json whenever you make any change (http://semver.org/). Otherwise our 'bower install/upgrade' won't pull your changes.

Thanks a lot for your great work and following up on all the issues.

vsprintf() alters the argv array

vsprintf() alters the argv array by prepending the format. Running the vsprintf() function several times with the same arguments has unpredictable results.

(sent by daaa and Djordje Ungar via email)

Negative number passed to the first '%f'.

Hi, isn't this strange?
sprintf("%f and %f", 12, 34) returns '12 and 34' ...OK
sprintf("%f and %f", 12, -34) returns '12 and -34' ...OK
sprintf("%f and %f", -12, 34) returns '-12 and -34' ...???
sprintf("%f and %f", -12, -34) returns '-12 and -34' ...OK

Preserve unmatched placeholders

As mentioned here #8 (comment), it would be nice to have option to return unmatched placeholders as they are.

For example, when we have this:

sprintf('Test number %s')

instead of 'Test number undefined' return 'Test number %s'

And same for named placeholders:

sprintf('%(name)s number 1')

instead of error about non-existing placeholder return '%(name)s number 1'

This will make possible complex chaining, when you need to process strings by few modules.

So far can't tell for sure how should it be done.

I have few options:

  • Global option during sprintf invocation:

    sprintf = require('sprintf-js').sprintf({
      preservePlaceholders: true
    })
    
    sprintf('%(name)s number 1')` -> `'%(name)s number 1'`
  • Live switch in and switch off:

    sprintf.preservePlaceholders(true)
    
    sprintf('%(name)s number 1')` -> `'%(name)s number 1'`
    
    sprintf.preservePlaceholders(false)
  • Special sprintfp function:

    sprintfp('%(name)s number 1')` -> `'%(name)s number 1'`

Does not support the # flag

sprintf("% #6f", "2")results in a SyntaxError: [sprintf] unexpected placeholder

From man printf:

Each format specification is introduced by the percent character ("%'').  The remainder of the format specification includes, in the following order:

Zero or more of the following flags:
 #       A `#' character specifying that the value should be printed in an "alternate 
form". For c, d, and s, formats, this option has no effect.  For the o formats the 
precision of the number is increased to force the first character of the output string 
to a zero.  For the x (X) format, a non-zero result has the string 0x (0X) prepended 
to it.  For e, E, f, g, and G, formats, the result will always contain a decimal point, 
even if no digits follow the point (normally, a decimal point only appears in the results 
of those formats if a digit follows the decimal point).  For g and G formats, trailing 
zeros are not removed from the result as they would otherwise be;

What kind of license?

I see the license text file, but is it MIT, what kind of license is it? The README.md should say the type of license to facilitate people taking an inventory of open source dependencies.

missed coposer.json

Pls, add composer.json to make it easy to install using composer.phar.

thanks

Support named arguments with spaces

var user = {name: "Dolly", age: 24, 'in co': 23, '#':1}
undefined
sprintf("%(name)s - %(age)s", user)
"Dolly - 24"
sprintf("%(name)s - %(age)s - %(in co)s", user)
sprintf.js:146 Uncaught SyntaxError: [sprintf] failed to parse named argument key(…)b.parse @ sprintf.js:146b @ sprintf.js:19(anonymous function) @ VM50747:2InjectedScript._evaluateOn @ (program):878InjectedScript._evaluateAndWrap @ (program):811InjectedScript.evaluate @ (program):667
sprintf("%(name)s - %(age)s - %(#)s", user)
sprintf.js:151 Uncaught SyntaxError: [sprintf] failed to parse named argument key(…)

Can named arguments, object keys with spaces ('avg val') or special charaters (#, _ etc) be supported?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.