sprintf.js is a complete open source JavaScript sprintf implementation

Overview

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 3-clause BSD 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.

Comments
  • Allow access to prototype properties

    Allow access to prototype properties

    Hi there, thanks for a great library! I've got a small PR, though it's entirely possible the current behaviour is by design (in which case I can work around it)

    Basically, this works as expected

    sprintf("%(x)s", { x: 2 })
    // "2"
    

    While this doesn't (or at least, not how I'd expect ;) )

    class C { get x () { return 2 } }
    sprintf("%(x)s", new C())
    // Error: [sprintf] property "x" does not exist
    

    The PR replaces !hasOwnProperty check with a === undefined check and adds a test. It doesn't break any other tests but I guess it's possible someone's relying on an error here?

    opened by fredludlow 21
  • What browsers does sprintf.js targets?

    What browsers does sprintf.js targets?

    What I'm actually curious about is whether you're fine with dropping IE entirely and only support last 2 versions of any evergreen browser in next major release? If this is the case it would be possible to reduce and simplify code a bit.

    opened by nazar-pc 18
  • Leave original placeholder if attribute is not present in passed object

    Leave original placeholder if attribute is not present in passed object

    When using named arguments, value in output for the field is currently replaced to 'undefined'. This change leaves the original placeholder instead of changing its value.

    opened by vdiez 7
  • Optimizations for modern browsers

    Optimizations for modern browsers

    Each commit contains pretty distinct change and can be picked separately from the rest. The only breaking change for older browsers is that String.prototype.repeat should be present.

    These changes allow ~10% reduction of gzipped library size after Google Closure Compiler minifier. I've tried to replace uglifyjs with closure-compiler-js, but it seems to be broken (at least gulp version of it), awfully documented and I wan't able to get it working in advanced mode even though Closure Compiler Service works perfectly with these sources.

    opened by nazar-pc 7
  • Bug parsing named arguments

    Bug parsing named arguments

    Hi, Basically the official documentation example

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

    at https://jsfiddle.net/0fzdctbt/1/ will work, however if you delete the s after (%name) and let the %(name) to be the last part of the string then this will fail with [sprintf] unexpected placeholder error.

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

    at https://jsfiddle.net/0fzdctbt/

    opened by sevketufuk 5
  • allow for browser and node assignments for certain cases involving es…

    allow for browser and node assignments for certain cases involving es…

    …6, webpack, typescript I ran into a problem when I upgraded to Typescript 2 and used WebPack to bundle my commonJS into browser code. It appears the 'exports' is detected, but I really need vsprintf to become availabable globally in the browser. This change allows for either or both.

    opened by rebeccapeltz 5
  • Missing Semicolon at the end of src/sprintf.js

    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.

    opened by SimplGy 5
  • pad character not working properly

    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

    opened by wkechel 5
  • No parameters rendered with

    No parameters rendered with "%s"

    Hi,

    could you please look at get_type function, it seems work not properly.

    On your format function you're waiting for "array" type but you've got an "array iterator".

    That's why code will never be executed and you'll never see your parameters on the output string

    opened by ImmortalJoker 4
  • [_.sprintf] expecting number but found string

    [_.sprintf] expecting number but found string

    _.sprintf("%f", "3"); and .sprintf("%f", "NaN"); get the error "[.sprintf] expecting number but found string", but parseFloat works well. Is it right behavior?

    enhancement 
    opened by herclogon 4
  • hx specifier doesn't work

    hx specifier doesn't work

    %hx specifier is for short hexadecimal numbers (typically 2 bytes). For example: sprintf("%hX\n", 65536); // = hexa 0 sprintf("%X\n", 65536); // = hexa 10000

    The javascript version of sprintf throws error: SyntaxError: [sprintf] unexpected placeholder

    opened by kurdbohu 3
  • Fix NaN being printed out as `-NaN`

    Fix NaN being printed out as `-NaN`

    I've encountered incorrect behavior in cases involving NaN. Consider the following example:

    sprintf('%f', NaN) // '-NaN'
    

    The library always adds minus sign before NaN. This fix considers NaN as a positive by including an additional check during sign detection.

    opened by Wain-PC 0
  • Licensing Question

    Licensing Question

    I noticed that the bower.json file indicates the the license is "BSD-3-Clause-Clear" instead of just "BSD-3-Clause" in other files, such as package.json. Is the inclusion of "-Clear" in the bower.json" intentional? Should it be just "BSD-3-Clause" instead?

    opened by rklevansriverbed 1
  • Support

    Support "%*s" as a format string

    in POSIX environments you could write: printf("%*d", width, num);. The "*" is not recognized by sprintf.js. Could this caoability be added to sprintf.js?

    opened by baiti 0
  • Add terminating semicolons to harden syntax

    Add terminating semicolons to harden syntax

    Semicolons were omitted where optional with a trailing line break. This can cause issues when e.g. minimising the script. This change consequently adds trailing semicolons to terminate statements and hence hardens the wider use of the script.

    I know it is the task of minifiers to add semicolons where required, when removing line breaks. It could be also seen as the task of minifiers to remove optional semicolons, instead of having this done in the formatted source file already. We just faced issues when this was used in Wordfence and a common plugin with a bad JavaScript minifier removed line breaks without adding then mandatory semicolons. Having them in the original source file makes the scripts more robust against such issues, while of course the minifier is to blame here, or that admin who uses it without checking the outcome 😄.

    For reference: https://github.com/WordPress/WordPress/pull/540

    opened by MichaIng 0
Owner
Alexandru Mărășteanu
Alexandru Mărășteanu
String manipulation helpers for javascript

The stable release documentation can be found here https://epeli.github.io/underscore.string/ Underscore.string Javascript lacks complete string manip

Esa-Matti Suuronen 3.4k Dec 25, 2022
Extra JavaScript string methods.

string.js string.js, or simply S is a lightweight (< 5 kb minified and gzipped) JavaScript library for the browser or for Node.js that provides extra

JP Richardson 1.8k Dec 17, 2022
A robust HTML entity encoder/decoder written in JavaScript.

he he (for “HTML entities”) is a robust HTML entity encoder/decoder written in JavaScript. It supports all standardized named character references as

Mathias Bynens 3.2k Dec 27, 2022
Multiline strings in JavaScript

multiline Multiline strings in JavaScript No more string concatenation or array join! Use ES2015 template literals instead whenever possible. Before c

Sindre Sorhus 1.4k Dec 30, 2022
Javascript URL mutation library

URI.js About Understanding URIs Documentation jQuery URI Plugin Author Changelog IMPORTANT: You may not need URI.js anymore! Modern browsers provide t

Medialize 6.2k Dec 30, 2022
Lightweight URL manipulation with JavaScript

domurl 2.x (former jsurl) Lightweight URL manipulation with JavaScript for both DOM and server JavaScript. Goal To have a convenient way working with

Mykhailo Stadnyk 511 Dec 28, 2022
Reference for How to Write an Open Source JavaScript Library - https://egghead.io/series/how-to-write-an-open-source-javascript-library

Reference for How to Write an Open Source JavaScript Library The purpose of this document is to serve as a reference for: How to Write an Open Source

Sarbbottam Bandyopadhyay 175 Dec 24, 2022
A complete habits manager, where you can track your progress and complete each daily activity in an organized way.

TrackIt Habit manager in a dynamic, clear and simple way. TackIt is an application that seeks to make it simple and accessible for any user to control

Rui Neto 13 Dec 31, 2022
Complete Open Source Front End Candy Machine V2 Minter dAPP Built For The Frog Nation NFT Solana Project. Built With React, Candy Machine V2, Typescript

Complete Open Source Front End Candy Machine V2 Minter dAPP Built For The Frog Nation NFT Solana Project. Built With React, Candy Machine V2, Typescript

null 17 Sep 24, 2022
Omnivore - a complete, open source read-it-later solution for people who like text

Omnivore Omnivore is a complete, open source read-it-later solution for people who like text. We built Omnivore because we love reading and we want it

Omnivore 597 Jan 1, 2023
An Open-Source JavaScript Implementation of Bionic Reading.

bionic-reading Try on Runkit or Online Sandbox An Open-Source JavaScript Implementation of Bionic Reading API. ⚙️ Install npm i bionic-reading yarn ad

shj 127 Dec 16, 2022
An Open-Source JavaScript Implementation of Bionic Reading.

TextVide (vide; Latin for "see") Support all languages that separate words with spaces Try on Runkit or Online Sandbox An Open-Source JavaScript Imple

shj 127 Dec 16, 2022
A damn-sexy, open source real-time dashboard builder for IOT and other web mashups. A free open-source alternative to Geckoboard.

freeboard free·board (noun) *\ˈfrē-ˌbȯrd* the distance between the waterline and the main deck or weather deck of a ship or between the level of the w

freeboard 6.3k Dec 28, 2022
An Open-Source Platform to certify open-source projects.

OC-Frontend This includes the frontend for Open-Certs. ?? After seeing so many open-source projects being monetized ?? without giving any recognition

Open Certs 15 Oct 23, 2022
Shikhar 4 Oct 9, 2022
This is a project for open source enthusiast who want to contribute to open source in this hacktoberfest 2022. 💻 🎯🚀

HACKTOBERFEST-2022-GDSC-IET-LUCKNOW Beginner-Hacktoberfest Need Your first pr for hacktoberfest 2k22 ? come on in About Participate in Hacktoberfest b

null 8 Oct 29, 2022
open-source implementation of the Turborepo custom remote cache server.

This project is an open-source implementation of the Turborepo custom remote cache server. If Vercel's official cache server isn't a viable option, th

Maksim Sinik 362 Dec 30, 2022
Open-source Fallout 2 engine implementation, a revival of darkfo project

Harold A post-nuclear RPG remake This is a modern reimplementation of the engine of the video game Fallout 2, as well as a personal research project i

Max Desiatov 8 Aug 19, 2022