Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ansi-to-html

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ansi-to-html - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

.eslintrc.json

52

gruntFile.js
/*global module:false*/
module.exports = function(grunt) {
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-eslint');
// Project configuration.
grunt.initConfig({
simplemocha: {
all: ['test/ansi_to_html.js'],
options: {reporter: 'tap'}
},
coffee: {
src: {
src: 'src/ansi_to_html.coffee',
dest: 'lib/ansi_to_html.js'
},
cli: {
src: 'src/cli.coffee',
dest: 'lib/cli.js'
},
test: {
src: 'test/ansi_to_html.coffee',
dest: 'test/ansi_to_html.js'
}
},
watch: {
files: ['src/**/*.coffee', 'test/**/*.coffee'],
tasks: 'default'
}
});
// Project configuration.
grunt.initConfig({
eslint: {
options: { configFile: '.eslintrc.json' },
target: ['lib/**/*.js', 'test/**/*.js']
},
simplemocha: {
all: ['test/ansi_to_html.js', ['test/cli.js']],
options: {reporter: 'tap'}
},
watch: {
files: ['src/**/*.js', 'test/**/*.js'],
tasks: 'default'
}
});
// Default task.
grunt.registerTask('default', ['coffee', 'simplemocha']);
// Default task.
grunt.registerTask('default', ['simplemocha']);
};

@@ -1,406 +0,461 @@

(function() {
var Filter, STYLES, defaults, entities, extend, j, results, toHexString,
slice = [].slice;
const entities = require('entities');
const defaults = {
fg: '#FFF',
bg: '#000',
newline: false,
escapeXML: false,
stream: false,
colors: getDefaultColors()
};
entities = require("entities");
function getDefaultColors() {
const colors = {
0: '#000',
1: '#A00',
2: '#0A0',
3: '#A50',
4: '#00A',
5: '#A0A',
6: '#0AA',
7: '#AAA',
8: '#555',
9: '#F55',
10: '#5F5',
11: '#FF5',
12: '#55F',
13: '#F5F',
14: '#5FF',
15: '#FFF'
};
STYLES = {
'ef0': 'color:#000',
'ef1': 'color:#A00',
'ef2': 'color:#0A0',
'ef3': 'color:#A50',
'ef4': 'color:#00A',
'ef5': 'color:#A0A',
'ef6': 'color:#0AA',
'ef7': 'color:#AAA',
'ef8': 'color:#555',
'ef9': 'color:#F55',
'ef10': 'color:#5F5',
'ef11': 'color:#FF5',
'ef12': 'color:#55F',
'ef13': 'color:#F5F',
'ef14': 'color:#5FF',
'ef15': 'color:#FFF',
'eb0': 'background-color:#000',
'eb1': 'background-color:#A00',
'eb2': 'background-color:#0A0',
'eb3': 'background-color:#A50',
'eb4': 'background-color:#00A',
'eb5': 'background-color:#A0A',
'eb6': 'background-color:#0AA',
'eb7': 'background-color:#AAA',
'eb8': 'background-color:#555',
'eb9': 'background-color:#F55',
'eb10': 'background-color:#5F5',
'eb11': 'background-color:#FF5',
'eb12': 'background-color:#55F',
'eb13': 'background-color:#F5F',
'eb14': 'background-color:#5FF',
'eb15': 'background-color:#FFF'
};
range(0, 5).forEach(red => {
range(0, 5).forEach(green => {
range(0, 5).forEach(blue => setStyleColor(red, green, blue, colors));
});
});
toHexString = function(num) {
num = num.toString(16);
while (num.length < 2) {
num = "0" + num;
}
return num;
};
range(0, 23).forEach(function (gray) {
const c = gray + 232;
const l = toHexString(gray * 10 + 8);
[0, 1, 2, 3, 4, 5].forEach(function(red) {
return [0, 1, 2, 3, 4, 5].forEach(function(green) {
return [0, 1, 2, 3, 4, 5].forEach(function(blue) {
var b, c, g, n, r, rgb;
c = 16 + (red * 36) + (green * 6) + blue;
r = red > 0 ? red * 40 + 55 : 0;
g = green > 0 ? green * 40 + 55 : 0;
b = blue > 0 ? blue * 40 + 55 : 0;
rgb = ((function() {
var j, len, ref, results;
ref = [r, g, b];
results = [];
for (j = 0, len = ref.length; j < len; j++) {
n = ref[j];
results.push(toHexString(n));
}
return results;
})()).join('');
STYLES["ef" + c] = "color:#" + rgb;
return STYLES["eb" + c] = "background-color:#" + rgb;
});
colors[c] = '#' + l + l + l;
});
});
(function() {
results = [];
for (j = 0; j <= 23; j++){ results.push(j); }
return results;
}).apply(this).forEach(function(gray) {
var c, l;
c = gray + 232;
l = toHexString(gray * 10 + 8);
STYLES["ef" + c] = "color:#" + l + l + l;
return STYLES["eb" + c] = "background-color:#" + l + l + l;
});
return colors;
}
extend = function() {
var dest, k, len, o, obj, objs, v;
dest = arguments[0], objs = 2 <= arguments.length ? slice.call(arguments, 1) : [];
for (o = 0, len = objs.length; o < len; o++) {
obj = objs[o];
for (k in obj) {
v = obj[k];
dest[k] = v;
}
/**
* @param {number} red
* @param {number} green
* @param {number} blue
* @param {object} colors
*/
function setStyleColor(red, green, blue, colors) {
const c = 16 + (red * 36) + (green * 6) + blue;
const r = red > 0 ? red * 40 + 55 : 0;
const g = green > 0 ? green * 40 + 55 : 0;
const b = blue > 0 ? blue * 40 + 55 : 0;
colors[c] = toColorHexString([r, g, b]);
}
/**
* Converts from a number like 15 to a hex string like 'F'
* @param {number} num
* @returns {string}
*/
function toHexString(num) {
var str = num.toString(16);
while (str.length < 2) {
str = '0' + str;
}
return dest;
};
defaults = {
fg: '#FFF',
bg: '#000',
newline: false,
escapeXML: false,
stream: false
};
return str;
}
Filter = (function() {
function Filter(options) {
if (options == null) {
options = {};
}
this.opts = extend({}, defaults, options);
this.input = [];
this.stack = [];
this.stickyStack = [];
/**
* Converts from an array of numbers like [15, 15, 15] to a hex string like 'FFF'
* @param {[red, green, blue]} ref
* @returns {string}
*/
function toColorHexString(ref) {
var results = [];
for (var j = 0, len = ref.length; j < len; j++) {
results.push(toHexString(ref[j]));
}
Filter.prototype.toHtml = function(input) {
var buf;
this.input = typeof input === 'string' ? [input] : input;
buf = [];
this.stickyStack.forEach((function(_this) {
return function(element) {
return _this.generateOutput(element.token, element.data, function(chunk) {
return buf.push(chunk);
});
};
})(this));
this.forEach(function(chunk) {
return buf.push(chunk);
});
this.input = [];
return buf.join('');
};
return '#' + results.join('');
}
Filter.prototype.forEach = function(callback) {
var buf;
buf = '';
this.input.forEach((function(_this) {
return function(chunk) {
buf += chunk;
return _this.tokenize(buf, function(token, data) {
_this.generateOutput(token, data, callback);
if (_this.opts.stream) {
return _this.updateStickyStack(token, data);
}
});
};
})(this));
if (this.stack.length) {
return callback(this.resetStyles());
}
};
/**
* @param {Array} stack
* @param {string} token
* @param {*} data
* @param {object} options
*/
function generateOutput(stack, token, data, options) {
var result;
Filter.prototype.generateOutput = function(token, data, callback) {
switch (token) {
case 'text':
return callback(this.pushText(data));
case 'display':
return this.handleDisplay(data, callback);
case 'xterm256':
return callback(this.pushStyle("ef" + data));
}
};
if (token === 'text') {
result = pushText(data, options);
} else if (token === 'display') {
result = handleDisplay(stack, data, options);
} else if (token === 'xterm256') {
result = pushForegroundColor(stack, options.colors[data]);
}
Filter.prototype.updateStickyStack = function(token, data) {
var notCategory;
notCategory = function(category) {
return function(e) {
return (category === null || e.category !== category) && category !== 'all';
};
};
if (token !== 'text') {
this.stickyStack = this.stickyStack.filter(notCategory(this.categoryForCode(data)));
return this.stickyStack.push({
token: token,
data: data,
category: this.categoryForCode(data)
});
}
return result;
}
/**
* @param {Array} stack
* @param {number} code
* @param {object} options
* @returns {*}
*/
function handleDisplay(stack, code, options) {
code = parseInt(code, 10);
var result;
const codeMap = {
'-1': () => '<br/>',
0: () => stack.length && resetStyles(stack),
1: () => pushTag(stack, 'b'),
3: () => pushTag(stack, 'i'),
4: () => pushTag(stack, 'u'),
8: () => pushStyle(stack, 'display:none'),
9: () => pushTag(stack, 'strike'),
22: () => closeTag(stack, 'b'),
23: () => closeTag(stack, 'i'),
24: () => closeTag(stack, 'u'),
39: () => pushForegroundColor(stack, options.fg),
49: () => pushBackgroundColor(stack, options.bg)
};
Filter.prototype.handleDisplay = function(code, callback) {
code = parseInt(code, 10);
if (code === -1) {
callback('<br/>');
}
if (code === 0) {
if (this.stack.length) {
callback(this.resetStyles());
}
}
if (code === 1) {
callback(this.pushTag('b'));
}
if (code === 2) {
if (codeMap[code]) {
result = codeMap[code]();
} else if (4 < code && code < 7) {
result = pushTag(stack, 'blink');
} else if (29 < code && code < 38) {
result = pushForegroundColor(stack, options.colors[code - 30]);
} else if ((39 < code && code < 48)) {
result = pushBackgroundColor(stack, options.colors[code - 40]);
} else if ((89 < code && code < 98)) {
result = pushForegroundColor(stack, options.colors[8 + (code - 90)]);
} else if ((99 < code && code < 108)) {
result = pushBackgroundColor(stack, options.colors[8 + (code - 100)]);
}
}
if (code === 3) {
callback(this.pushTag('i'));
}
if (code === 4) {
callback(this.pushTag('u'));
}
if ((4 < code && code < 7)) {
callback(this.pushTag('blink'));
}
if (code === 7) {
return result;
}
}
if (code === 8) {
callback(this.pushStyle('display:none'));
}
if (code === 9) {
callback(this.pushTag('strike'));
}
if (code === 22) {
callback(this.closeTag('b'));
}
if (code === 23) {
callback(this.closeTag('i'));
}
if (code === 24) {
callback(this.closeTag('u'));
}
if ((29 < code && code < 38)) {
callback(this.pushStyle("ef" + (code - 30)));
}
if (code === 39) {
callback(this.pushStyle("color:" + this.opts.fg));
}
if ((39 < code && code < 48)) {
callback(this.pushStyle("eb" + (code - 40)));
}
if (code === 49) {
callback(this.pushStyle("background-color:" + this.opts.bg));
}
if ((89 < code && code < 98)) {
callback(this.pushStyle("ef" + (8 + (code - 90))));
}
if ((99 < code && code < 108)) {
return callback(this.pushStyle("eb" + (8 + (code - 100))));
}
};
/**
* Clear all the styles
* @returns {string}
*/
function resetStyles(stack) {
var stackClone = stack.slice(0);
Filter.prototype.categoryForCode = function(code) {
code = parseInt(code, 10);
if (code === 0) {
return 'all';
} else if (code === 1) {
return 'bold';
} else if ((2 < code && code < 5)) {
return 'underline';
} else if ((4 < code && code < 7)) {
return 'blink';
} else if (code === 8) {
return 'hide';
} else if (code === 9) {
return 'strike';
} else if ((29 < code && code < 38) || code === 39 || (89 < code && code < 98)) {
return 'foreground-color';
} else if ((39 < code && code < 48) || code === 49 || (99 < code && code < 108)) {
return 'background-color';
} else {
return null;
}
};
stack.length = 0;
Filter.prototype.pushTag = function(tag, style) {
if (style == null) {
style = '';
}
if (style.length && style.indexOf(':') === -1) {
style = STYLES[style];
}
this.stack.push(tag);
return ["<" + tag, (style ? " style=\"" + style + "\"" : void 0), ">"].join('');
return stackClone.reverse().map(function (tag) {
return '</' + tag + '>';
}).join('');
}
/**
* Creates an array of numbers ranging from low to high
* @param {number} low
* @param {number} high
* @returns {Array}
* @example range(3, 7); // creates [3, 4, 5, 6, 7]
*/
function range(low, high) {
const results = [];
for (var j = low; j <= high; j++) {
results.push(j);
}
return results;
}
/**
* Returns a new function that is true if value is NOT the same category
* @param {string} category
* @returns {function}
*/
function notCategory(category) {
return function (e) {
return (category === null || e.category !== category) && category !== 'all';
};
}
Filter.prototype.pushText = function(text) {
if (this.opts.escapeXML) {
/**
* Converts a code into an ansi token type
* @param {number} code
* @returns {string}
*/
function categoryForCode(code) {
code = parseInt(code, 10);
var result = null;
if (code === 0) {
result = 'all';
} else if (code === 1) {
result = 'bold';
} else if ((2 < code && code < 5)) {
result = 'underline';
} else if ((4 < code && code < 7)) {
result = 'blink';
} else if (code === 8) {
result = 'hide';
} else if (code === 9) {
result = 'strike';
} else if ((29 < code && code < 38) || code === 39 || (89 < code && code < 98)) {
result = 'foreground-color';
} else if ((39 < code && code < 48) || code === 49 || (99 < code && code < 108)) {
result = 'background-color';
}
return result;
}
/**
* @param {string} text
* @param {object} options
* @returns {string}
*/
function pushText(text, options) {
if (options.escapeXML) {
return entities.encodeXML(text);
} else {
return text;
}
};
}
Filter.prototype.pushStyle = function(style) {
return this.pushTag("span", style);
};
return text;
}
Filter.prototype.closeTag = function(style) {
var last;
if (this.stack.slice(-1)[0] === style) {
last = this.stack.pop();
}
if (last != null) {
return "</" + style + ">";
}
};
/**
* @param {Array} stack
* @param {string} tag
* @param {string} [style='']
* @returns {string}
*/
function pushTag(stack, tag, style) {
if (!style) {
style = '';
}
Filter.prototype.resetStyles = function() {
var ref, stack;
ref = [this.stack, []], stack = ref[0], this.stack = ref[1];
return stack.reverse().map(function(tag) {
return "</" + tag + ">";
}).join('');
};
stack.push(tag);
Filter.prototype.tokenize = function(text, callback) {
var ansiHandler, ansiMatch, ansiMess, handler, i, len, length, newline, o, process, realText, remove, removeXterm256, results1, tokens;
ansiMatch = false;
ansiHandler = 3;
remove = function(m) {
return ['<' + tag, (style ? ' style="' + style + '"' : void 0), '>'].join('');
}
/**
* @param {Array} stack
* @param {string} style
* @returns {string}
*/
function pushStyle (stack, style) {
return pushTag(stack, 'span', style);
}
function pushForegroundColor(stack, color) {
return pushTag(stack, 'span', 'color:' + color);
}
function pushBackgroundColor(stack, color) {
return pushTag(stack, 'span', 'background-color:' + color);
}
/**
* @param {Array} stack
* @param {string} style
* @returns {string}
*/
function closeTag(stack, style) {
var last;
if (stack.slice(-1)[0] === style) {
last = stack.pop();
}
if (last) {
return '</' + style + '>';
}
}
/**
* @param {string} text
* @param {object} options
* @param {function} callback
* @returns {Array}
*/
function tokenize(text, options, callback) {
var ansiMatch = false;
var ansiHandler = 3;
function remove() {
return '';
};
removeXterm256 = function(m, g1) {
}
function removeXterm256(m, g1) {
callback('xterm256', g1);
return '';
};
newline = (function(_this) {
return function(m) {
if (_this.opts.newline) {
}
function newline(m) {
if (options.newline) {
callback('display', -1);
} else {
} else {
callback('text', m);
}
return '';
};
})(this);
ansiMess = function(m, g1) {
var code, len, o;
}
return '';
}
function ansiMess(m, g1) {
ansiMatch = true;
if (g1.trim().length === 0) {
g1 = '0';
g1 = '0';
}
g1 = g1.trimRight(';').split(';');
for (o = 0, len = g1.length; o < len; o++) {
code = g1[o];
callback('display', code);
for (var o = 0, len = g1.length; o < len; o++) {
callback('display', g1[o]);
}
return '';
};
realText = function(m) {
}
function realText(m) {
callback('text', m);
return '';
};
tokens = [
{
pattern: /^\x08+/,
sub: remove
}, {
pattern: /^\x1b\[[012]?K/,
sub: remove
}, {
pattern: /^\x1b\[38;5;(\d+)m/,
sub: removeXterm256
}, {
pattern: /^\n/,
sub: newline
}, {
pattern: /^\x1b\[((?:\d{1,3};?)+|)m/,
sub: ansiMess
}, {
pattern: /^\x1b\[?[\d;]{0,3}/,
sub: remove
}, {
pattern: /^([^\x1b\x08\n]+)/,
sub: realText
}
];
process = function(handler, i) {
var matches;
}
/* eslint no-control-regex:0 */
const tokens = [{
pattern: /^\x08+/,
sub: remove
}, {
pattern: /^\x1b\[[012]?K/,
sub: remove
}, {
pattern: /^\x1b\[38;5;(\d+)m/,
sub: removeXterm256
}, {
pattern: /^\n/,
sub: newline
}, {
pattern: /^\x1b\[((?:\d{1,3};?)+|)m/,
sub: ansiMess
}, {
pattern: /^\x1b\[?[\d;]{0,3}/,
sub: remove
}, {
pattern: /^([^\x1b\x08\n]+)/,
sub: realText
}];
function process(handler, i) {
if (i > ansiHandler && ansiMatch) {
return;
} else {
ansiMatch = false;
return;
}
matches = text.match(handler.pattern);
ansiMatch = false;
text = text.replace(handler.pattern, handler.sub);
if (matches == null) {
}
var handler;
var results1 = [];
var length = text.length;
while (length > 0) {
for (var i = 0, o = 0, len = tokens.length; o < len; i = ++o) {
handler = tokens[i];
process(handler, i);
}
};
results1 = [];
while ((length = text.length) > 0) {
for (i = o = 0, len = tokens.length; o < len; i = ++o) {
handler = tokens[i];
process(handler, i);
}
if (text.length === length) {
break;
break;
} else {
results1.push(void 0);
results1.push(0);
}
}
return results1;
};
return Filter;
length = text.length;
}
})();
return results1;
}
module.exports = Filter;
/**
* If streaming, then the stack is "sticky"
*
* @param {Array} stickyStack
* @param {string} token
* @param {*} data
* @returns {Array}
*/
function updateStickyStack(stickyStack, token, data) {
if (token !== 'text') {
stickyStack = stickyStack.filter(notCategory(categoryForCode(data)));
stickyStack.push({token: token, data: data, category: categoryForCode(data)});
}
}).call(this);
return stickyStack;
}
function Filter(options) {
options = options || {};
if (options.colors) {
options.colors = Object.assign({}, defaults.colors, options.colors);
}
this.opts = Object.assign({}, defaults, options);
this.stack = [];
this.stickyStack = [];
}
Filter.prototype = {
toHtml (input) {
input = typeof input === 'string' ? [input] : input;
const stack = this.stack;
const options = this.opts;
const buf = [];
this.stickyStack.forEach(element => {
var output = generateOutput(stack, element.token, element.data, options);
if (output) {
buf.push(output);
}
});
tokenize(input.join(''), options, (token, data) => {
var output = generateOutput(stack, token, data, options);
if (output) {
buf.push(output);
}
if (options.stream) {
this.stickyStack = updateStickyStack(this.stickyStack, token, data);
}
});
if (stack.length) {
buf.push(resetStyles(stack));
}
return buf.join('');
}
};
module.exports = Filter;

@@ -1,71 +0,63 @@

(function() {
var args, convert, file, help, htmlStream, i, j, ref, skip, stream;
/* eslint no-console:0 */
const help = '\nuasge: ansi-to-html [options] [file]\n \nfile: The file to display or stdin\n \noptions: \n \n -f, --fg The background color used for resets (#000)\n -b, --bg The foreground color used for resets (#FFF)\n -n, --newline Convert newline characters to <br/> (false)\n -x, --escapeXML Generate XML entities (false)\n -v, --version Print version\n -h, --help Print help\n ';
var file = null,
skip = false,
args = {
stream: true
};
help = "\nuasge: ansi-to-html [options] [file]\n \nfile: The file to display or stdin\n \noptions: \n \n -f, --fg The background color used for resets (#000)\n -b, --bg The foreground color used for resets (#FFF)\n -n, --newline Convert newline characters to <br/> (false)\n -x, --escapeXML Generate XML entities (false)\n -v, --version Print version\n -h, --help Print help\n ";
file = null;
skip = false;
args = {
stream: true
};
for (i = j = 2, ref = process.argv.length; 2 <= ref ? j < ref : j > ref; i = 2 <= ref ? ++j : --j) {
for (var i = 2, j = 2, ref = process.argv.length; 2 <= ref ? j < ref : j > ref; i = 2 <= ref ? ++j : --j) {
if (skip) {
skip = false;
continue;
skip = false;
continue;
}
switch (process.argv[i]) {
case '-n':
case '--newline':
args.newline = true;
break;
case '-x':
case '--escapeXML':
args.escapeXML = true;
break;
case '-f':
case '--fg':
args.fg = process.argv[i + 1];
skip = true;
break;
case '-b':
case '--bg':
args.bg = process.argv[i + 1];
skip = true;
break;
case '-v':
case '--version':
console.log(require(__dirname + "/../package.json").version);
process.exit(0);
break;
case '-h':
case '--help':
console.log(help);
process.exit(0);
break;
default:
file = process.argv[i];
case '-n':
case '--newline':
args.newline = true;
break;
case '-x':
case '--escapeXML':
args.escapeXML = true;
break;
case '-f':
case '--fg':
args.fg = process.argv[i + 1];
skip = true;
break;
case '-b':
case '--bg':
args.bg = process.argv[i + 1];
skip = true;
break;
case '-v':
case '--version':
console.log(require(__dirname + '/../package.json').version);
process.exit(0);
break;
case '-h':
case '--help':
console.log(help);
process.exit(0);
break;
default:
file = process.argv[i];
}
}
}
convert = new (require('../'))(args);
var convert = new (require('./ansi_to_html.js'))(args);
htmlStream = function(stream) {
return stream.on('data', function(chunk) {
return process.stdout.write(convert.toHtml(chunk));
var htmlStream = function (stream) {
return stream.on('data', function (chunk) {
return process.stdout.write(convert.toHtml(chunk));
});
};
};
if (file) {
stream = require('fs').createReadStream(file, {
encoding: 'utf8'
});
if (file) {
var stream = require('fs').createReadStream(file, {encoding: 'utf8'});
htmlStream(stream);
} else {
} else {
process.stdin.setEncoding('utf8');
htmlStream(process.stdin);
}
}).call(this);
}
{
"name": "ansi-to-html",
"version": "0.5.0",
"version": "0.6.0",
"description": "Convert ansi escaped text streams to html.",
"main": "lib/ansi_to_html.js",
"engines": { "node": "*" },
"engines": {
"node": "*"
},
"scripts": {
"test": "grunt simplemocha"
"lint": "./node_modules/eslint/bin/eslint.js lib test",
"test": "./node_modules/mocha/bin/mocha --reporter tap"
},

@@ -26,19 +29,25 @@ "repository": {

},
"contributors": [{
"name": "Michael",
"email": "michael@riesd.com"
}, {
"name": "Thorsten Kohnhorst",
"email": "monsterkodi@gmx.net"
}, {
"name": "Yoram Grahame",
"email": "yoz@yoz.com"
}],
"license": "MIT",
"contributors": [
{
"name": "Dane Stuckel",
"email": "dane.stuckel@gmail.com"
},
{
"name": "Michael",
"email": "michael@riesd.com"
},
{
"name": "Thorsten Kohnhorst",
"email": "monsterkodi@gmx.net"
},
{
"name": "Yoram Grahame",
"email": "yoz@yoz.com"
}
],
"license": "MIT",
"devDependencies": {
"chai": "~3.5.0",
"grunt": "~0.4.5",
"grunt-contrib-coffee": "^0.13.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-simple-mocha": "~0.4.1"
"eslint": "^3.13.1",
"mocha": "^3.2.0"
},

@@ -45,0 +54,0 @@ "dependencies": {

@@ -60,10 +60,14 @@ ## Ansi to Html

**colors** <code>Object/Array with values 0 - 255 containing CSS color values</code> Can override specific colors or the entire ANSI palette
### Default options
```coffee
fg: '#FFF'
bg: '#000'
newline: false
escapeXML: false
stream: false
```javascript
{
fg: '#FFF',
bg: '#000',
newline: false,
escapeXML: false,
stream: false
}
```

@@ -81,17 +85,8 @@

If you don't have it already, install the grunt command-line tool:
Lint
npm install -g grunt-cli
npm run lint
Build and test
Test
grunt
All the time
grunt watch
Or separately
grunt coffee
grunt simplemocha # or npm test
npm test

@@ -1,274 +0,352 @@

(function() {
var Filter, expect, test;
/* globals describe, it*/
Filter = require('../lib/ansi_to_html.js');
const Filter = require('../lib/ansi_to_html.js');
const expect = require('chai').expect;
expect = require('chai').expect;
function test(text, result, done, opts) {
if (!opts) {
opts = {};
}
test = function(text, result, done, opts) {
var f, filtered;
if (opts == null) {
opts = {};
var f = new Filter(opts);
function filtered(memo, t) {
return memo + f.toHtml(t);
}
f = new Filter(opts);
filtered = function(memo, t) {
return memo += f.toHtml(t);
};
text = typeof text.reduce === 'function' ? text : [text];
expect(text.reduce(filtered, '')).to.equal(result);
return done();
};
}
describe('ansi to html', function() {
describe('constructed with no options', function() {
it("doesn't modify the input string", function(done) {
var result, text;
text = result = 'some text';
return test(text, result, done);
});
it('returns plain text when given plain text', function(done) {
var result, text;
text = 'test\ntest\n';
result = 'test\ntest\n';
return test(text, result, done);
});
it('renders foreground colors', function(done) {
var result, text;
text = "colors: \x1b[30mblack\x1b[37mwhite";
result = 'colors: <span style="color:#000">black<span style="color:' + '#AAA">white</span></span>';
return test(text, result, done);
});
it('renders light foreground colors', function(done) {
var result, text;
text = 'colors: \x1b[90mblack\x1b[97mwhite';
result = 'colors: <span style="color:#555">black<span style="color:' + '#FFF">white</span></span>';
return test(text, result, done);
});
it('renders background colors', function(done) {
var result, text;
text = 'colors: \x1b[40mblack\x1b[47mwhite';
result = 'colors: <span style="background-color:#000">black<span ' + 'style="background-color:#AAA">white</span></span>';
return test(text, result, done);
});
it('renders light background colors', function(done) {
var result, text;
text = 'colors: \x1b[100mblack\x1b[107mwhite';
result = 'colors: <span style="background-color:#555">black<span ' + 'style="background-color:#FFF">white</span></span>';
return test(text, result, done);
});
it('renders strikethrough', function(done) {
var result, text;
text = 'strike: \x1b[9mthat';
result = 'strike: <strike>that</strike>';
return test(text, result, done);
});
it('renders blink', function(done) {
var result, text;
text = 'blink: \x1b[5mwhat';
result = 'blink: <blink>what</blink>';
return test(text, result, done);
});
it('renders underline', function(done) {
var result, text;
text = 'underline: \x1b[4mstuff';
result = 'underline: <u>stuff</u>';
return test(text, result, done);
});
it('renders bold', function(done) {
var result, text;
text = 'bold: \x1b[1mstuff';
result = 'bold: <b>stuff</b>';
return test(text, result, done);
});
it('renders italic', function(done) {
var result, text;
text = 'italic: \x1b[3mstuff';
result = 'italic: <i>stuff</i>';
return test(text, result, done);
});
it('handles ressets', function(done) {
var result, text;
text = '\x1b[1mthis is bold\x1b[0m, but this isn\'t';
result = '<b>this is bold</b>, but this isn\'t';
return test(text, result, done);
});
it('handles multiple resets', function(done) {
var result, text;
text = 'normal, \x1b[1mbold, \x1b[4munderline, \x1b[31mred\x1b[0m, normal';
result = 'normal, <b>bold, <u>underline, <span style="color:' + '#A00">red</span></u></b>, normal';
return test(text, result, done);
});
it('handles resets with implicit 0', function(done) {
var result, text;
text = '\x1b[1mthis is bold\x1b[m, but this isn\'t';
result = '<b>this is bold</b>, but this isn\'t';
return test(text, result, done);
});
it('renders multi-attribute sequences', function(done) {
var result, text;
text = 'normal, \x1b[1;4;31mbold, underline, and red\x1b[0m, normal';
result = 'normal, <b><u><span style="color:#A00">bold, underline,' + ' and red</span></u></b>, normal';
return test(text, result, done);
});
it('renders multi-attribute sequences with a semi-colon', function(done) {
var result, text;
text = 'normal, \x1b[1;4;31;mbold, underline, and red\x1b[0m, normal';
result = 'normal, <b><u><span style="color:#A00">bold, underline, ' + 'and red</span></u></b>, normal';
return test(text, result, done);
});
it('eats malformed sequences', function(done) {
var result, text;
text = '\x1b[25oops forgot the \'m\'';
result = 'oops forgot the \'m\'';
return test(text, result, done);
});
it('renders xterm 256 sequences', function(done) {
var result, text;
text = '\x1b[38;5;196mhello';
result = '<span style="color:#ff0000">hello</span>';
return test(text, result, done);
});
it('handles resetting to default foreground color', function(done) {
var result, text;
text = '\x1b[30mblack\x1b[39mdefault';
result = '<span style="color:#000">black<span style="color:#FFF">' + 'default</span></span>';
return test(text, result, done);
});
it('handles resetting to default background color', function(done) {
var result, text;
text = '\x1b[100mblack\x1b[49mdefault';
result = '<span style="background-color:#555">black<span style=' + '"background-color:#000">default</span></span>';
return test(text, result, done);
});
it('is able to disable underline', function(done) {
var result, text;
text = 'underline: \x1b[4mstuff\x1b[24mthings';
result = 'underline: <u>stuff</u>things';
return test(text, result, done);
});
it('is able to skip disabling underline', function(done) {
var result, text;
text = 'not underline: stuff\x1b[24mthings';
result = 'not underline: stuffthings';
return test(text, result, done);
});
it('renders two escape sequences in sequence', function(done) {
var result, text;
text = 'months remaining\x1b[1;31mtimes\x1b[m\x1b[1;32mmultiplied' + ' by\x1b[m $10';
result = 'months remaining<b><span style="color:#A00">times</span>' + '</b><b><span style="color:#0A0">multiplied by</span></b> $10';
return test(text, result, done);
});
it('drops EL code with no parameter', function(done) {
var result, text;
text = '\x1b[Khello';
result = 'hello';
return test(text, result, done);
});
it('drops EL code with 0 parameter', function(done) {
var result, text;
text = '\x1b[0Khello';
result = 'hello';
return test(text, result, done);
});
it('drops EL code with 1 parameter', function(done) {
var result, text;
text = '\x1b[1Khello';
result = 'hello';
return test(text, result, done);
});
it('drops EL code with 2 parameter', function(done) {
var result, text;
text = '\x1b[2Khello';
result = 'hello';
return test(text, result, done);
});
it('renders un-bold code appropriately', function(done) {
var result, text;
text = '\x1b[1mHello\x1b[22m World';
result = '<b>Hello</b> World';
return test(text, result, done);
});
it('skips rendering un-bold code appropriately', function(done) {
var result, text;
text = 'Hello\x1b[22m World';
result = 'Hello World';
return test(text, result, done);
});
it('renders un-italic code appropriately', function(done) {
var result, text;
text = '\x1b[3mHello\x1b[23m World';
result = '<i>Hello</i> World';
return test(text, result, done);
});
return it('skips rendering un-italic code appropriately', function(done) {
var result, text;
text = 'Hello\x1b[23m World';
result = 'Hello World';
return test(text, result, done);
});
describe('ansi to html', function () {
describe('constructed with no options', function () {
it('doesn\'t modify the input string', function (done) {
const text = 'some text';
const result = 'some text';
return test(text, result, done);
});
it('returns plain text when given plain text', function (done) {
const text = 'test\ntest\n';
const result = 'test\ntest\n';
return test(text, result, done);
});
it('renders foreground colors', function (done) {
const text = 'colors: \x1b[30mblack\x1b[37mwhite';
const result = 'colors: <span style="color:#000">black<span style="color:#AAA">white</span></span>';
return test(text, result, done);
});
it('renders light foreground colors', function (done) {
const text = 'colors: \x1b[90mblack\x1b[97mwhite';
const result = 'colors: <span style="color:#555">black<span style="color:#FFF">white</span></span>';
return test(text, result, done);
});
it('renders background colors', function (done) {
const text = 'colors: \x1b[40mblack\x1b[47mwhite';
const result = 'colors: <span style="background-color:#000">black<span style="background-color:#AAA">white</span></span>';
return test(text, result, done);
});
it('renders light background colors', function (done) {
const text = 'colors: \x1b[100mblack\x1b[107mwhite';
const result = 'colors: <span style="background-color:#555">black<span style="background-color:#FFF">white</span></span>';
return test(text, result, done);
});
it('renders strikethrough', function (done) {
const text = 'strike: \x1b[9mthat';
const result = 'strike: <strike>that</strike>';
return test(text, result, done);
});
it('renders blink', function (done) {
const text = 'blink: \x1b[5mwhat';
const result = 'blink: <blink>what</blink>';
return test(text, result, done);
});
it('renders underline', function (done) {
const text = 'underline: \x1b[4mstuff';
const result = 'underline: <u>stuff</u>';
return test(text, result, done);
});
it('renders bold', function (done) {
const text = 'bold: \x1b[1mstuff';
const result = 'bold: <b>stuff</b>';
return test(text, result, done);
});
it('renders italic', function (done) {
const text = 'italic: \x1b[3mstuff';
const result = 'italic: <i>stuff</i>';
return test(text, result, done);
});
it('handles resets', function (done) {
const text = '\x1b[1mthis is bold\x1b[0m, but this isn\'t';
const result = '<b>this is bold</b>, but this isn\'t';
return test(text, result, done);
});
it('handles multiple resets', function (done) {
const text = 'normal, \x1b[1mbold, \x1b[4munderline, \x1b[31mred\x1b[0m, normal';
const result = 'normal, <b>bold, <u>underline, <span style="color:' + '#A00">red</span></u></b>, normal';
return test(text, result, done);
});
it('handles resets with implicit 0', function (done) {
const text = '\x1b[1mthis is bold\x1b[m, but this isn\'t';
const result = '<b>this is bold</b>, but this isn\'t';
return test(text, result, done);
});
it('renders multi-attribute sequences', function (done) {
const text = 'normal, \x1b[1;4;31mbold, underline, and red\x1b[0m, normal';
const result = 'normal, <b><u><span style="color:#A00">bold, underline,' + ' and red</span></u></b>, normal';
return test(text, result, done);
});
it('renders multi-attribute sequences with a semi-colon', function (done) {
const text = 'normal, \x1b[1;4;31;mbold, underline, and red\x1b[0m, normal';
const result = 'normal, <b><u><span style="color:#A00">bold, underline, and red</span></u></b>, normal';
return test(text, result, done);
});
it('eats malformed sequences', function (done) {
const text = '\x1b[25oops forgot the \'m\'';
const result = 'oops forgot the \'m\'';
return test(text, result, done);
});
it('renders xterm 256 sequences', function (done) {
const text = '\x1b[38;5;196mhello';
const result = '<span style="color:#ff0000">hello</span>';
return test(text, result, done);
});
it('handles resetting to default foreground color', function (done) {
const text = '\x1b[30mblack\x1b[39mdefault';
const result = '<span style="color:#000">black<span style="color:#FFF">default</span></span>';
return test(text, result, done);
});
it('handles resetting to default background color', function (done) {
const text = '\x1b[100mblack\x1b[49mdefault';
const result = '<span style="background-color:#555">black<span style="background-color:#000">default</span></span>';
return test(text, result, done);
});
it('is able to disable underline', function (done) {
const text = 'underline: \x1b[4mstuff\x1b[24mthings';
const result = 'underline: <u>stuff</u>things';
return test(text, result, done);
});
it('is able to skip disabling underline', function (done) {
const text = 'not underline: stuff\x1b[24mthings';
const result = 'not underline: stuffthings';
return test(text, result, done);
});
it('renders two escape sequences in sequence', function (done) {
const text = 'months remaining\x1b[1;31mtimes\x1b[m\x1b[1;32mmultiplied by\x1b[m $10';
const result = 'months remaining<b><span style="color:#A00">times</span></b><b><span style="color:#0A0">multiplied by</span></b> $10';
return test(text, result, done);
});
it('drops EL code with no parameter', function (done) {
const text = '\x1b[Khello';
const result = 'hello';
return test(text, result, done);
});
it('drops EL code with 0 parameter', function (done) {
const text = '\x1b[0Khello';
const result = 'hello';
return test(text, result, done);
});
it('drops EL code with 1 parameter', function (done) {
const text = '\x1b[1Khello';
const result = 'hello';
return test(text, result, done);
});
it('drops EL code with 2 parameter', function (done) {
const text = '\x1b[2Khello';
const result = 'hello';
return test(text, result, done);
});
it('renders un-bold code appropriately', function (done) {
const text = '\x1b[1mHello\x1b[22m World';
const result = '<b>Hello</b> World';
return test(text, result, done);
});
it('skips rendering un-bold code appropriately', function (done) {
const text = 'Hello\x1b[22m World';
const result = 'Hello World';
return test(text, result, done);
});
it('renders un-italic code appropriately', function (done) {
const text = '\x1b[3mHello\x1b[23m World';
const result = '<i>Hello</i> World';
return test(text, result, done);
});
it('skips rendering un-italic code appropriately', function (done) {
const text = 'Hello\x1b[23m World';
const result = 'Hello World';
return test(text, result, done);
});
});
describe('with escapeXML option enabled', function() {
return it('escapes XML entities', function(done) {
var result, text;
text = 'normal, \x1b[1;4;31;mbold, <underline>, and red\x1b[0m, normal';
result = 'normal, <b><u><span style="color:#A00">bold, &lt;underline' + '&gt;, and red</span></u></b>, normal';
return test(text, result, done, {
escapeXML: true
describe('with escapeXML option enabled', function () {
it('escapes XML entities', function (done) {
const text = 'normal, \x1b[1;4;31;mbold, <underline>, and red\x1b[0m, normal';
const result = 'normal, <b><u><span style="color:#A00">bold, &lt;underline&gt;, and red</span></u></b>, normal';
return test(text, result, done, {escapeXML: true});
});
});
});
describe('with newline option enabled', function() {
it('renders line breaks', function(done) {
var result, text;
text = 'test\ntest\n';
result = 'test<br/>test<br/>';
return test(text, result, done, {
newline: true
describe('with newline option enabled', function () {
it('renders line breaks', function (done) {
const text = 'test\ntest\n';
const result = 'test<br/>test<br/>';
return test(text, result, done, {newline: true});
});
});
return it('renders multiple line breaks', function(done) {
var result, text;
text = 'test\n\ntest\n';
result = 'test<br/><br/>test<br/>';
return test(text, result, done, {
newline: true
it('renders multiple line breaks', function (done) {
const text = 'test\n\ntest\n';
const result = 'test<br/><br/>test<br/>';
return test(text, result, done, {newline: true});
});
});
});
return describe('with stream option enabled', function() {
it('persists styles between toHtml() invocations', function(done) {
var result, text;
text = ['\x1b[31mred', 'also red'];
result = '<span style="color:#A00">red</span><span style="color:' + '#A00">also red</span>';
return test(text, result, done, {
stream: true
describe('with stream option enabled', function () {
it('persists styles between toHtml() invocations', function (done) {
const text = ['\x1b[31mred', 'also red'];
const result = '<span style="color:#A00">red</span><span style="color:#A00">also red</span>';
return test(text, result, done, {stream: true});
});
});
it('persists styles between more than two toHtml() invocations', function(done) {
var result, text;
text = ['\x1b[31mred', 'also red', 'and red'];
result = '<span style="color:#A00">red</span><span style="color:' + '#A00">also red</span><span style="color:#A00">and red</span>';
return test(text, result, done, {
stream: true
it('persists styles between more than two toHtml() invocations', function (done) {
const text = ['\x1b[31mred', 'also red', 'and red'];
const result = '<span style="color:#A00">red</span><span style="color:#A00">also red</span><span style="color:#A00">and red</span>';
return test(text, result, done, {stream: true});
});
});
it('does not persist styles beyond their usefulness', function(done) {
var result, text;
text = ['\x1b[31mred', 'also red', '\x1b[30mblack', 'and black'];
result = '<span style="color:#A00">red</span><span style="color:' + '#A00">also red</span><span style="color:#A00"><span style="color:' + '#000">black</span></span><span style="color:#000">and black</span>';
return test(text, result, done, {
stream: true
it('does not persist styles beyond their usefulness', function (done) {
const text = ['\x1b[31mred', 'also red', '\x1b[30mblack', 'and black'];
const result = '<span style="color:#A00">red</span><span style="color:#A00">also red</span><span style="color:#A00"><span style="color:#000">black</span></span><span style="color:#000">and black</span>';
return test(text, result, done, {stream: true});
});
});
return it('removes all state when encountering a reset', function(done) {
var result, text;
text = ['\x1b[1mthis is bold\x1b[0m, but this isn\'t', ' nor is this'];
result = '<b>this is bold</b>, but this isn\'t nor is this';
return test(text, result, done, {
stream: true
it('removes one state when encountering a reset', function (done) {
const text = ['\x1b[1mthis is bold\x1b[0m, but this isn\'t', ' nor is this'];
const result = '<b>this is bold</b>, but this isn\'t nor is this';
return test(text, result, done, {stream: true});
});
});
it('removes multiple state when encountering a reset', function (done) {
const text = ['\x1b[1mthis \x1b[9mis bold\x1b[0m, but this isn\'t', ' nor is this'];
const result = '<b>this <strike>is bold</strike></b>, but this isn\'t nor is this';
return test(text, result, done, {stream: true});
});
});
});
}).call(this);
describe('with custom colors enabled', function () {
it('renders basic colors', function (done) {
const text = ['\x1b[31mblue', 'not blue'];
const result = '<span style="color:#00A">blue</span>not blue';
return test(text, result, done, {colors: {1: '#00A'}});
});
it('renders basic colors with streaming', function (done) {
const text = ['\x1b[31mblue', 'also blue'];
const result = '<span style="color:#00A">blue</span><span style="color:#00A">also blue</span>';
return test(text, result, done, {stream: true, colors: {1: '#00A'}});
});
it('renders custom colors and default colors', function (done) {
const text = ['\x1b[31mblue', 'not blue', '\x1b[94mlight blue', 'not colored'];
const result = '<span style="color:#00A">blue</span>not blue<span style="color:#55F">light blue</span>not colored';
return test(text, result, done, {colors: {1: '#00A'}});
});
it('renders custom colors and default colors together', function (done) {
const text = ['\x1b[31mblue', 'not blue', '\x1b[94mlight blue', 'not colored'];
const result = '<span style="color:#00A">blue</span>not blue<span style="color:#55F">light blue</span>not colored';
return test(text, result, done, {colors: {1: '#00A'}});
});
it('renders custom 8/ 16 colors', function (done) {
// code - 90 + 8 = color
// so 94 - 90 + 8 = 12
const text = ['\x1b[94mlighter blue'];
const result = '<span style="color:#33F">lighter blue</span>';
return test(text, result, done, {colors: {12: '#33F'}});
});
it('renders custom 256 colors', function (done) {
// code - 90 + 8 = color
// so 94 - 90 + 8 = 12
const text = ['\x1b[38;5;125mdark red', 'then \x1b[38;5;126msome other color'];
const result = '<span style="color:#af005f">dark red</span>then <span style="color:#af225f">some other color</span>';
return test(text, result, done, {colors: {126: '#af225f'}});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc