249 lines
6.8 KiB
JavaScript
249 lines
6.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
let _ = require('lodash');
|
||
|
let del = require('del');
|
||
|
let gear = require('gear');
|
||
|
let path = require('path');
|
||
|
let utility = require('./utility');
|
||
|
|
||
|
let parseHeader = utility.parseHeader;
|
||
|
let tasks = require('gear-lib');
|
||
|
|
||
|
tasks.clean = function(directories, blobs, done) {
|
||
|
directories = _.isString(directories) ? [directories] : directories;
|
||
|
|
||
|
return del(directories).then(() => done(null, blobs));
|
||
|
};
|
||
|
tasks.clean.type = 'collect';
|
||
|
|
||
|
// Depending on the languages required for the current language being
|
||
|
// processed, this task reorders it's dependencies first then include the
|
||
|
// language.
|
||
|
tasks.reorderDeps = function(options, blobs, done) {
|
||
|
let buffer = {},
|
||
|
newBlobOrder = [];
|
||
|
|
||
|
_.each(blobs, function(blob) {
|
||
|
let basename = path.basename(blob.name),
|
||
|
fileInfo = parseHeader(blob.result),
|
||
|
extra = { blob: blob, processed: false };
|
||
|
|
||
|
buffer[basename] = _.merge(extra, fileInfo || {});
|
||
|
});
|
||
|
|
||
|
function pushInBlob(object) {
|
||
|
if(!object.processed) {
|
||
|
object.processed = true;
|
||
|
newBlobOrder.push(object.blob);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_.each(buffer, function(buf) {
|
||
|
let object;
|
||
|
|
||
|
if(buf.Requires) {
|
||
|
_.each(buf.Requires, function(language) {
|
||
|
object = buffer[language];
|
||
|
pushInBlob(object);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
pushInBlob(buf);
|
||
|
});
|
||
|
|
||
|
done(null, newBlobOrder);
|
||
|
};
|
||
|
tasks.reorderDeps.type = 'collect';
|
||
|
|
||
|
tasks.template = function(template, blob, done) {
|
||
|
template = template || '';
|
||
|
|
||
|
let filename = path.basename(blob.name),
|
||
|
basename = path.basename(filename, '.js'),
|
||
|
content = _.template(template)({
|
||
|
name: basename,
|
||
|
filename: filename,
|
||
|
content: blob.result.trim()
|
||
|
});
|
||
|
|
||
|
return done(null, new gear.Blob(content, blob));
|
||
|
};
|
||
|
|
||
|
tasks.templateAll = function(options, blobs, done) {
|
||
|
return options.callback(blobs)
|
||
|
.then(function(data) {
|
||
|
let template = options.template || data.template,
|
||
|
content = _.template(template)(data);
|
||
|
|
||
|
return done(null, [new gear.Blob(content)]);
|
||
|
})
|
||
|
.catch(done);
|
||
|
};
|
||
|
tasks.templateAll.type = 'collect';
|
||
|
|
||
|
tasks.rename = function(options, blob, done) {
|
||
|
options = options || {};
|
||
|
|
||
|
let name = blob.name,
|
||
|
ext = new RegExp(path.extname(name) + '$');
|
||
|
|
||
|
name = name.replace(ext, options.extname);
|
||
|
|
||
|
return done(null, new gear.Blob(blob.result, { name: name }));
|
||
|
};
|
||
|
|
||
|
// Adds the contributors from `AUTHORS.en.txt` onto the `package.json` file
|
||
|
// and moves the result into the `build` directory.
|
||
|
tasks.buildPackage = function(json, blob, done) {
|
||
|
let result,
|
||
|
lines = blob.result.split(/\r?\n/),
|
||
|
regex = /^- (.*) <(.*)>$/;
|
||
|
|
||
|
json.contributors = _.transform(lines, function(result, line) {
|
||
|
let matches = line.match(regex);
|
||
|
|
||
|
if(matches) {
|
||
|
result.push({
|
||
|
name: matches[1],
|
||
|
email: matches[2]
|
||
|
});
|
||
|
}
|
||
|
}, []);
|
||
|
|
||
|
result = JSON.stringify(json, null, ' ');
|
||
|
|
||
|
return done(null, new gear.Blob(result, blob));
|
||
|
};
|
||
|
|
||
|
// Mainly for replacing the keys of `utility.REPLACES` for it's values while
|
||
|
// skipping over strings, regular expressions, or comments. However, this is
|
||
|
// pretty generic so long as you use the `utility.replace` function, you can
|
||
|
// replace a regular expression with a string.
|
||
|
tasks.replaceSkippingStrings = function(params, blob, done) {
|
||
|
let content = blob.result,
|
||
|
length = content.length,
|
||
|
offset = 0,
|
||
|
|
||
|
replace = params.replace || '',
|
||
|
regex = params.regex,
|
||
|
starts = /\/\/|['"\/]/,
|
||
|
|
||
|
result = [],
|
||
|
chunk, end, match, start, terminator;
|
||
|
|
||
|
while(offset < length) {
|
||
|
chunk = content.slice(offset);
|
||
|
match = chunk.match(starts);
|
||
|
end = match ? match.index : length;
|
||
|
|
||
|
chunk = content.slice(offset, end + offset);
|
||
|
result.push(chunk.replace(regex, replace));
|
||
|
|
||
|
offset += end;
|
||
|
|
||
|
if(match) {
|
||
|
// We found a starter sequence: either a `//` or a "quote"
|
||
|
// In the case of `//` our terminator is the end of line.
|
||
|
// Otherwise it's either a matching quote or an escape symbol.
|
||
|
terminator = match[0] !== '//' ? new RegExp(`[${match[0]}\\\\]`)
|
||
|
: /$/m;
|
||
|
start = offset;
|
||
|
offset += 1;
|
||
|
|
||
|
while(true) {
|
||
|
chunk = content.slice(offset);
|
||
|
match = chunk.match(terminator);
|
||
|
|
||
|
if(!match) {
|
||
|
return done('Unmatched quote');
|
||
|
}
|
||
|
|
||
|
if(match[0] === '\\') {
|
||
|
offset += match.index + 2;
|
||
|
} else {
|
||
|
offset += match.index + 1;
|
||
|
result.push(content.slice(start, offset));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return done(null, new gear.Blob(result.join(''), blob));
|
||
|
};
|
||
|
|
||
|
tasks.filter = function(callback, blobs, done) {
|
||
|
let filteredBlobs = _.filter(blobs, callback);
|
||
|
|
||
|
// Re-add in blobs required from header definition
|
||
|
_.each(filteredBlobs, function(blob) {
|
||
|
let dirname = path.dirname(blob.name),
|
||
|
content = blob.result,
|
||
|
fileInfo = parseHeader(content);
|
||
|
|
||
|
if(fileInfo && fileInfo.Requires) {
|
||
|
_.each(fileInfo.Requires, function(language) {
|
||
|
let filename = `${dirname}/${language}`,
|
||
|
fileFound = _.find(filteredBlobs, { name: filename });
|
||
|
|
||
|
if(!fileFound) {
|
||
|
filteredBlobs.push(
|
||
|
_.find(blobs, { name: filename }));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return done(null, filteredBlobs);
|
||
|
};
|
||
|
tasks.filter.type = 'collect';
|
||
|
|
||
|
tasks.readSnippet = function(options, blob, done) {
|
||
|
let name = path.basename(blob.name, '.js'),
|
||
|
fileInfo = parseHeader(blob.result),
|
||
|
snippetName = path.join('test', 'detect', name, 'default.txt');
|
||
|
|
||
|
function onRead(error, blob) {
|
||
|
if(error) return done(error); // ignore missing snippets
|
||
|
|
||
|
let meta = { name: `${name}.js`, fileInfo: fileInfo };
|
||
|
|
||
|
return done(null, new gear.Blob(blob.result, meta));
|
||
|
}
|
||
|
|
||
|
gear.Blob.readFile(snippetName, 'utf8', onRead, false);
|
||
|
};
|
||
|
|
||
|
tasks.insertLicenseTag = function(options, blob, done) {
|
||
|
let hljsVersion = require('../package').version,
|
||
|
licenseTag = `/*! highlight.js v${hljsVersion} | ` +
|
||
|
`BSD3 License | git.io/hljslicense */\n`;
|
||
|
|
||
|
return done(null, new gear.Blob(licenseTag + blob.result, blob));
|
||
|
};
|
||
|
|
||
|
// Packages up included languages into the core `highlight.js` and moves the
|
||
|
// result into the `build` directory.
|
||
|
tasks.packageFiles = function(options, blobs, done) {
|
||
|
let content,
|
||
|
coreFile = _.head(blobs),
|
||
|
languages = _.tail(blobs),
|
||
|
|
||
|
lines = coreFile.result
|
||
|
.replace(utility.regex.header, '')
|
||
|
.split('\n\n'),
|
||
|
lastLine = _.last(lines),
|
||
|
langStr = _.reduce(languages, (str, language) =>
|
||
|
`${str + language.result}\n`, '');
|
||
|
|
||
|
lines[lines.length - 1] = langStr.trim();
|
||
|
|
||
|
lines = lines.concat(lastLine);
|
||
|
content = lines.join('\n\n');
|
||
|
|
||
|
return done(null, [new gear.Blob(content)]);
|
||
|
};
|
||
|
tasks.packageFiles.type = 'collect';
|
||
|
|
||
|
module.exports = new gear.Registry({ tasks: tasks });
|