UNPKG

iustoet

Version:

Ansi codes, figlet fonts, and ascii art. 100% JS

580 lines (568 loc) 21.2 kB
(function(root, factory){ if(typeof define === 'function' && define.amd){ define([ 'ascii-art-ansi', 'ascii-art-font', 'ascii-art-image', 'ascii-art-table', 'ascii-art-graph', 'ascii-art-utf', 'ascii-art-ansi/grid', 'ascii-art-ansi', 'strangler' ], factory); }else if(typeof module === 'object' && module.exports){ module.exports = factory( require('ascii-art-ansi'), require('ascii-art-font'), require('ascii-art-image'), require('ascii-art-table'), require('ascii-art-graph'), require('ascii-art-utf'), require('ascii-art-ansi/grid'), require('strangler') ); }else{ root.AsciiArt = factory( root.AsciiArtAnsi, root.AsciiArtFont, root.AsciiArtImage, root.AsciiArtTable, root.AsciiArtGraph, root.AsciiArtUTF, root.AsciiArtAnsiGrid, root.Strangler ); } }(typeof self !== 'undefined' ? self : this, function(Ansi, Font, Image, Table, Graph, utf, TextGrid, Strangler){ var AsciiArt = { Ansi, Font, Image, Table, Graph }; var boxEdge = function(type, size, options, style){ var edge = ''; switch(type){ case 'l': edge += options.ul+"\n"; for(var lcv=2; lcv< size; lcv++){ edge += style(options.l)+"\n"; } edge += style(options.ll); break; case 'r': edge += options.ur+"\n"; for(var lcv=2; lcv< size; lcv++){ edge += style(options.r)+"\n"; } edge += style(options.lr); break; case 't': for(var lcv=0; lcv< size; lcv++){ edge += style(options.t); } break; case 'b': for(var lcv=0; lcv< size; lcv++){ edge += style(options.b); } break; } return edge; } var getTextFile = function(file, cb){ var parts = (file ||'').split('/') if(!parts.filter(function(p){ return p.trim() }).length){ throw new Error('incomplete path provided!'); } /*switch(parts[0]){ case 'textfiles.com': if(parts[1]){ var pre = ''; var post = ''; switch(parts[1]){ case 'NFOS': post = 'asciiart/'; case 'asciiart': pre = 'artscene.'; break; case 'LOGOS': case 'DECUS': post = 'art/'; break; case 'RAZOR': case 'FAIRLIGHT': case 'DREAMTEAM': case 'HUMBLE': case 'HYBRID': case 'PRESTIGE': case 'INC': case 'TDUJAM': case 'ANSI': post = 'piracy/'; break; } request( 'http://'+pre+'textfiles.com/'+post+parts[1]+'/'+parts[2], function(err, res, body){ var data = body || ( res && res.request && res.request.responseContent && res.request.responseContent.body ) || undefined; cb(undefined, data); } ); break; } //default : throw new Error('unknown art source:'+parts[0]); }*/ } //todo: optional styling on font callback var combine = function(blockOne, blockTwo, style){ var linesOne = blockOne.split("\n"); var linesTwo = blockTwo.split("\n"); var diff = Math.max(linesOne.length - linesTwo.length, 0); linesOne.forEach(function(line, index){ if(index >= diff){ if(style){ linesOne[index] = linesOne[index]+AsciiArt.Ansi.Codes(linesTwo[index-diff], style, true); }else{ linesOne[index] = linesOne[index]+linesTwo[index-diff]; } } }); return linesOne.join("\n"); }; var safeCombine = function(oldText, newText, style){ return combine( oldText|| (new Array(newText.split("\n").length)).join("\n"), newText, style ); } var fontChain = function(){ var cb; var chain = []; var result; var ob = this; var done = function(){ ob.working = false; check(); } var check = function(){ if(ob.working) return; else ob.working = true; if(result && cb && chain.length === 0){ check = function(){}; cb(undefined, result); } //todo: refactor this rat's nest into a mode switch var item; var mode; if(chain.length){ item = chain.shift(); if(item.options) item = item.options; if(typeof item == 'string'){ mode = 'join'; }else{ if(item.artwork){ mode = 'artwork'; }else{ if(item.start !== undefined || item.stop ){ mode = 'lines'; }else{ if(item.x !== undefined && item.y !== undefined ){ mode = 'overlay'; }else{ if(item.font){ mode = 'font'; }else{ if(item.data){ mode = 'table'; }else{ if(item.style && item.text){ mode = 'style'; }else{ if(item.height && item.width && item.graph){ mode = 'graph'; }else{ if(item.l && item.r && item.t && item.b){ mode = 'border'; }else{ if(item.strip){ mode = 'strip'; }else{ mode = 'image'; } } } } } } } } } } } switch(mode){ case 'join': setTimeout(function(){ result = safeCombine(result, item); done(); }, 1); break; case 'artwork': getTextFile(item.artwork, function(err, artwork){ result = safeCombine(result, artwork); done(); }); break; case 'strip': result = Ansi.strip(result); done(); break; case 'lines': setTimeout(function(){ result = ( result.split("\n").slice( item.start || 0, item.stop) ).join("\n"); done(); }, 1); break; case 'overlay': setTimeout(function(){ var canvas = new TextGrid(result); if(item.style){ item.text = Ansi.map(item.text, function(chr, codes){ return (item.style?Ansi.codes(chr, item.style):''); }); } canvas.drawOnto(item.text, item.x, item.y, item.transparent); result = canvas.toString(); done(); }, 1); break; case 'style': setTimeout(function(){ result = Ansi.codes(item.text || result, item.style); done(); }, 1); break; case 'font': if(item.font.indexOf('u:') === 0){ result = safeCombine( result, utf.font(item.text, item.font.substring(2)), item.style ); done(); }else{ AsciiArt.Font.create(item.text, item.font, function(err, text){ result = safeCombine(result, text, item.style); done(); }); } break; case 'border': var canvas = new TextGrid(result); var styler = item.style?function(s){ return AsciiArt.style(s, item.style); }:function(s){ return s }; canvas.drawOnto(boxEdge('l', canvas.height, item, styler), 0, 0); canvas.drawOnto(boxEdge('r', canvas.height, item, styler), -1, 0); canvas.drawOnto(boxEdge('t', canvas.width-3, item, styler), 1, 0); canvas.drawOnto(boxEdge('b', canvas.width-3, item, styler), 1, -1); result = canvas.toString(); setTimeout(function(){ done(); }, 0); break; case 'table': setTimeout(function(){ var opts = {}; [ 'intersection', 'horizontalBar', 'verticalBar', 'dataStyle', 'headerStyle', 'bars', 'cellStyle', 'borderColor' ].forEach(function(opt){ opts[opt] = item[opt]; }) var table = new AsciiArt.Table(opts); var fields = item.columns || Object.keys(item.data[0]||{}); table.setHeading.apply(table, fields); table.data = item.data; var res = table.write( item.width || ( process && process.stdout && process.stdout.columns ) || 80 ); result = safeCombine(result, res); done(); }, 1); break; case 'image': var image = new AsciiArt.Image(item); if(item.lineart){ image.writeLineArt(function(err, text){ if(!err) result = safeCombine(result, text); done(); }); }else{ if(item.posterize){ image.writePosterized(function(err, text){ if(!err) result = safeCombine(result, text); done(); }); }else{ image.write(function(err, text){ if(!err) result = safeCombine(result, text); done(); }); } } break; case 'graph': AsciiArt.Graph.create(item, function(err, text){ if(!err) result = safeCombine(result, text); done(); }); break; } } this.font = function(str, fontName, style, callback){ if(arguments.length == 1 && typeof str === 'object'){ chain.push(str); }else{ if(typeof style == 'function'){ callback = style; style = undefined; } if(callback) cb = callback; chain.push({ font : fontName, text : str, style : style }); } check(); return ob; }; this.artwork = function(artwork, callback){ if(callback) cb = callback; chain.push({ artwork : artwork, }); check(); return ob; } this.lines = function(start, stop, callback){ var opts = { start : start }; if(typeof stop == 'function'){ cb = stop; }else{ if(callback) cb = callback; opts.stop = stop; } chain.push(opts); check(); return ob; } this.image = function(options, callback){ if(callback) cb = callback; chain.push({ options : options, }); check(); return ob; }; this.strip = function(options, callback){ if(callback) cb = callback; chain.push({ strip : true, }); check(); return ob; }; this.border = function(options, callback){ if(callback) cb = callback; chain.push({ options : options, }); check(); return ob; }; this.graph = function(options, callback){ if(callback) cb = callback; options.graph = true; chain.push({ options : options, }); check(); return ob; }; this.table = function(options, callback){ if(callback) cb = callback; chain.push(options); check(); return ob; }; this.join = function(text, callback){ if(callback) cb = callback; chain.push(text); check(); return ob; }; this.style = function(text, styles, callback){ return Ansi.codes(text, styles); var opts = {}; if((typeof styles == 'function' || !styles) && !callback){ callback = styles; opts = text; }else{ opts.text = text; opts.style = style; } if(callback) cb = callback; chain.push(opts); check(); return ob; }; this.overlay = function(text, options, callback){ if(typeof options == 'function'){ callback = options; options = {x:0, y:0}; } if(callback) cb = callback; chain.push({ options : { x: options.x ||0, y: options.y ||0, style: options.style, transparent: !!options.transparent, chroma: typeof options.transparent == 'string'? options.transparent:undefined, text: text } }); check(); return ob; }; this.completed = function(){ return new Promise(function(resolve, reject){ cb = function(err, result){ if(err) return reject(err); resolve(result); } check(); }); };//*/ this.toPromise = function(){ return new Promise(function(resolve, reject){ cb = function(err, result){ if(err) return reject(err); resolve(result); } check(); }); };//*/ this.then = function(handler){ var promise = new Promise(function(resolve, reject){ cb = function(err, result){ if(err) return reject(err); resolve(result); } check(); }); return promise.then(handler); }; return this; }; AsciiArt.Font.newReturnContext = function(options){ var chain = fontChain.apply({}); return chain.font(options); } AsciiArt.Font.newReturnContext = function(options){ var chain = fontChain.apply({}); return chain.font(options); } AsciiArt.font = function(str, font, callback){ if(font.indexOf('u:') === 0){ var result = utf.font(str, font.substring(2)); if(callback){ setTimeout(function(){ callback(undefined, result); }, 0); //todo: support promise returns here! return result; } }else return AsciiArt.Font.create(str, font, callback); } AsciiArt.style = function(text, styles, terminate){ return Ansi.codes(text, styles, terminate); } AsciiArt.Image.newReturnContext = function(options){ var chain = fontChain.apply({}); return chain.image(options); } AsciiArt.image = function(options, callback){ return AsciiArt.Image.create(options, callback); } AsciiArt.Table.newReturnContext = function(options){ var chain = fontChain.apply({}); return chain.table(options); } AsciiArt.table = function(options, callback){ return AsciiArt.Table.create(options, callback); } AsciiArt.Graph.newReturnContext = function(options){ var chain = fontChain.apply({}); return chain.font(options); } AsciiArt.graph = function(options, callback){ return AsciiArt.Graph.create(options, callback); } AsciiArt.use = function(interfaceName, implementation){ switch(interfaceName.toLowerCase()){ case 'request': AsciiArt.Image.useRequest(implementation); AsciiArt.Artwork.useRequest(implementation); break; case 'artwork': AsciiArt.Artwork = implementation; break; default : throw new Error('Unknown interface: '+interfaceName) } } AsciiArt.artwork = function(options, callback){ if(!callback){ var chain = fontChain.apply({}); return chain.image(options); }else{ getTextFile(options.artwork, function(err, artwork){ callback(artwork); }); } } //*/ AsciiArt.strings = function(strs, options, callback){ if(typeof options == 'string') options = {font:options}; var jobs = 0; var results = []; function checkComplete(){ jobs--; if(jobs == 0) callback.apply(callback, results); } strs.forEach(function(str, index){ jobs++; AsciiArt.font(str, options.font, options.style, function(rendered){ results[index] = rendered; checkComplete(); }) }); } return AsciiArt; }));