Comparing version 0.3.3 to 0.4.0
--- | ||
tags: ['docs/verbfile.js'] | ||
tags: ['verb-tag-jscomments'] | ||
--- | ||
@@ -27,8 +27,18 @@ # {%= name %} {%= badge("fury") %} | ||
## API | ||
{%= extract("index.js") %} | ||
{%= jscomments("index.js") %} | ||
## Authors | ||
{%= contrib("brian") %} | ||
{%= contrib("jon") %} | ||
{%= include("authors", { | ||
authors: [ | ||
{ | ||
name: 'Jon Schlinkert', | ||
username: 'jonschlinkert' | ||
}, | ||
{ | ||
name: 'Brian Woodward', | ||
username: 'doowb' | ||
} | ||
] | ||
}) %} | ||
@@ -35,0 +45,0 @@ ## License |
{ | ||
"name": "strings", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"main": [ | ||
@@ -5,0 +5,0 @@ "index.js" |
421
index.js
@@ -10,13 +10,14 @@ /** | ||
var frep = require('frep'); | ||
var replace = require('frep'); | ||
var _ = require('lodash'); | ||
var utils = require('./lib/utils.js'); | ||
var utils = require('./lib/utils'); | ||
/** | ||
* ## new Strings() | ||
* ## Strings | ||
* | ||
* > Strings constructor method | ||
* | ||
* Instantiate a new instance of Strings, optionally passing a default context to use. | ||
* Create a new instance of `Strings`, optionally passing a default context to use. | ||
* | ||
@@ -29,6 +30,8 @@ * **Example** | ||
* | ||
* @class `Strings` | ||
* @constructor | ||
* @return {Object} Instance of a Strings object | ||
*/ | ||
function Strings(context) { | ||
function Strings(context, options) { | ||
if (!(this instanceof Strings)) { | ||
@@ -38,3 +41,7 @@ return new Strings(context); | ||
this._context = context || {}; | ||
this.options = options || {}; | ||
this.options.nonull = false; | ||
this.context = context || {}; | ||
this._replacements = {}; | ||
@@ -50,10 +57,14 @@ this._propstrings = {}; | ||
/** | ||
* ## .propstring (name, propstring) | ||
* ## .propstring | ||
* | ||
* Get or set a propstring. | ||
* Set or get a named propstring. | ||
* | ||
* ```js | ||
* strings.propstring(name, propstring) | ||
* ``` | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.propstring('permalinks', ':destBase/:dirname/:basename/index.:ext'); | ||
* strings.propstring('url', ':base/blog/posts/:basename:ext'); | ||
* ``` | ||
@@ -63,10 +74,24 @@ * | ||
* @param {String} `propstring` | ||
* @return {Object} Instance of the current Strings object | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
*/ | ||
Strings.prototype.propstring = function (name, str) { | ||
if (_.isUndefined(str)) { | ||
return this._propstrings[name]; | ||
var isPropstring = function(str) { | ||
return /:/.test(str) ? 'null' : str; | ||
}; | ||
Strings.prototype.propstring = function (name, str, options) { | ||
options = _.extend({}, this.options, options); | ||
if (!str) { | ||
// if `nonull:false` return the propstring or `'__null__'` | ||
if (options.nonull === false) { | ||
return this._propstrings[name] || isPropstring(name); | ||
} | ||
// if only one argument is passed, lookup the name | ||
// and return the propstring. Or just return the | ||
// name if it isn't set already. | ||
return this._propstrings[name] || name; | ||
} | ||
this._propstrings[name] = str; | ||
@@ -78,15 +103,20 @@ return this; | ||
/** | ||
* ## .pattern (name, pattern) | ||
* ## .pattern | ||
* | ||
* Get or set regular expression or string. | ||
* Set or get a string or regex pattern to be used for matching. | ||
* | ||
* ```js | ||
* strings.pattern(name, pattern, flags); | ||
* ``` | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.pattern('prop', ':([\\w]+)'); | ||
* strings.pattern('anyProp', ':([\\w]+)'); | ||
* ``` | ||
* | ||
* @param {String} `name` | ||
* @param {String} `pattern` | ||
* @return {Object} Instance of the current Strings object | ||
* @param {String} `name` The name of the stored pattern. | ||
* @param {String|RegExp|Function} `pattern` The pattern to use for matching. | ||
* @param {String} `flags` Optionally pass RegExp flags to use. | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
@@ -96,5 +126,3 @@ */ | ||
Strings.prototype.pattern = function (name, pattern, flags) { | ||
if (_.isUndefined(pattern)) { | ||
return this._patterns[name]; | ||
} | ||
if (!pattern) {return this._patterns[name];} | ||
if (!(pattern instanceof RegExp)) { | ||
@@ -109,6 +137,11 @@ pattern = new RegExp(pattern, flags || ''); | ||
/** | ||
* ## .replacement (name, replacement) | ||
* ## .replacement | ||
* | ||
* Get or set a replacement string or function. | ||
* Set or get a replacement pattern. Replacement patterns can be a | ||
* regular expression, string or function. | ||
* | ||
* ```js | ||
* strings.replacement(name, replacement) | ||
* ``` | ||
* | ||
* **Example** | ||
@@ -123,4 +156,4 @@ * | ||
* @param {String} `name` | ||
* @param {String} `replacement` | ||
* @return {Object} Instance of the current Strings object | ||
* @param {String|Function} `replacement` The replacement to use when patterns are matched. | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
@@ -130,5 +163,3 @@ */ | ||
Strings.prototype.replacement = function (name, replacement) { | ||
if (_.isUndefined(replacement)) { | ||
return this._replacements[name]; | ||
} | ||
if (!replacement) {return this._replacements[name];} | ||
this._replacements[name] = replacement; | ||
@@ -140,40 +171,19 @@ return this; | ||
/** | ||
* ## .parser ( name, replacement-patterns ) | ||
* ## .parser | ||
* | ||
* Define a named parser to be used against any given string. | ||
* Set a parser that can later be used to parse any given string. | ||
* | ||
* **Example** | ||
* | ||
* Pass an object: | ||
* | ||
* ```js | ||
* strings.parser('prop', { | ||
* pattern: /:([\\w]+)/, | ||
* replacement: function(match) { | ||
* return match.toUpperCase(); | ||
* } | ||
* ); | ||
* strings.parser (name, replacements) | ||
* ``` | ||
* | ||
* Or an array | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.parser('prop', [ | ||
* { | ||
* pattern: 'a', | ||
* replacement: 'b' | ||
* }, | ||
* { | ||
* pattern: 'c', | ||
* replacement: 'd' | ||
* } | ||
* ]); | ||
* ``` | ||
* {%= docs("example-parser.md") %} | ||
* | ||
* @param {String} `name` name of the parser. | ||
* @param {Object|Array} `pairings` array of replacement patterns to store with the given name. | ||
* @param {String|RegExp} `pattern` | ||
* @param {String|Function} `replacement` | ||
* @return {Object} Instance of the current Strings object | ||
* | ||
* @param {String} `name` | ||
* @param {Object|Array} `arr` Object or array of replacement patterns to associate. | ||
* @property {String|RegExp} `pattern` | ||
* @property {String|Function} `replacement` | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
@@ -183,6 +193,4 @@ */ | ||
Strings.prototype.parser = function (name, arr) { | ||
if (_.isUndefined(arr)) { | ||
return this._parsers[name]; | ||
} | ||
this._parsers[name] = !Array.isArray(arr) ? [arr] : arr; | ||
if (!arr) {return this._parsers[name];} | ||
this._parsers[name] = utils.arrayify(arr); | ||
return this; | ||
@@ -193,7 +201,10 @@ }; | ||
/** | ||
* ## .parsers ( parsers ) | ||
* ## .parsers | ||
* | ||
* Return a list of parsers based on the given list of named | ||
* parsers or parser objects. | ||
* Get an array of stored parsers by passing a parser name or array of parser names. | ||
* | ||
* ```js | ||
* strings.parsers(array) | ||
* ``` | ||
* | ||
* **Example** | ||
@@ -209,5 +220,5 @@ * | ||
* | ||
* {%= docs("parsers-example.md") %} | ||
* {%= docs("example-parsers.md") %} | ||
* | ||
* @param {String|Array} `parsers` named parsers or parser objects to use. | ||
* @param {String|Array} `parsers` string or array of parsers to get. | ||
* @return {Array} | ||
@@ -222,7 +233,6 @@ * @api public | ||
} | ||
parsers = utils.arrayify(parsers); | ||
parsers = Array.isArray(parsers) ? parsers : [parsers]; | ||
// find the specified parsers | ||
var _parsers = _.map(parsers, function (parser) { | ||
var arr = _.flatten(_.map(parsers, function (parser) { | ||
// if this is an actual parser object, just return it | ||
@@ -232,3 +242,2 @@ if (_.isObject(parser)) { | ||
} | ||
// find the parser and return it | ||
@@ -238,6 +247,6 @@ if (this._parsers.hasOwnProperty(parser)) { | ||
} | ||
}, this); | ||
}, this)); | ||
// finally normalize and return parsers | ||
return utils._normalize(_.flatten(_parsers)); | ||
return utils._normalizePatterns(arr); | ||
}; | ||
@@ -247,13 +256,18 @@ | ||
/** | ||
* ## .extend ( parser, replacement-patterns ) | ||
* ## .extendParser | ||
* | ||
* Extend a parser. | ||
* Extend a parser with additional replacement patterns. Useful if you're using | ||
* an external module for replacement patterns and you need to extend it. | ||
* | ||
* ```js | ||
* strings.extendParser(parser, replacements) | ||
* ``` | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.extend('prop', { | ||
* strings.extendParser('prop', { | ||
* pattern: /:([\\w]+)/, | ||
* replacement: function(match) { | ||
* return match.toUpperCase(); | ||
* replacement: function(str) { | ||
* return str.toUpperCase(); | ||
* } | ||
@@ -267,9 +281,9 @@ * ); | ||
* @param {String|Function} `replacement` | ||
* @return {Object} Instance of the current Strings object | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
*/ | ||
Strings.prototype.extend = function (name, arr) { | ||
arr = !Array.isArray(arr) ? [arr] : arr; | ||
var parser = _.union(this._parsers[name], arr); | ||
Strings.prototype.extendParser = function (name, arr) { | ||
arr = utils.arrayify(arr); | ||
var parser = _.union([], this._parsers[name], arr); | ||
this._parsers[name] = parser; | ||
@@ -281,21 +295,27 @@ return this; | ||
/** | ||
* ## .template( name, propstring, parsers ) | ||
* ## .template | ||
* | ||
* Store, by name, a named propstring and an array of parsers. | ||
* Set or get a reusable Strings template, consisting of a propstring | ||
* and an array of parsers. | ||
* | ||
* Templates are useful since they can be stored and then later used | ||
* with any context. | ||
* | ||
* ```js | ||
* strings.template(name, propstring, parsers); | ||
* ``` | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* // strings.template(name string, array); | ||
* strings.template('prop', ['prop'], { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* }); | ||
* strings.template('abc', ':a/:b/:c', ['a', 'b', 'c']); | ||
* // or use a named propstring | ||
* strings.template('abc', 'foo', ['a', 'b', 'c']); | ||
* here ^ | ||
* ``` | ||
* | ||
* @param {String} `name` The name of the template to store | ||
* @param {String} `name` Name of replacement group to use for building the final string | ||
* @param {Object} `context` Optional Object to bind to replacement function as `this` | ||
* @return {String} | ||
* @param {String} `name` | ||
* @param {String} `propstring` | ||
* @param {Array} `parsers` Names of the parsers to use with the template. | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
@@ -305,18 +325,15 @@ */ | ||
Strings.prototype.template = function (name, propstring, parsers) { | ||
if (_.isUndefined(propstring) && _.isUndefined(parsers)) { | ||
// Get the stored template only the name is passed | ||
if (arguments.length === 1) { | ||
return this._templates[name]; | ||
} | ||
if (arguments.length === 2 && typeof propstring === 'object') { | ||
this._templates[name] = { | ||
propstring: this.propstring(propstring.propstring), | ||
parsers: propstring.parsers | ||
}; | ||
} else { | ||
this._templates[name] = { | ||
propstring: this.propstring(propstring), | ||
parsers: parsers | ||
}; | ||
var opts = propstring; | ||
propstring = opts.propstring, | ||
parsers = opts.parsers | ||
} else if (arguments.length === 2 && typeof propstring === 'string') { | ||
throw new Error('Templates must be defined with an object or array of parsers.'); | ||
} | ||
propstring = this.propstring(propstring); | ||
this._templates[name] = {propstring: propstring, parsers: parsers}; | ||
return this; | ||
@@ -327,87 +344,43 @@ }; | ||
/** | ||
* ## .transform( named-propstring, named-parsers, context) | ||
* ## .replace | ||
* | ||
* Similar to `.process`, except that the first parameter is the name | ||
* of the stored `propstring` to use, rather than any given string. | ||
* Replace `:propstrings` with the real values. | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.transform('propstring', ['parser'], { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* }); | ||
* strings.replace(str, context) | ||
* ``` | ||
* | ||
* Or pass an object, `strings.transform({})`: | ||
* | ||
* ```js | ||
* strings.transform({ | ||
* propstring: 'prop', | ||
* parsers: ['prop'], | ||
* context: { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* } | ||
* }); | ||
* ``` | ||
* | ||
* @param {String} `name` The name of the stored template to use | ||
* @param {Object} `context` The optional context object to bind to replacement functions as `this` | ||
* @return {String} | ||
* @api public | ||
*/ | ||
Strings.prototype.transform = function (propstring, parsers, context) { | ||
if (arguments.length === 1) { | ||
propstring = propstring.propstring; | ||
parsers = propstring.parsers; | ||
context = propstring.context; | ||
} | ||
return this.process(this.propstring(propstring), parsers, context); | ||
}; | ||
/** | ||
* ## .use( named-propstring, named-parsers, context) | ||
* | ||
* Similar to `.process`, except that the first parameter is the name | ||
* of the stored `propstring` to use, rather than any given string. | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.use('propstring', ['parser'], { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* strings.replace(':a/:b/:c', { | ||
* a: 'foo', | ||
* b: 'bar', | ||
* c: 'baz' | ||
* }); | ||
* //=> foo/bar/baz | ||
* ``` | ||
* | ||
* Or pass an object, `strings.use({})`: | ||
* | ||
* ```js | ||
* strings.use({ | ||
* propstring: 'prop', | ||
* parsers: ['prop'], | ||
* context: { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* } | ||
* }); | ||
* ``` | ||
* | ||
* @param {String} `name` The name of the stored template to use | ||
* @param {Object} `context` The optional context object to bind to replacement functions as `this` | ||
* @return {String} | ||
* @param {String} `str` The string with `:propstrings` to replace. | ||
* @param {String} `context` The object with replacement properties. | ||
* @return {Strings} to allow chaining | ||
* @api public | ||
*/ | ||
Strings.prototype.use = function (template, context) { | ||
var tmpl = this.template(template); | ||
return this.process(tmpl.propstring, tmpl.parsers, context); | ||
Strings.prototype.replace = function (str, context) { | ||
var ctx = _.extend({}, this.context, context); | ||
return replace.strWithArr(str, utils._bind([ | ||
{ | ||
pattern: /:([\w-]+)/g, | ||
replacement: function(match, prop) { | ||
return this[prop] || prop; | ||
} | ||
}, | ||
{ | ||
pattern: /\{([^}]+)}/g, | ||
replacement: function(match, prop) { | ||
return this[prop] || prop; | ||
} | ||
} | ||
], ctx)); | ||
}; | ||
@@ -417,18 +390,14 @@ | ||
/** | ||
* ## .process (str, parsers, context) | ||
* ## .process | ||
* | ||
* Directly process the given string, using a named replacement | ||
* Directly process the given prop-string, using a named replacement | ||
* pattern or array of named replacement patterns, with the given | ||
* context. | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.process(':foo/:bar/:baz', ['a', 'b', 'c'], { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* }); | ||
* strings.process(str, parsers, context) | ||
* ``` | ||
* | ||
* {%= docs("example-process") %} | ||
* | ||
* @param {String} `str` the string to process | ||
@@ -442,5 +411,16 @@ * @param {String|Object|Array} `parsers` named parsers or parser objects to use when processing. | ||
Strings.prototype.process = function (str, arr, context) { | ||
var parsers = this.parsers(arr); | ||
var ctx = _.extend({}, this._context, context); | ||
return frep.strWithArr(str, utils._bind(parsers, ctx)); | ||
if (arguments.length === 1) { | ||
throw new Error('`strings.process()` expects at least two arguments.'); | ||
} | ||
if (this._templates.hasOwnProperty(str)) { | ||
context = arr; | ||
var template = this._templates[str]; | ||
str = template.propstring; | ||
arr = template.parsers; | ||
} | ||
arr = this.parsers(arr); | ||
var ctx = _.extend({}, this.context, context); | ||
return replace.strWithArr(str, utils._bind(arr, ctx)); | ||
}; | ||
@@ -450,56 +430,21 @@ | ||
/** | ||
* ## .group ( name, propstring, parsers ) | ||
* ## .run | ||
* | ||
* Define a named group of propstring/parser mappings, or get a | ||
* group if only the name is passed. | ||
* Process a template with the given context. | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* strings.group('my-group-name', ':foo/:bar/:baz', ['a', 'b', 'c']); | ||
* strings.run(template, context) | ||
* ``` | ||
* | ||
* To get a group: | ||
* | ||
* ```js | ||
* strings.group( name ); | ||
* ``` | ||
* | ||
* @param {String} `name` | ||
* @param {String} `propstring` the name of the propstring to use | ||
* @param {String|Array} `parsers` name or array of names of parsers to use | ||
* @return {Object} Instance of the current Strings object | ||
* @api public | ||
*/ | ||
Strings.prototype.group = function (groupName, propstring, parsers) { | ||
if (_.isUndefined(propstring) && _.isUndefined(parsers)) { | ||
return this._groups[groupName]; | ||
} | ||
this._groups[groupName] = { | ||
propstring: propstring, | ||
parsers: parsers | ||
}; | ||
return this; | ||
}; | ||
/** | ||
* ## .run ( groupname, context ) | ||
* | ||
* Process the specified group using the given context. | ||
* | ||
* **Example** | ||
* | ||
* Set: (`strings.run( string, object )`) | ||
* | ||
* ```js | ||
* strings.run('my-group-name', { | ||
* foo: 'aaa', | ||
* bar: 'bbb', | ||
* baz: 'ccc' | ||
* strings.run('blogTemplate', { | ||
* dest: '_gh_pages', | ||
* basename: '2014-07-01-post', | ||
* ext: '.html' | ||
* }); | ||
* ``` | ||
* | ||
* @param {String} `group` The group to run. | ||
* @param {String} `template` The template to process. | ||
* @param {Object} `context` Optional context object, to bind to replacement function as `this` | ||
@@ -510,5 +455,7 @@ * @return {String} | ||
Strings.prototype.run = function (group, context) { | ||
var namedGroup = this.group(group); | ||
return this.transform(namedGroup.propstring, namedGroup.parsers, context); | ||
Strings.prototype.run = function (name, context) { | ||
var template = this._templates[name]; | ||
var propstring = template.propstring; | ||
var parsers = template.parsers; | ||
return this.process(propstring, parsers, context); | ||
}; | ||
@@ -515,0 +462,0 @@ |
101
lib/utils.js
/** | ||
* Strings <https://github.com/sellside/strings> | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
@@ -11,16 +11,61 @@ * Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
var _ = require('lodash'); | ||
var utils = {}; | ||
utils._normalize = function (parsers) { | ||
/** | ||
* Export `utils` | ||
*/ | ||
var utils = module.exports = {}; | ||
/** | ||
* ## .arrayify | ||
* | ||
* Ensure that values are returned as an array. | ||
* | ||
* @param {Object|Array} `value` | ||
* @return {Array} | ||
*/ | ||
utils.arrayify = function(value) { | ||
return !Array.isArray(value) ? [value] : value; | ||
}; | ||
/** | ||
* ## ._normalizePatterns | ||
* | ||
* Normalize `key: value` replacement patterns into an array | ||
* of objects with `pattern` and `replacement` keys. | ||
* | ||
* **Example** | ||
* | ||
* ```js | ||
* [ | ||
* {key: value}, | ||
* {key: value} | ||
* ] | ||
* ``` | ||
* converts to: | ||
* | ||
* ```js | ||
* [ | ||
* { pattern: key, replacement: value }, | ||
* { pattern: key, replacement: value } | ||
* ] | ||
* ``` | ||
* | ||
* @param {Object|Array} parsers | ||
* @return {Object} | ||
* @api private | ||
*/ | ||
utils._normalizePatterns = function (replacementPatterns) { | ||
var arr = []; | ||
if (Array.isArray(parsers)) { | ||
// [{key: value}, {key, value}] => [{pattern: key, replacement: value], {pattern:key, replacement: value}] | ||
var i; | ||
for (i = 0; i < parsers.length; i++) { | ||
arr = arr.concat(utils._normalizeObject(parsers[i])); | ||
if (Array.isArray(replacementPatterns)) { | ||
for (var i = 0; i < replacementPatterns.length; i++) { | ||
arr = arr.concat(utils._normalizeObj(replacementPatterns[i])); | ||
} | ||
} else { | ||
// {key: value} => [{pattern: key, replacement: value}]; | ||
arr = arr.concat(utils._normalizeObject(parsers)); | ||
arr = arr.concat(utils._normalizeObj(replacementPatterns)); | ||
} | ||
@@ -31,12 +76,18 @@ return arr; | ||
utils._normalizeObject = function (obj) { | ||
/** | ||
* ## ._normalizeObj | ||
* | ||
* Normalize the `key: value` pairs in a single replacement | ||
* pattern object. | ||
* | ||
* @param {Object} `obj` | ||
* @return {Array} | ||
*/ | ||
if (_.isUndefined(obj)) { | ||
return []; | ||
} | ||
if (obj.hasOwnProperty('pattern') && obj.hasOwnProperty('replacement')) { | ||
utils._normalizeObj = function (obj) { | ||
if (_.isUndefined(obj)) return []; | ||
if (obj.hasOwnProperty('pattern') | ||
&& obj.hasOwnProperty('replacement')) { | ||
return [obj]; | ||
} | ||
var arr = []; | ||
@@ -46,3 +97,2 @@ _.forOwn(obj, function (value, key) { | ||
}); | ||
return arr; | ||
@@ -52,4 +102,15 @@ }; | ||
/** | ||
* ## ._bind | ||
* | ||
* Bind the current `Strings` object, enabling `this` to | ||
* be used in replacement functions. | ||
* | ||
* @param {Object|Array} `replacements` | ||
* @param {Object} `context` | ||
* @return {Array} | ||
*/ | ||
utils._bind = function (replacements, context) { | ||
replacements = _.cloneDeep(replacements); | ||
replacements = _.cloneDeep(utils.arrayify(replacements)); | ||
context = context || {}; | ||
@@ -67,3 +128,1 @@ | ||
}; | ||
module.exports = utils; |
{ | ||
"name": "strings", | ||
"version": "0.3.3", | ||
"version": "0.4.0", | ||
"description": "Easily replace and transform :props in strings.", | ||
@@ -63,5 +63,8 @@ "homepage": "https://github.com/doowb/strings", | ||
"mocha": "^1.19.0", | ||
"parse-filepath": "^0.3.0", | ||
"relative": "^0.1.4", | ||
"verb": "^0.2.11" | ||
"verb": "^0.2.11", | ||
"verb-tag-jscomments": "^0.1.4", | ||
"verbalize": "^0.1.2" | ||
} | ||
} |
282
README.md
@@ -24,7 +24,7 @@ # strings [![NPM version](https://badge.fury.io/js/strings.png)](http://badge.fury.io/js/strings) | ||
## API | ||
### new Strings() | ||
### Strings | ||
> Strings constructor method | ||
Instantiate a new instance of Strings, optionally passing a default context to use. | ||
Create a new instance of `Strings`, optionally passing a default context to use. | ||
@@ -36,9 +36,13 @@ **Example** | ||
``` | ||
* `return`{Object} Instance of a Strings object | ||
* `return` {Object} Instance of a Strings object | ||
### .propstring | ||
### .propstring ( name, propstring ) | ||
Set or get a named propstring. | ||
Get or set a propstring. | ||
```js | ||
strings.propstring(name, propstring) | ||
``` | ||
@@ -48,29 +52,39 @@ **Example** | ||
```js | ||
strings.propstring('permalinks', ':destBase/:dirname/:basename/index.:ext'); | ||
strings.propstring('url', ':base/blog/posts/:basename:ext'); | ||
``` | ||
* `name` {String}: | ||
* `propstring` {String}: | ||
* `return` {Object} Instance of the current Strings object | ||
* `name` {String} | ||
* `propstring` {String} | ||
* `return`{Strings} to allow chaining | ||
### .pattern ( name, pattern ) | ||
### .pattern | ||
Get or set regular expression or string. | ||
Set or get a string or regex pattern to be used for matching. | ||
```js | ||
strings.pattern(name, pattern, flags); | ||
``` | ||
**Example** | ||
```js | ||
strings.pattern('prop', ':([\\w]+)'); | ||
strings.pattern('anyProp', ':([\\w]+)'); | ||
``` | ||
* `name` {String}: | ||
* `pattern` {String}: | ||
* `return` {Object} Instance of the current Strings object | ||
* `name` {String}: The name of the stored pattern. | ||
* `pattern` {String|RegExp|Function}: The pattern to use for matching. | ||
* `flags` {String}: Optionally pass RegExp flags to use. | ||
* `return`{Strings} to allow chaining | ||
### .replacement ( name, replacement ) | ||
### .replacement | ||
Get or set a replacement string or function. | ||
Set or get a replacement pattern. Replacement patterns can be a | ||
regular expression, string or function. | ||
```js | ||
strings.replacement(name, replacement) | ||
``` | ||
**Example** | ||
@@ -84,11 +98,15 @@ | ||
* `name` {String}: | ||
* `replacement` {String}: | ||
* `return` {Object} Instance of the current Strings object | ||
* `name` {String} | ||
* `replacement` {String|Function}: The replacement to use when patterns are matched. | ||
* `return`{Strings} to allow chaining | ||
### .parser ( name, replacement-patterns ) | ||
### .parser | ||
Define a named parser to be used against any given string. | ||
Set a parser that can later be used to parse any given string. | ||
```js | ||
strings.parser (name, replacements) | ||
``` | ||
**Example** | ||
@@ -106,3 +124,2 @@ | ||
``` | ||
Or an array | ||
@@ -123,14 +140,15 @@ | ||
* `name` {String}: name of the parser. | ||
* `pairings` {Object|Array}: array of replacement patterns to store with the given name. | ||
* `pattern` {String|RegExp}: | ||
* `replacement` {String|Function}: | ||
* `return` {Object} Instance of the current Strings object | ||
* `name` {String} | ||
* `arr` {Object|Array}: Object or array of replacement patterns to associate. | ||
* `return`{Strings} to allow chaining | ||
### .parsers ( parsers ) | ||
### .parsers | ||
Return a list of parsers based on the given list of named | ||
parsers or parser objects. | ||
Get an array of stored parsers by passing a parser name or array of parser names. | ||
```js | ||
strings.parsers(array) | ||
``` | ||
**Example** | ||
@@ -146,2 +164,3 @@ | ||
Using `parsers` like this: | ||
@@ -176,17 +195,22 @@ | ||
* `parsers` {String|Array}: named parsers or parser objects to use. | ||
* `return` {Array} | ||
* `parsers` {String|Array}: string or array of parsers to get. | ||
* `return`{Array} | ||
### .extend ( parser, replacement-patterns ) | ||
### .extendParser | ||
Extend a parser. | ||
Extend a parser with additional replacement patterns. Useful if you're using | ||
an external module for replacement patterns and you need to extend it. | ||
```js | ||
strings.extendParser(parser, replacements) | ||
``` | ||
**Example** | ||
```js | ||
strings.extend('prop', { | ||
strings.extendParser('prop', { | ||
pattern: /:([\\w]+)/, | ||
replacement: function(match) { | ||
return match.toUpperCase(); | ||
replacement: function(str) { | ||
return str.toUpperCase(); | ||
} | ||
@@ -198,110 +222,79 @@ ); | ||
* `arr` {Object|Array}: array of replacement patterns to store with the given name. | ||
* `pattern` {String|RegExp}: | ||
* `replacement` {String|Function}: | ||
* `return` {Object} Instance of the current Strings object | ||
* `pattern` {String|RegExp} | ||
* `replacement` {String|Function} | ||
* `return`{Strings} to allow chaining | ||
### .template ( name, propstring, parsers ) | ||
### .template | ||
Store, by name, a named propstring and an array of parsers. | ||
Set or get a reusable Strings template, consisting of a propstring | ||
and an array of parsers. | ||
**Example** | ||
Templates are useful since they can be stored and then later used | ||
with any context. | ||
```js | ||
// strings.template(name string, array); | ||
strings.template('prop', ['prop'], { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
}); | ||
strings.template(name, propstring, parsers); | ||
``` | ||
* `name` {String}: The name of the template to store | ||
* `name` {String}: Name of replacement group to use for building the final string | ||
* `context` {Object}: Optional Object to bind to replacement function as `this` | ||
* `return` {String} | ||
### .transform ( named-propstring, named-parsers, context ) | ||
Similar to `.process`, except that the first parameter is the name | ||
of the stored `propstring` to use, rather than any given string. | ||
**Example** | ||
```js | ||
strings.transform('propstring', ['parser'], { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
}); | ||
strings.template('abc', ':a/:b/:c', ['a', 'b', 'c']); | ||
// or use a named propstring | ||
strings.template('abc', 'foo', ['a', 'b', 'c']); | ||
here ^ | ||
``` | ||
Or pass an object, `strings.transform({})`: | ||
* `name` {String} | ||
* `propstring` {String} | ||
* `parsers` {Array}: Names of the parsers to use with the template. | ||
* `return`{Strings} to allow chaining | ||
```js | ||
strings.transform({ | ||
propstring: 'prop', | ||
parsers: ['prop'], | ||
context: { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
} | ||
}); | ||
``` | ||
* `name` {String}: The name of the stored template to use | ||
* `context` {Object}: The optional context object to bind to replacement functions as `this` | ||
* `return` {String} | ||
### .replace | ||
Replace `:propstrings` with the real values. | ||
### .use ( named-propstring, named-parsers, context ) | ||
Similar to `.process`, except that the first parameter is the name | ||
of the stored `propstring` to use, rather than any given string. | ||
**Example** | ||
```js | ||
strings.use('propstring', ['parser'], { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
}); | ||
strings.replace(str, context) | ||
``` | ||
Or pass an object, `strings.use({})`: | ||
**Example** | ||
```js | ||
strings.use({ | ||
propstring: 'prop', | ||
parsers: ['prop'], | ||
context: { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
} | ||
strings.replace(':a/:b/:c', { | ||
a: 'foo', | ||
b: 'bar', | ||
c: 'baz' | ||
}); | ||
//=> foo/bar/baz | ||
``` | ||
* `name` {String}: The name of the stored template to use | ||
* `context` {Object}: The optional context object to bind to replacement functions as `this` | ||
* `return` {String} | ||
* `str` {String}: The string with `:propstrings` to replace. | ||
* `context` {String}: The object with replacement properties. | ||
* `return`{Strings} to allow chaining | ||
### .process ( str, parsers, context ) | ||
### .process | ||
Directly process the given string, using a named replacement | ||
Directly process the given prop-string, using a named replacement | ||
pattern or array of named replacement patterns, with the given | ||
context. | ||
**Example** | ||
```js | ||
strings.process(str, parsers, context) | ||
``` | ||
**Examples:** | ||
Pass a propstring and the parsers to use: | ||
```js | ||
strings.process(':foo/:bar/:baz', ['a', 'b', 'c'], { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
}); | ||
// define some parsers to do simple key-value replacements | ||
strings.parser('a', {'{foo}': 'AAA'}); | ||
strings.parser('b', {'{bar}': 'BBB'}); | ||
strings.parser('c', {'{baz}': 'CCC'}); | ||
console.log(strings.process('{foo}/{bar}/{baz}', ['a', 'b', 'c'])); | ||
// => 'AAA/BBB/CCC' | ||
``` | ||
@@ -311,63 +304,42 @@ | ||
* `parsers` {String|Object|Array}: named parsers or parser objects to use when processing. | ||
* `context` {Object}: context to use. optional if a global context is passed. | ||
* `return` {String} | ||
* `context` {Object}: context to use. optional if a global context is passed. | ||
* `return`{String} | ||
### .group ( name, propstring, parsers ) | ||
### .run | ||
Define a named group of propstring/parser mappings, or get a | ||
group if only the name is passed. | ||
Process a template with the given context. | ||
**Example** | ||
```js | ||
strings.group('my-group-name', ':foo/:bar/:baz', ['a', 'b', 'c']); | ||
strings.run(template, context) | ||
``` | ||
To get a group: | ||
```js | ||
strings.group( name ); | ||
``` | ||
* `name` {String}: | ||
* `propstring` {String}: the name of the propstring to use | ||
* `parsers` {String|Array}: name or array of names of parsers to use | ||
* `return` {Object} Instance of the current Strings object | ||
### .run ( groupname, context ) | ||
Process the specified group using the given context. | ||
**Example** | ||
Set: (`strings.run( string, object )`) | ||
```js | ||
strings.run('my-group-name', { | ||
foo: 'aaa', | ||
bar: 'bbb', | ||
baz: 'ccc' | ||
strings.run('blogTemplate', { | ||
dest: '_gh_pages', | ||
basename: '2014-07-01-post', | ||
ext: '.html' | ||
}); | ||
``` | ||
* `group` {String}: The group to run. | ||
* `context` {Object}: Optional context object, to bind to replacement function as `this` | ||
* `return` {String} | ||
* `template` {String}: The template to process. | ||
* `context` {Object}: Optional context object, to bind to replacement function as `this` | ||
* `return`{String} | ||
## Authors | ||
**Jon Schlinkert** | ||
+ [github/jonschlinkert](https://github.com/jonschlinkert) | ||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) | ||
**Brian Woodward** | ||
+ [github/doowb](https://github.com/doowb) | ||
+ [twitter/doowb](http://twitter.com/doowb) | ||
+ [twitter/doowb](http://twitter.com/doowb) | ||
**Jon Schlinkert** | ||
+ [github/jonschlinkert](https://github.com/jonschlinkert) | ||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) | ||
## License | ||
@@ -379,2 +351,2 @@ Copyright (c) 2014 Brian Woodward, contributors. | ||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on May 27, 2014._ | ||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on June 30, 2014._ |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var expect = require('chai').expect; | ||
var Strings = require('../'); | ||
describe('.parser() - add', function() { | ||
var strings = new Strings(); | ||
describe('.parser', function() { | ||
var strings; | ||
beforeEach(function() { | ||
strings = new Strings(); | ||
}); | ||
describe('when a named parser is defined', function() { | ||
it('should replace values with strings', function () { | ||
var name = 'test-parser-1'; | ||
var actual = [{ | ||
@@ -21,9 +27,8 @@ ':basename': 'foo', | ||
}]; | ||
strings.parser(name, actual); | ||
expect(strings._parsers).to.have.property(name); | ||
expect(actual).to.eql(strings._parsers[name]); | ||
strings.parser('a', actual); | ||
expect(strings._parsers).to.have.property('a'); | ||
expect(actual).to.eql(strings._parsers['a']); | ||
}); | ||
it('should replace values with functions', function () { | ||
var name = 'test-parser-1'; | ||
var actual = [{ | ||
@@ -38,16 +43,11 @@ ':basename': function () { | ||
strings.parser(name, actual); | ||
expect(strings._parsers).to.have.property(name); | ||
expect(actual).to.eql(strings._parsers[name]); | ||
strings.parser('b', actual); | ||
expect(strings._parsers).to.have.property('b'); | ||
expect(actual).to.eql(strings._parsers['b']); | ||
}); | ||
}); | ||
}); | ||
describe('.parser() - get', function() { | ||
var strings = new Strings(); | ||
describe('when only one paramter is passed', function() { | ||
it('it should retrieve the stored parser with the given name', function () { | ||
var name = 'test-parser-2'; | ||
var actual = [{ | ||
it('it should get the parser with the given name', function () { | ||
var parser = { | ||
':basename': function () { | ||
@@ -59,7 +59,7 @@ return 'foo'; | ||
} | ||
}]; | ||
strings.parser(name, actual); | ||
expect(actual).to.eql(strings.parser(name)); | ||
}; | ||
strings.parser('c', parser); | ||
expect(strings.parser('c')).to.eql([parser]); | ||
}); | ||
}); | ||
}); |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var expect = require('chai').expect; | ||
@@ -10,0 +11,0 @@ var Strings = require('../'); |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var expect = require('chai').expect; | ||
var Strings = require('../'); | ||
describe('.pattern()', function() { | ||
describe('.pattern', function() { | ||
var strings = new Strings(); | ||
@@ -14,0 +15,0 @@ describe('when a pattern is set', function() { |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var path = require('path'); | ||
var expect = require('chai').expect; | ||
@@ -13,3 +15,3 @@ var Strings = require('../'); | ||
describe('.template()', function () { | ||
describe('.template', function () { | ||
@@ -19,23 +21,184 @@ var strings; | ||
strings = new Strings(); | ||
strings.propstring('pathProps', ':destbase/:dirname/:basename/index:ext'); | ||
strings.parser('parsePath', [ | ||
{ | ||
pattern: ':destbase', | ||
replacement: function () { | ||
return this.destbase; | ||
} | ||
}, | ||
{ | ||
pattern: ':dirname', | ||
replacement: function () { | ||
return path.dirname(this.src); | ||
} | ||
}, | ||
{ | ||
pattern: ':basename', | ||
replacement: function () { | ||
return path.basename(this.src, path.extname(this.src)); | ||
}, | ||
}, | ||
{ | ||
pattern: ':ext', | ||
replacement: function () { | ||
return path.extname(this.src); | ||
} | ||
} | ||
]); | ||
strings.template('permalinks', 'pathProps', ['parsePath']); | ||
}); | ||
it('when a template is passed in', function () { | ||
var expected = ':basename/index:ext'; | ||
var actual = strings.process(':basename/index:ext'); | ||
expect(actual).to.eql(expected); | ||
describe('when no context is passed', function () { | ||
it('should process the propstring with an array of parsers', function () { | ||
strings.parser('a', {'{foo}': 'AAA'}); | ||
strings.parser('b', {'{bar}': 'BBB'}); | ||
strings.parser('c', {'{baz}': 'CCC'}); | ||
var actual = strings.process('{foo}/{bar}/{baz}', ['a', 'b', 'c']); | ||
expect(actual).to.eql('AAA/BBB/CCC'); | ||
}); | ||
}); | ||
it('when a template and parser object are passed in', function () { | ||
var expected = 'file/index.html'; | ||
var parser = { | ||
':basename': 'file', | ||
':ext': '.html' | ||
}; | ||
var actual = strings.process(':basename/index:ext', parser); | ||
expect(actual).to.eql(expected); | ||
describe('when a context is passed', function () { | ||
it('should process the propstring with an array of parsers', function () { | ||
strings.parser('a', {'{foo}': function() { | ||
return this.alpha.toUpperCase(); | ||
}}); | ||
strings.parser('b', {'{bar}': function() { | ||
return this.beta.toUpperCase(); | ||
}}); | ||
strings.parser('c', {'{baz}': function() { | ||
return this.gamma.toUpperCase(); | ||
}}); | ||
var ctx = { | ||
alpha: 'aaa', | ||
beta: 'bbb', | ||
gamma: 'ccc' | ||
}; | ||
var actual = strings.process('{foo}/{bar}/{baz}', ['a', 'b', 'c'], ctx); | ||
expect(actual).to.eql('AAA/BBB/CCC'); | ||
}); | ||
}); | ||
it('when a template, parser object, and context are passed in', function () { | ||
var path = require('path'); | ||
var expected = 'file/index.html'; | ||
describe('when the name of a stored template is passed', function () { | ||
it('should use the propstring and parsers from the template with the given context', function () { | ||
var actual = strings.process('permalinks', { | ||
destbase: 'foo', | ||
src: 'a/b.html' | ||
}); | ||
expect(actual).to.eql('foo/a/b/index.html'); | ||
}); | ||
it('should process the stored propstring with the given context', function () { | ||
var actual = strings.process('permalinks', { | ||
destbase: '_gh_pages', | ||
src: 'blog/file.html' | ||
}); | ||
expect(actual).to.eql('_gh_pages/blog/file/index.html'); | ||
}); | ||
it('should use the propstring and parsers from the template with the given context', function () { | ||
var actual = strings.process('permalinks', { | ||
destbase: 'bar', | ||
src: 'a/b.html' | ||
}); | ||
expect(actual).to.eql('bar/a/b/index.html'); | ||
}); | ||
}); | ||
describe('when a single argument is passed:', function () { | ||
it('should throw an error', function () { | ||
var actual; | ||
try { | ||
strings.process(':basename/index:ext'); | ||
} catch(err) { | ||
actual = err; | ||
} | ||
expect(/Error/.test(actual)).to.be.true; | ||
}); | ||
}); | ||
describe('when a template...:', function () { | ||
describe('and parser object are passed:', function () { | ||
it('should replace propstrings with the parser', function () { | ||
var actual = strings.process(':basename/index:ext', { | ||
':basename': 'file', | ||
':ext': '.html' | ||
}); | ||
expect(actual).to.eql('file/index.html'); | ||
}); | ||
}); | ||
describe('and parser object and context are passed:', function () { | ||
it('should replace propstrings with the parser using the given context', function () { | ||
var parser = [ | ||
{ | ||
pattern: ':basename', | ||
replacement: function () { | ||
return path.basename(this.filepath, path.extname(this.filepath)); | ||
} | ||
}, | ||
{ | ||
pattern: ':ext', | ||
replacement: function () { | ||
return path.extname(this.filepath); | ||
} | ||
} | ||
]; | ||
var actual = strings.process(':basename/index:ext', parser, { | ||
filepath: 'path/to/my/file.html' | ||
}); | ||
expect(actual).to.eql('file/index.html'); | ||
}); | ||
}); | ||
}); | ||
it('when a template, parser object, and context are passed', function () { | ||
var parser = [ | ||
{ | ||
pattern: /:basename/, | ||
replacement: function () { | ||
return path.basename(this.filepath, path.extname(this.filepath)); | ||
} | ||
}, | ||
{ | ||
pattern: /:ext/, | ||
replacement: function () { | ||
return path.extname(this.filepath); | ||
} | ||
} | ||
] | ||
var actual = strings.process(':basename/index:ext', parser, { | ||
filepath: 'path/to/my/file.html' | ||
}); | ||
expect(actual).to.eql('file/index.html'); | ||
}); | ||
it('when a template, parser object, and context are passed', function () { | ||
var parser = [ | ||
{ | ||
pattern: /\{basename}/, | ||
replacement: function () { | ||
return path.basename(this.filepath, path.extname(this.filepath)); | ||
} | ||
}, | ||
{ | ||
pattern: /\{ext}/, | ||
replacement: function () { | ||
return path.extname(this.filepath); | ||
} | ||
} | ||
]; | ||
var actual = strings.process('{basename}/index{ext}', parser, { | ||
filepath: 'path/to/my/file.html' | ||
}); | ||
expect(actual).to.eql('file/index.html'); | ||
}); | ||
it('when a template, parser object, and context are passed', function () { | ||
var parser = { | ||
@@ -49,13 +212,10 @@ ':basename': function () { | ||
}; | ||
var context = { | ||
var actual = strings.process(':basename/index:ext', parser, { | ||
filepath: 'path/to/my/file.html' | ||
}; | ||
var actual = strings.process(':basename/index:ext', parser, context); | ||
expect(actual).to.eql(expected); | ||
}); | ||
expect(actual).to.eql('file/index.html'); | ||
}); | ||
it('when a template, named parser, and context are passed in', function () { | ||
var path = require('path'); | ||
var expected = 'file/index.html'; | ||
var parser = { | ||
it('when a template, named parser, and context are passed', function () { | ||
strings.parser('path', { | ||
':basename': function () { | ||
@@ -67,12 +227,126 @@ return path.basename(this.filepath, path.extname(this.filepath)); | ||
} | ||
}; | ||
var context = { | ||
}); | ||
var actual = strings.process(':basename/index:ext', 'path', { | ||
filepath: 'path/to/my/file.html' | ||
}; | ||
}); | ||
expect(actual).to.eql('file/index.html'); | ||
}); | ||
strings.parser('path', parser); | ||
var actual = strings.process(':basename/index:ext', 'path', context); | ||
expect(actual).to.eql(expected); | ||
describe('when a named propstring and parser object are defined', function () { | ||
it('should get the propstring and parse it.', function () { | ||
var actual = strings.process('{a}/{b}', { | ||
'{a}': 'foo', | ||
'{b}': 'bar' | ||
}); | ||
expect(actual).to.eql('foo/bar'); | ||
}); | ||
}); | ||
describe('when a parser has replacement functions', function () { | ||
describe('when fallback values are defined in the functions', function () { | ||
it('should use the fallbacks when a value is not on the context', function () { | ||
strings.parser('nonsensical', [ | ||
{ | ||
pattern: /\{a}/g, | ||
replacement: function () { | ||
return this.a || '__UNKNOWN_A__'; | ||
} | ||
}, | ||
{ | ||
pattern: /\{b}/g, | ||
replacement: function () { | ||
return this.b || '__UNKNOWN_B__'; | ||
} | ||
}, | ||
{ | ||
pattern: /\{c}/g, | ||
replacement: function () { | ||
return this.c || '__UNKNOWN_C__'; | ||
} | ||
} | ||
]); | ||
var actual = strings.process('{a}/{b}/{c}', 'nonsensical', {a: 'foo', c: 'bar'}); | ||
expect(actual).to.eql('foo/__UNKNOWN_B__/bar'); | ||
}); | ||
}); | ||
}); | ||
describe('when a propstrings are defined but a value is missing on the context', function () { | ||
it('should just return the actual propstring in the result.', function () { | ||
var parser = { | ||
'{base}': function () { | ||
return this.base; | ||
}, | ||
'{name}': function () { | ||
return this.name; | ||
}, | ||
'{ext}': function () { | ||
return this.ext; | ||
} | ||
}; | ||
strings.template('permalink', '{base}/{dirname}/{name}/index{ext}', parser); | ||
var actual = strings.process('permalink', { | ||
base: '_gh_pages', | ||
name: 'blog', | ||
ext: '.html' | ||
}); | ||
expect(actual).to.eql('_gh_pages/{dirname}/blog/index.html'); | ||
}); | ||
}); | ||
it('when a propstring and parser object are passed', function () { | ||
var actual = strings.process(':a/:b/:c/index:d', {':c': 'file', ':d': '.html'}); | ||
expect(actual).to.eql(':a/:b/file/index.html'); | ||
}); | ||
describe('when a propstring, parser object, and context are passed:', function () { | ||
it('should process the string with the given context.', function () { | ||
var parser = { | ||
':c': function () { | ||
return path.basename(this.foo, path.extname(this.foo)); | ||
}, | ||
':d': function () { | ||
return path.extname(this.foo); | ||
}, | ||
':a': function () { | ||
return this.destbase; | ||
} | ||
}; | ||
var actual = strings.process(':a/:b/:c/index:d', parser, { | ||
foo: 'path/to/my/file.html', | ||
destbase: '_gh_pages' | ||
}); | ||
expect(actual).to.eql('_gh_pages/:b/file/index.html'); | ||
}); | ||
}); | ||
describe('when a default value is passed the parser', function () { | ||
it('should be used if it\'s not on the context', function () { | ||
var parser = { | ||
':c': function () { | ||
return path.basename(this.foo, path.extname(this.foo)); | ||
}, | ||
':d': function () { | ||
return path.extname(this.foo); | ||
}, | ||
':a': function () { | ||
return this.destbase || '.'; | ||
} | ||
}; | ||
strings.parser('path', parser); | ||
var actual = strings.process(':a/:b/:c/index:d', 'path', { | ||
foo: 'path/to/my/file.html' | ||
}); | ||
expect(actual).to.eql('./:b/file/index.html'); | ||
}); | ||
}); | ||
}); |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var expect = require('chai').expect; | ||
@@ -14,20 +15,26 @@ var Strings = require('../'); | ||
var strings = new Strings(); | ||
strings.propstring('pretty', ':destbase/:dirname/:basename/index:ext'); | ||
strings.propstring('test1', ':foo/:baz/:basename/index:ext'); | ||
strings.propstring('test2', ':basename/index:ext'); | ||
describe('when a propstring is set', function() { | ||
it('should be stored by Strings on the `_propstrings` object:', function () { | ||
var name = 'test1'; | ||
var template = ':foo/:baz/:basename/index:ext'; | ||
strings.propstring(name, template); | ||
var actual = strings._propstrings[name]; | ||
expect(strings._propstrings).to.have.property(name); | ||
expect(actual).to.eql(template); | ||
var actual = strings._propstrings['test1']; | ||
expect(strings._propstrings).to.have.property('test1'); | ||
expect(actual).to.eql(':foo/:baz/:basename/index:ext'); | ||
}); | ||
it('should be retrievable using `propstring(name)`', function () { | ||
var name = 'test2'; | ||
var template = ':basename/index:ext'; | ||
strings.propstring(name, template); | ||
var actual = strings.propstring(name); | ||
expect(template).to.eql(template); | ||
it('should be able to get the propstring using the name', function () { | ||
var actual = strings.propstring('test2'); | ||
expect(actual).to.eql(':basename/index:ext'); | ||
}); | ||
it('should get a stored propstring', function () { | ||
var actual = strings.propstring('pretty'); | ||
expect(actual).to.eql(':destbase/:dirname/:basename/index:ext'); | ||
}); | ||
}); | ||
}); |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var expect = require('chai').expect; | ||
@@ -14,21 +15,18 @@ var Strings = require('../'); | ||
var strings = new Strings(); | ||
describe('when a replacement is set', function() { | ||
it('should be stored by Strings on the `_replacements` object:', function () { | ||
var name = 'a'; | ||
var replacement = 'b'; | ||
strings.replacement(name, replacement); | ||
var actual = strings._replacements[name]; | ||
expect(strings._replacements).to.have.property(name); | ||
expect(actual).to.eql(replacement); | ||
strings.replacement('a', 'b'); | ||
expect(strings._replacements).to.have.property('a'); | ||
expect(strings._replacements['a']).to.eql('b'); | ||
}); | ||
it('should be retrievable using `replacement(name)`', function () { | ||
var name = 'b'; | ||
var replacement = function(match) { return match; }; | ||
strings.replacement(name, replacement); | ||
var actual = strings.replacement(name); | ||
expect(replacement).to.eql(replacement); | ||
expect(actual).to.be.an.instanceof(Function); | ||
strings.replacement('b', replacement); | ||
expect(strings.replacement('b')).to.eql(replacement); | ||
expect(strings.replacement('b')).to.be.an.instanceof(Function); | ||
}); | ||
}); | ||
}); |
/** | ||
* Sellside <http://www.sellside.com> | ||
* Created and maintained by Jon Schlinkert and Brian Woodward | ||
* Strings <https://github.com/assemble/strings> | ||
* | ||
* Copyright (c) 2014 Sellside. | ||
* Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward | ||
* Licensed under the MIT License (MIT). | ||
*/ | ||
'use strict'; | ||
var expect = require('chai').expect; | ||
var Strings = require('../'); | ||
var path = require('path'); | ||
var Strings = require('..'); | ||
describe('.template()', function () { | ||
describe('.template', function() { | ||
var strings; | ||
before(function () { | ||
beforeEach(function () { | ||
strings = new Strings(); | ||
strings.propstring('pretty', ':destbase/:dirname/:basename/index:ext'); | ||
strings.parser('path', [ | ||
{ | ||
pattern: ':destbase', | ||
replacement: function () { | ||
return this.destbase() | ||
} | ||
strings.propstring('pretty', ':a/:b/:c/index:d'); | ||
strings.parser('path', { | ||
':a': function () { | ||
return this.destbase; | ||
}, | ||
{ | ||
pattern: ':dirname', | ||
replacement: function () { | ||
return path.dirname(this.src); | ||
} | ||
':b': function () { | ||
return path.dirname(this.src); | ||
}, | ||
{ | ||
pattern: ':basename', | ||
replacement: function () { | ||
return path.basename(this.src, path.extname(this.src)); | ||
}, | ||
':c': function () { | ||
return path.basename(this.src, path.extname(this.src)); | ||
}, | ||
{ | ||
pattern: ':ext', | ||
replacement: function () { | ||
return path.extname(this.src); | ||
} | ||
':d': function () { | ||
return path.extname(this.src); | ||
} | ||
]); | ||
}); | ||
strings.template('permalinks', 'pretty', ['path']); | ||
}); | ||
describe('when propstring and parsers are passed as params', function () { | ||
it('should return the template by name', function () { | ||
it('when a template without a parser object is passed', function () { | ||
strings.propstring('aaa', ':basename/index:ext'); | ||
var actual = ''; | ||
try { | ||
strings.template('foo', 'aaa'); | ||
} catch(err) { | ||
actual = err; | ||
} | ||
expect(/Error/.test(actual)).to.be.true; | ||
strings._propstrings = {}; | ||
}); | ||
describe('when a single argument is passed', function () { | ||
it('should lookup template by the given string', function () { | ||
var expected = { | ||
propstring: ':destbase/:dirname/:basename/index:ext', | ||
propstring: ':a/:b/:c/index:d', | ||
parsers: ['path'] | ||
}; | ||
var actual = strings.template('permalinks'); | ||
expect(actual).to.eql(expected); | ||
expect(strings.template('permalinks')).to.eql(expected); | ||
}); | ||
}); | ||
describe('when template is set', function () { | ||
it('should be in on the `_templates` object', function () { | ||
strings.template('a', 'b', ['a', 'b']); | ||
expect(strings._templates).to.have.property('a'); | ||
expect(strings._templates['a']).to.eql({propstring: 'b', parsers: ['a', 'b']}); | ||
expect(strings.template('a')).to.eql({propstring: 'b', parsers: ['a', 'b']}); | ||
}); | ||
}); | ||
describe('when propstring and parsers are passed as properties on an object', function () { | ||
@@ -65,7 +73,6 @@ it('should return the template by name', function () { | ||
var expected = { | ||
propstring: ':destbase/:dirname/:basename/index:ext', | ||
propstring: ':a/:b/:c/index:d', | ||
parsers: ['path'] | ||
}; | ||
var actual = strings.template('foo'); | ||
expect(actual).to.eql(expected); | ||
expect(strings.template('foo')).to.eql(expected); | ||
}); | ||
@@ -75,64 +82,5 @@ }); | ||
it('should get a stored propstring', function () { | ||
var expected = ':destbase/:dirname/:basename/index:ext'; | ||
var actual = strings.propstring('pretty'); | ||
expect(actual).to.eql(expected); | ||
expect(actual).to.eql(':a/:b/:c/index:d'); | ||
}); | ||
it('when a propstring and parser object are passed in', function () { | ||
var expected = ':destbase/:dirname/file/index.html'; | ||
var parser = { | ||
':basename': 'file', | ||
':ext': '.html' | ||
}; | ||
var actual = strings.transform('pretty', parser); | ||
expect(actual).to.eql(expected); | ||
}); | ||
it('when a propstring, parser object, and context are passed in', function () { | ||
var path = require('path'); | ||
var expected = '_gh_pages/:dirname/file/index.html'; | ||
var parser = { | ||
':basename': function () { | ||
return path.basename(this.filepath, path.extname(this.filepath)); | ||
}, | ||
':ext': function () { | ||
return path.extname(this.filepath); | ||
}, | ||
':destbase': function () { | ||
return this.destbase; | ||
} | ||
}; | ||
var context = { | ||
filepath: 'path/to/my/file.html', | ||
destbase: '_gh_pages' | ||
}; | ||
var actual = strings.transform('pretty', parser, context); | ||
expect(actual).to.eql(expected); | ||
}); | ||
describe('when a default value is passed in the parser', function () { | ||
it('should be used if it\'s not on the context', function () { | ||
var path = require('path'); | ||
var expected = './:dirname/file/index.html'; | ||
var parser = { | ||
':basename': function () { | ||
return path.basename(this.filepath, path.extname(this.filepath)); | ||
}, | ||
':ext': function () { | ||
return path.extname(this.filepath); | ||
}, | ||
':destbase': function () { | ||
return this.destbase || '.'; | ||
} | ||
}; | ||
var context = { | ||
filepath: 'path/to/my/file.html' | ||
}; | ||
strings.parser('path', parser); | ||
var actual = strings.transform('pretty', 'path', context); | ||
expect(actual).to.eql(expected); | ||
}); | ||
}); | ||
}); |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
53528
0
9
26
1227
341