string-format
string-format is a small JavaScript library for formatting strings, based on
Python's str.format()
. For example:
'"{firstName} {lastName}" <{email}>'.format(user)
The equivalent concatenation:
'"' + user.firstName + ' ' + user.lastName + '" <' + user.email + '>'
Installation
Node
-
Install:
$ npm install string-format
-
Require:
const format = require('string-format')
Browser
-
Define window.format
:
<script src="path/to/string-format.js"></script>
Modes
string-format can be used in two modes: function mode and
method mode.
Function mode
format('Hello, {}!', 'Alice')
In this mode the first argument is a template string and the remaining
arguments are values to be interpolated.
Method mode
'Hello, {}!'.format('Alice')
In this mode values to be interpolated are supplied to the format
method
of a template string. This mode is not enabled by default. The method must
first be defined via format.extend
:
format.extend(String.prototype, {})
format(template, $0, $1, …, $N)
and template.format($0, $1, …, $N)
can then
be used interchangeably.
format(template, $0, $1, …, $N)
Returns the result of replacing each {…}
placeholder in the template string
with its corresponding replacement.
Placeholders may contain numbers which refer to positional arguments:
'{0}, you have {1} unread message{2}'.format('Holly', 2, 's')
Unmatched placeholders produce no output:
'{0}, you have {1} unread message{2}'.format('Steve', 1)
A format string may reference a positional argument multiple times:
"The name's {1}. {0} {1}.".format('James', 'Bond')
Positional arguments may be referenced implicitly:
'{}, you have {} unread message{}'.format('Steve', 1)
A format string must not contain both implicit and explicit references:
'My name is {} {}. Do you like the name {0}?'.format('Lemony', 'Snicket')
{{
and }}
in format strings produce {
and }
:
'{{}} creates an empty {} in {}'.format('dictionary', 'Python')
Dot notation may be used to reference object properties:
const bobby = {firstName: 'Bobby', lastName: 'Fischer'}
const garry = {firstName: 'Garry', lastName: 'Kasparov'}
'{0.firstName} {0.lastName} vs. {1.firstName} {1.lastName}'.format(bobby, garry)
0.
may be omitted when referencing a property of {0}
:
const repo = {owner: 'davidchambers', slug: 'string-format'}
'https://github.com/{owner}/{slug}'.format(repo)
If the referenced property is a method, it is invoked with no arguments to
determine the replacement:
const sheldon = {
firstName: 'Sheldon',
lastName: 'Cooper',
dob: new Date('1970-01-01'),
fullName: function() { return this.firstName + ' ' + this.lastName },
quip: function() { return 'Bazinga!' },
}
'{fullName} was born at precisely {dob.toISOString}'.format(sheldon)
"I've always wanted to go to a goth club. {quip.toUpperCase}".format(sheldon)
format.create(transformers)
This function takes an object mapping names to transformers and returns a
formatting function. A transformer is applied if its name appears, prefixed
with !
, after a field name in a template string.
const fmt = format.create({
escape: s => s.replace(/[&<>"'`]/g, c => '&#' + c.charCodeAt(0) + ';'),
upper: s => s.toUpperCase(),
})
fmt('Hello, {!upper}!', 'Alice')
const restaurant = {name: 'Anchor & Hope', url: 'http://anchorandhopesf.com/'}
fmt('<a href="{url!escape}">{name!escape}</a>', restaurant)
format.extend(prototype, transformers)
This function takes a prototype (presumably String.prototype
) and an object
mapping names to transformers, and defines a format
method on the prototype.
A transformer is applied if its name appears, prefixed with !
, after a field
name in a template string.
format.extend(String.prototype, {
escape: s => s.replace(/[&<>"'`]/g, c => '&#' + c.charCodeAt(0) + ';'),
upper: s => s.toUpperCase(),
})
'Hello, {!upper}!'.format('Alice')
const restaurant = {name: 'Anchor & Hope', url: 'http://anchorandhopesf.com/'}
'<a href="{url!escape}">{name!escape}</a>'.format(restaurant)
Running the test suite
$ npm install
$ npm test