-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passes full file path to the replacement function #76
Changes from 2 commits
4426673
6134613
8ebae0f
40c69e8
d16a62a
4507d01
717a199
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,19 @@ gulp.task('templates', function(){ | |
.pipe(gulp.dest('build/file.txt')); | ||
}); | ||
``` | ||
### Use FilePath | ||
```javascript | ||
var replace = require('gulp-replace'); | ||
|
||
gulp.task('templates', function(){ | ||
gulp.src(['file.txt']) | ||
.pipe(replace(/foo(.{3})/g, function($0, str){ | ||
return str + 'foo' + this.filePath; | ||
}, {passFileName: true})) | ||
.pipe(gulp.dest('build/file.txt')); | ||
}); | ||
``` | ||
|
||
### String Replace | ||
```javascript | ||
var replace = require('gulp-replace'); | ||
|
@@ -61,6 +74,8 @@ Type: `String` or `Function` | |
|
||
The replacement string or function. See the [MDN documentation for String.replace] for details. | ||
|
||
if `Function` and `options.passFileName` is true, then Function within the filePath is equal to the current file `file.path`. | ||
|
||
### gulp-replace options | ||
|
||
An optional third argument, `options`, can be passed. | ||
|
@@ -69,11 +84,17 @@ An optional third argument, `options`, can be passed. | |
Type: `Object` | ||
|
||
##### options.skipBinary | ||
Type: `boolean` | ||
Type: `boolean` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These actually need two spaces or a line break after them, otherwise they appear on the same line |
||
Default: `false` | ||
|
||
Skip binary files | ||
|
||
##### options.passFileName | ||
Type: `boolean` | ||
Default: `false` | ||
|
||
Passes full file path to the replacement function | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
|
||
[MDN documentation for RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp | ||
[MDN documentation for String.replace]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,73 +5,86 @@ var rs = require('replacestream'); | |
var istextorbinary = require('istextorbinary'); | ||
|
||
module.exports = function(search, replacement, options) { | ||
return new Transform({ | ||
objectMode: true, | ||
transform: function(file, enc, callback) { | ||
if (file.isNull()) { | ||
return callback(null, file); | ||
} | ||
|
||
function doReplace() { | ||
if (file.isStream()) { | ||
file.contents = file.contents.pipe(rs(search, replacement)); | ||
return callback(null, file); | ||
} | ||
|
||
if (file.isBuffer()) { | ||
if (search instanceof RegExp) { | ||
file.contents = new Buffer(String(file.contents).replace(search, replacement)); | ||
} | ||
else { | ||
var chunks = String(file.contents).split(search); | ||
|
||
var result; | ||
if (typeof replacement === 'function') { | ||
// Start with the first chunk already in the result | ||
// Replacements will be added thereafter | ||
// This is done to avoid checking the value of i in the loop | ||
result = [ chunks[0] ]; | ||
|
||
// The replacement function should be called once for each match | ||
for (var i = 1; i < chunks.length; i++) { | ||
// Add the replacement value | ||
result.push(replacement(search)); | ||
|
||
// Add the next chunk | ||
result.push(chunks[i]); | ||
} | ||
|
||
result = result.join(''); | ||
} | ||
else { | ||
result = chunks.join(replacement); | ||
} | ||
|
||
file.contents = new Buffer(result); | ||
} | ||
return callback(null, file); | ||
} | ||
|
||
callback(null, file); | ||
} | ||
|
||
if (options && options.skipBinary) { | ||
istextorbinary.isText(file.path, file.contents, function(err, result) { | ||
if (err) { | ||
return callback(err, file); | ||
} | ||
|
||
if (!result) { | ||
callback(null, file); | ||
} else { | ||
doReplace(); | ||
} | ||
}); | ||
|
||
return; | ||
} | ||
|
||
doReplace(); | ||
} | ||
}); | ||
return new Transform({ | ||
objectMode: true, | ||
transform: function(file, enc, callback) { | ||
if (file.isNull()) { | ||
return callback(null, file); | ||
} | ||
|
||
function doReplace() { | ||
if (file.isStream()) { | ||
file.contents = file.contents.pipe(rs(search, replacement)); | ||
return callback(null, file); | ||
} | ||
|
||
if (file.isBuffer()) { | ||
if (search instanceof RegExp) { | ||
file.contents = new Buffer(String(file.contents).replace(search, replacement)); | ||
} | ||
else { | ||
var chunks = String(file.contents).split(search); | ||
|
||
var result; | ||
if (typeof replacement === 'function') { | ||
// Start with the first chunk already in the result | ||
// Replacements will be added thereafter | ||
// This is done to avoid checking the value of i in the loop | ||
result = [ chunks[0] ]; | ||
|
||
// The replacement function should be called once for each match | ||
for (var i = 1; i < chunks.length; i++) { | ||
// Add the replacement value | ||
result.push(replacement(search)); | ||
|
||
// Add the next chunk | ||
result.push(chunks[i]); | ||
} | ||
|
||
result = result.join(''); | ||
} | ||
else { | ||
result = chunks.join(replacement); | ||
} | ||
|
||
file.contents = new Buffer(result); | ||
} | ||
return callback(null, file); | ||
} | ||
|
||
callback(null, file); | ||
} | ||
|
||
if (options) { | ||
if (options.passFileName && typeof replacement === 'function') { | ||
var userReplacement = replacement; | ||
replacement = function () { | ||
var context = { | ||
filePath: file.path | ||
}; | ||
userReplacement.apply(context, arguments); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is definitely a clever way to achieve this, but I wonder if users will ever use |
||
} | ||
|
||
if(options.skipBinary) { | ||
istextorbinary.isText(file.path, file.contents, function(err, result) { | ||
if (err) { | ||
return callback(err, file); | ||
} | ||
|
||
if (!result) { | ||
callback(null, file); | ||
} else { | ||
doReplace(); | ||
} | ||
}); | ||
|
||
return; | ||
} | ||
|
||
} | ||
|
||
doReplace(); | ||
} | ||
}); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not change spaces to tabs in your PR, it makes it hard to review. Can you change it back and push a new commit? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "gulp-replace", | ||
"version": "0.5.4", | ||
"version": "0.5.5", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a new feature, so we should bump to |
||
"description": "A string replace plugin for gulp", | ||
"dependencies": { | ||
"istextorbinary": "1.0.2", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return 'bar in' + this.filePath;
It is customary to replace
foo
withbar
:) In this case, we can just tack the path onto the end.