StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
6.6 KiB
288 lines
6.6 KiB
'use strict';
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var fs = require('fs');
|
|
var util = require('engine-utils');
|
|
var Emitter = require('component-emitter');
|
|
var utils = require('./utils');
|
|
var engine = util.fromStringRenderer('base');
|
|
Emitter(engine);
|
|
|
|
/**
|
|
* Expose the Engine constructor
|
|
*/
|
|
|
|
engine.Engine = utils.Engine;
|
|
|
|
/**
|
|
* expose engine `defaults`
|
|
*/
|
|
|
|
engine.options = {
|
|
name: 'base',
|
|
dest: {ext: '.html'}
|
|
};
|
|
|
|
/**
|
|
* Return a compiled function from the given template
|
|
* `string` and `options`.
|
|
*
|
|
* ```js
|
|
* var engine = require('engine-base');
|
|
* var fn = engine.compileSync('<%= name %>');
|
|
* console.log(fn({name: 'Halle'})); //=> 'Halle'
|
|
* ```
|
|
* @param {String} `str` Template string to compile.
|
|
* @param {Object} `options` Options or settings to pass to base
|
|
* @return {Function}
|
|
* @api public
|
|
*/
|
|
|
|
function compileSync(str, locals) {
|
|
try {
|
|
locals = locals || {};
|
|
locals.settings = locals.settings || {};
|
|
var settings = {};
|
|
var picked = utils.merge(pick(locals), pick(locals.settings));
|
|
var delims = picked.delims;
|
|
var opts = picked.opts;
|
|
var fns = picked.fns;
|
|
|
|
settings.imports = utils.merge({}, fns.helpers, fns.imports);
|
|
settings = utils.merge({}, settings, delims);
|
|
|
|
if (locals.debugEngine === true) {
|
|
inspectHelpers(settings, opts);
|
|
}
|
|
|
|
delete settings.imports.with;
|
|
delete settings.imports.if;
|
|
|
|
var base = new utils.Engine(settings);
|
|
return base.compile(str, settings);
|
|
} catch (err) {
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return a compiled function from the given template
|
|
* `string` and `options` can `callback`
|
|
*
|
|
* ```js
|
|
* var engine = require('engine-base');
|
|
* engine.compile('<%= name %>', function (err, fn) {
|
|
* console.log(fn({name: 'Halle'})); //=> 'Halle'
|
|
* });
|
|
* ```
|
|
* @param {String} `str` Template string to compile.
|
|
* @param {Object} `options` Options or settings to pass to engine.
|
|
* @param {Function} `cb` Callback function
|
|
* @api public
|
|
*/
|
|
|
|
function compile(str, options, cb) {
|
|
if (typeof options === 'function') {
|
|
return compile(str, {}, options);
|
|
}
|
|
if (typeof cb !== 'function') {
|
|
return compileSync(str, options);
|
|
}
|
|
try {
|
|
cb(null, compileSync(str, options));
|
|
} catch (err) {
|
|
cb(err);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render templates synchronously.
|
|
*
|
|
* ```js
|
|
* var engine = require('engine-base');
|
|
* engine.renderSync('<%= name %>', {name: 'Halle'});
|
|
* //=> 'Halle'
|
|
* ```
|
|
*
|
|
* @param {Object} `str` The string to render.
|
|
* @param {Object} `options` Object of options.
|
|
* @option {Object} `settings` Settings to pass to Lo-Dash.
|
|
* @option {Arrary} `delims` Template delimiters, generated by [delimiter-regex]
|
|
* @option {Object} `imports` Template helpers to pass to Lo-Dash.
|
|
* @return {String} Rendered string.
|
|
* @api public
|
|
*/
|
|
|
|
function renderSync(str, locals) {
|
|
locals = locals || {};
|
|
locals.settings = locals.settings || {};
|
|
|
|
var settings = {};
|
|
var picked = utils.merge(pick(locals), pick(locals.settings));
|
|
var delims = picked.delims;
|
|
var opts = picked.opts;
|
|
var fns = picked.fns;
|
|
|
|
settings.imports = utils.merge({}, fns.helpers, fns.imports);
|
|
settings = utils.merge({}, settings, delims);
|
|
|
|
if (locals.debugEngine === true) {
|
|
inspectHelpers(settings, opts);
|
|
}
|
|
|
|
if (typeof str === 'function') {
|
|
var ctx = utils.omit(locals, ['helpers', 'imports']);
|
|
return str(ctx);
|
|
}
|
|
|
|
try {
|
|
var base = new utils.Engine(settings);
|
|
return base.render(str, locals);
|
|
} catch (err) {
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* String support. Render the given `str`
|
|
* and invoke the callback `callback(err, str)`.
|
|
*
|
|
* ```js
|
|
* var engine = require('engine-base');
|
|
* engine.render('<%= name %>', {name: 'Jon'}, function (err, content) {
|
|
* console.log(content); //=> 'Jon'
|
|
* });
|
|
* ```
|
|
*
|
|
* @param {String} `str`
|
|
* @param {Object|Function} `locals` or callback.
|
|
* @property {Object} `cache` enable template caching
|
|
* @property {String} `filename` filename required for caching
|
|
* @param {Function} `callback`
|
|
* @api public
|
|
*/
|
|
|
|
function render(str, locals, cb) {
|
|
if (typeof locals === 'function') {
|
|
return render(str, {}, locals);
|
|
}
|
|
if (typeof cb !== 'function') {
|
|
return renderSync(str, locals);
|
|
}
|
|
try {
|
|
cb(null, renderSync(str, locals));
|
|
} catch (err) {
|
|
return cb(err);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* File support. Render a file at the given `filepath`
|
|
* and callback `callback(err, str)`.
|
|
*
|
|
* ```js
|
|
* var engine = require('engine-base');
|
|
* engine.renderFile('foo/bar/baz.tmpl', {name: 'Halle'});
|
|
* //=> 'Halle'
|
|
* ```
|
|
*
|
|
* @param {String} `path`
|
|
* @param {Object|Function} `options` or callback function.
|
|
* @param {Function} `callback`
|
|
* @api public
|
|
*/
|
|
|
|
function renderFile(fp, opts, cb) {
|
|
if (typeof opts === 'function') {
|
|
return renderFile(fp, {}, opts);
|
|
}
|
|
var str = fs.readFileSync(fp, 'utf8');
|
|
render(str, opts, cb);
|
|
}
|
|
|
|
/**
|
|
* Handle custom delimiters
|
|
*/
|
|
|
|
function delimsObject(delims) {
|
|
var a = delims[0], b = delims[1];
|
|
var res = {};
|
|
res.interpolate = utils.delims(a + '=', b);
|
|
res.evaluate = utils.delims(a, b);
|
|
res.escape = utils.delims(a + '-', b);
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Inspect helpers if `debugEngine` is enabled
|
|
*/
|
|
|
|
function inspectHelpers(settings, opts) {
|
|
var helpers = Object.keys(settings.imports);
|
|
for (var key in opts) {
|
|
if (helpers.indexOf(key) !== -1) {
|
|
var msg = conflictMessage(settings, opts, key);
|
|
var err = new Error(msg);
|
|
err.id = 'helper-conflict';
|
|
err.engine = 'engine-base';
|
|
engine.emit('error', err);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Conflict report displayed when the same key exists as both
|
|
* a helper name and the key of a (data) property on the context.
|
|
*/
|
|
|
|
function conflictMessage(settings, options, key) {
|
|
var type1 = typeof settings.imports[key];
|
|
var type2 = typeof options[key];
|
|
|
|
return 'Property "' + key + '" is defined on '
|
|
+ 'more than one object: \n'
|
|
+ ' - `settings.imports` as ' + article(type1) + ' ' + type1
|
|
+ '\n'
|
|
+ ' - `options` as ' + article(type2) + ' ' + type2;
|
|
}
|
|
|
|
function article(word) {
|
|
var n = /^[aeiou]/.test(word);
|
|
return n ? 'an' : 'a';
|
|
}
|
|
|
|
function pick(obj) {
|
|
var res = {};
|
|
res.delims = utils.pick(obj, ['interpolate', 'evaluate', 'escape']);
|
|
res.opts = utils.omit(obj, ['helpers', 'imports']);
|
|
res.fns = utils.pick(obj, ['helpers', 'imports']);
|
|
if (Array.isArray(obj.delims)) {
|
|
res.delims = utils.merge({}, delimsObject(obj.delims), res.delims);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Express support.
|
|
*/
|
|
|
|
engine.__express = engine.renderFile;
|
|
|
|
/**
|
|
* Expose `engine`
|
|
*/
|
|
|
|
module.exports = engine;
|
|
|
|
/**
|
|
* Expose `engine` methods
|
|
*/
|
|
|
|
module.exports.render = render;
|
|
module.exports.renderFile = renderFile;
|
|
module.exports.renderSync = renderSync;
|
|
module.exports.compile = compile;
|
|
module.exports.compileSync = compileSync;
|
|
|