description and source-codegulp-file-include = function (opts) {
if (typeof opts === 'string') {
opts = {prefix: opts};
}
opts = extend({}, {
basepath: '@file',
prefix: '@@',
suffix: '',
context: {},
filters: false,
indent: false
}, opts);
if (opts.basepath !== '@file') {
opts.basepath = opts.basepath === '@root' ? process.cwd() : path.resolve(opts.basepath);
}
var customWebRoot = !!opts.context.webRoot;
function fileInclude(file, enc, cb) {
if (!customWebRoot) {
// built-in webRoot variable, example usage: <link rel=stylesheet href=@@webRoot/style.css>
opts.context.webRoot =
path.relative(path.dirname(file.path), file.base).replace(/\\/g, '/') || '.';
}
if (file.isNull()) {
cb(null, file);
} else if (file.isStream()) {
file.contents.pipe(concat(function(data) {
try {
data = include(file, String(data));
cb(null, data);
} catch (e) {
cb(new gutil.PluginError('gulp-file-include', e.message));
}
}));
} else if (file.isBuffer()) {
try {
file = include(file, String(file.contents));
cb(null, file);
} catch (e) {
cb(new gutil.PluginError('gulp-file-include', e.message));
}
}
}
return through.obj(fileInclude);
function stripCommentedIncludes(content, opts) {
// remove single line html comments that use the format: <!-- @@include() -->
var regex = new RegExp('<\!--(.*)' + opts.prefix + '[ ]*include([\\s\\S]*?)[ ]*' + opts.suffix + '-->', 'g');
return content.replace(regex, '');
}
function include(file, text, data) {
var filebase = opts.basepath === '@file' ? path.dirname(file.path) : opts.basepath;
var currentFilename = path.resolve(file.base, file.path);
data = extend(true, {}, opts.context, data || {});
data.content = text;
text = stripCommentedIncludes(text, opts);
text = replaceOperator(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'if',
handler: conditionalHandler
});
text = replaceOperator(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'for',
handler: forHandler
});
text = replaceVariable(text, data, opts);
text = replaceFunction(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'include',
handler: includeHandler
});
text = replaceFunction(text, {
prefix: opts.prefix,
suffix: opts.suffix,
name: 'loop',
handler: loopHandler
});
function conditionalHandler(inst) {
// jshint ignore: start
var condition = new Function('var context = this; with (context) { return ' + inst.args + '; }').call(data);
// jshint ignore: end
return condition ? inst.body : '';
}
function forHandler(inst) {
var condition = 'var context = this; with (context) { var result=""; for' + inst.args + ' { result+=`' + inst.body + '`; }
return result; }';
// jshint ignore: start
var result = new Function(condition).call(data);
// jshint ignore: end
return result;
}
function includeHandler(inst) {
var args = /[^)"\']*["\']([^"\']*)["\'](,\s*({[\s\S]*})){0,1}\s*/.exec(inst.args);
if (args) {
var includePath = path.resolve(filebase, args[1]);
// for checking if we are not including the current file again
if (currentFilename.toLowerCase() === includePath.toLowerCase()) {
throw new Error('recursion detected in file: ' + currentFilename);
}
var includeContent = fs.readFileSync(includePath, 'utf-8');
if (opts.indent) {
includeContent = setIndent(inst.before, inst.before.length, includeContent);
}
// need to double each `$` to escape it in the `replace` function
// includeContent = includeContent.replace(/\$/gi, '$$$$');
// apply filters on include content
if (typeof opts.filters === 'object') {
includeContent = applyFilters(includeContent, args.input);
}
v ...