mirror of
https://github.com/avwo/whistle.git
synced 2026-10-23 01:49:10 +08:00
66 lines
1.8 KiB
JavaScript
66 lines
1.8 KiB
JavaScript
var Transform = require('pipestream').Transform;
|
|
var util = require('util');
|
|
|
|
var LENGTH = 5120;
|
|
var slice = [].slice;
|
|
var SUB_MATCH_RE = /(^|..?)?(\$[&\d])/g;
|
|
|
|
function ReplacePatternTransform(pattern, value) {
|
|
Transform.call(this);
|
|
this._pattern = pattern;
|
|
this._value = value == null ? '' : value + '';
|
|
this._rest = '';
|
|
}
|
|
|
|
util.inherits(ReplacePatternTransform, Transform);
|
|
|
|
var proto = ReplacePatternTransform.prototype;
|
|
proto._transform = function(chunk, encoding, callback) {
|
|
if (chunk != null) {
|
|
chunk = this._rest + chunk;
|
|
var index = 0;
|
|
var value = this._value;
|
|
var result = chunk.replace(this._pattern, function() {
|
|
var matcher = replacePattern(value, arguments);
|
|
var lastIndex = arguments.length - 1;
|
|
index = arguments[lastIndex - 1] + arguments[lastIndex].length;
|
|
return matcher;
|
|
});
|
|
index = Math.max(index, chunk.length + 1 - LENGTH);
|
|
this._rest = chunk.substring(index);
|
|
chunk = result.substring(0, result.length - this._rest.length);
|
|
} else if (this._rest) {
|
|
chunk = this._rest.replace(this._pattern, function() {
|
|
return replacePattern(this._value, arguments);
|
|
});
|
|
}
|
|
|
|
callback(null, chunk);
|
|
};
|
|
|
|
function getSubMatchers(args) {
|
|
args = slice.call(args);
|
|
return args.slice(0, -2);
|
|
}
|
|
function replacePattern(replacement, args) {
|
|
var arr = args.length ? getSubMatchers(args) : args;
|
|
return replacement ? replacement.replace(SUB_MATCH_RE, function(_, $1, $2) {
|
|
if ($1 === '\\\\') {
|
|
$1 = '\\';
|
|
} else {
|
|
$1 = $1 || '';
|
|
var lastChar = $1[1] || $1[0];
|
|
if (lastChar === '\\') {
|
|
return $1.slice(0, -1) + $2;
|
|
}
|
|
}
|
|
$2 = $2.substring(1);
|
|
if ($2 === '&') {
|
|
$2 = 0;
|
|
}
|
|
return $1 + (arr[$2] || '');
|
|
}) : '';
|
|
}
|
|
ReplacePatternTransform.replacePattern = replacePattern;
|
|
module.exports = ReplacePatternTransform;
|