diff --git a/lib/block.js b/lib/block.js index d10ba39..f0a62a4 100644 --- a/lib/block.js +++ b/lib/block.js @@ -20,6 +20,26 @@ Block.prototype.compile = function () { return this.config.keepUnassigned ? this.originals : []; } + // get the replacement strings and do replacements for extensions + if (this.uniqueExts) { + var basename = path.basename(this.file.path); + var extname = path.extname(basename); + basename = basename.slice(0, basename.lastIndexOf(extname)) + if (this.uniqueExts['%f']) + this.uniqueExts['%f'].value = basename; + if (this.uniqueExts['%e']) + this.uniqueExts['%e'].value = extname; + + Object.keys(this.uniqueExts).forEach(function (key) { + var unique = this.uniqueExts[key]; + this.template = this.template.replace(unique.regex, unique.value); + }.bind(this)); + } + + if (this.srcIsNull) { + return this.indent + this.template; + } + return this.replacements.map(function (replacement) { if (this.template) { if (Array.isArray(replacement)) { @@ -51,10 +71,13 @@ Block.prototype.compile = function () { }.bind(this)); }; + Block.prototype.reset = function () { this.originals = []; this.replacements = []; this.template = null; + this.uniqueExts = null; + this.srcIsNull = false; }; Block.prototype.setTask = function (task) { @@ -64,6 +87,8 @@ Block.prototype.setTask = function (task) { if (task) { this.replacements = task.src; this.template = task.tpl; + this.uniqueExts = task.uni; + this.srcIsNull = task.srcIsNull; } }; diff --git a/lib/index.js b/lib/index.js index 6f7b212..86e4b8d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -14,9 +14,7 @@ module.exports = function (options, userConfig) { if (typeof userConfig === 'boolean') { config.keepUnassigned = userConfig; - } - - if (typeof userConfig === 'object') { + } else if (typeof userConfig === 'object') { config = extend(config, userConfig); } @@ -58,6 +56,8 @@ module.exports = function (options, userConfig) { * .... * } */ +var utilExtensions = /%f|%e/g; + function getTasks(options) { var tasks = {}; @@ -65,17 +65,35 @@ function getTasks(options) { var item = options[key]; var src = []; var tpl = null; + var uniqueExtensions = {}; + var result; + var srcIsNull; - if (item.src) { + if (typeof item.src !== 'undefined') { + srcIsNull = item.src === null; src = src.concat(item.src); tpl = item.tpl; } else { src = src.concat(item); } + while (result = utilExtensions.exec(tpl)) { + var type = result[0]; + var unique = {}; + + if (uniqueExtensions[type]) + continue; + + unique.regex = new RegExp(result[0], "g"); + unique.value = null; + uniqueExtensions[type] = unique; + } + tasks[key] = { src: src, - tpl: tpl + tpl: tpl, + uni: uniqueExtensions, + srcIsNull: srcIsNull }; }); diff --git a/package.json b/package.json index 18cf037..fc25834 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp-html-replace", - "version": "1.3.0", + "version": "1.4.0", "description": "Replace build blocks in HTML. Like useref but done right.", "keywords": [ "gulpplugin", @@ -15,6 +15,10 @@ "name": "Vladimir Kucherenko", "email": "kvsoftware@gmail.com" }, + "contributors": [ + {"name": "Bruce MacNaughton", + "email": "bmacnaughton@gmail.com"} + ], "main": "./lib/index.js", "scripts": { "test": "mocha --reporter spec", diff --git a/readme.md b/readme.md index c2267e1..c5c700f 100644 --- a/readme.md +++ b/readme.md @@ -69,6 +69,36 @@ htmlreplace({ > In the second example `data-main="%s"` and `src="%s"` will be replaced with `data-main.js` and `require-src.js` accordingly, producing `` as the result +###### Extended replacements: +```javascript +// Replacement based on the file being processed +htmlreplace({ + js: { + src: null, + tpl: '' + } +}) +// Extended replacement combined with standard replacement +htmlreplace({ + js: { + src: 'dir', + tpl: '' + } +}) + +``` +* **src** - `null|String|Array` Same as examples above but null if there are no standard replacements in the template. +* **tpl** - `String` Template string. Extended replacements do not use `util.format()` and are performed before standard replacements. + +> In the first example `src` is null because there are no standard replacements. `%f` is replaced with the name (without extension) of the file currently being processed. If the file being processed is `xyzzy.html` the result is ``. + +> In the second example `src` has been set to the string `'dir'`. Extended replacements are processed first, replacing `%f` with `xyzzy`, then `%s` will be replaced with `dir` resulting in ``. + +Valid extended replacements are: + +* **%f** - this will be replaced with the filename, without an extension. +* **%e** - this will be replaced with the extension including the `.` character. + #### options Type: `object` diff --git a/test/buffer.js b/test/buffer.js index 91f8d7e..4e1aa67 100644 --- a/test/buffer.js +++ b/test/buffer.js @@ -47,6 +47,26 @@ describe('Buffer mode', function () { src: [['js/with_tpl_2vars1.js', 'js/with_tpl_2vars2.js'], ['js/with_tpl_2vars1_2.js', 'js/with_tpl_2vars2_2.js']], tpl: '' }, + js_files_x_tpl: { + src: null, + tpl: '' + }, + js_files_x_tpl_src: { + src: 'js', + tpl: '' + }, + js_files_x_tpl_multiple: { + src: ['js/with_tpl.js', 'js/with_tpl_2.js'], + tpl: '' + }, + js_files_x_tpl_2vars: { + src: [['js/with_tpl_2vars1.js', 'js/with_tpl_2vars2.js']], + tpl: '' + }, + js_files_x_tpl_2vars_multiple: { + src: [['js/with_tpl_2vars1.js', 'js/with_tpl_2vars2.js'], ['js/with_tpl_2vars1_2.js', 'js/with_tpl_2vars2_2.js']], + tpl: '' + }, 'lorem-ipsum': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }); diff --git a/test/expected.html b/test/expected.html index d55715d..54030b3 100644 --- a/test/expected.html +++ b/test/expected.html @@ -20,6 +20,18 @@ + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. diff --git a/test/fixture.html b/test/fixture.html index 2899853..21b9bce 100644 --- a/test/fixture.html +++ b/test/fixture.html @@ -30,6 +30,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/test/stream.js b/test/stream.js index cfed3c4..ae56593 100644 --- a/test/stream.js +++ b/test/stream.js @@ -51,6 +51,26 @@ describe('Stream mode', function () { src: [['js/with_tpl_2vars1.js', 'js/with_tpl_2vars2.js'], ['js/with_tpl_2vars1_2.js', 'js/with_tpl_2vars2_2.js']], tpl: '' }, + js_files_x_tpl: { + src: null, + tpl: '' + }, + js_files_x_tpl_src: { + src: 'js', + tpl: '' + }, + js_files_x_tpl_multiple: { + src: ['js/with_tpl.js', 'js/with_tpl_2.js'], + tpl: '' + }, + js_files_x_tpl_2vars: { + src: [['js/with_tpl_2vars1.js', 'js/with_tpl_2vars2.js']], + tpl: '' + }, + js_files_x_tpl_2vars_multiple: { + src: [['js/with_tpl_2vars1.js', 'js/with_tpl_2vars2.js'], ['js/with_tpl_2vars1_2.js', 'js/with_tpl_2vars2_2.js']], + tpl: '' + }, 'lorem-ipsum': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' });