Version 1
[yaffs-website] / node_modules / grunt-legacy-log-utils / index.js
1 /*
2  * grunt
3  * http://gruntjs.com/
4  *
5  * Copyright (c) 2016 "Cowboy" Ben Alman
6  * Licensed under the MIT license.
7  * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
8  */
9
10 'use strict';
11
12 var chalk = require('chalk');
13 var _ = require('lodash');
14
15 // Pretty-format a word list.
16 exports.wordlist = function(arr, options) {
17   options = _.defaults(options || {}, {
18     separator: ', ',
19     color: 'cyan'
20   });
21   return arr.map(function(item) {
22     return options.color ? chalk[options.color](item) : item;
23   }).join(options.separator);
24 };
25
26 // Return a string, uncolored (suitable for testing .length, etc).
27 exports.uncolor = function(str) {
28   return str.replace(/\x1B\[\d+m/g, '');
29 };
30
31 // Word-wrap text to a given width, permitting ANSI color codes.
32 exports.wraptext = function(width, text) {
33   // notes to self:
34   // grab 1st character or ansi code from string
35   // if ansi code, add to array and save for later, strip from front of string
36   // if character, add to array and increment counter, strip from front of string
37   // if width + 1 is reached and current character isn't space:
38   //  slice off everything after last space in array and prepend it to string
39   //  etc
40
41   // This result array will be joined on \n.
42   var result = [];
43   var matches, color, tmp;
44   var captured = [];
45   var charlen = 0;
46
47   while (matches = text.match(/(?:(\x1B\[\d+m)|\n|(.))([\s\S]*)/)) {
48     // Updated text to be everything not matched.
49     text = matches[3];
50
51     // Matched a color code?
52     if (matches[1]) {
53       // Save last captured color code for later use.
54       color = matches[1];
55       // Capture color code.
56       captured.push(matches[1]);
57       continue;
58
59     // Matched a non-newline character?
60     } else if (matches[2]) {
61       // If this is the first character and a previous color code was set, push
62       // that onto the captured array first.
63       if (charlen === 0 && color) { captured.push(color); }
64       // Push the matched character.
65       captured.push(matches[2]);
66       // Increment the current charlen.
67       charlen++;
68       // If not yet at the width limit or a space was matched, continue.
69       if (charlen <= width || matches[2] === ' ') { continue; }
70       // The current charlen exceeds the width and a space wasn't matched.
71       // "Roll everything back" until the last space character.
72       tmp = captured.lastIndexOf(' ');
73       text = captured.slice(tmp === -1 ? tmp : tmp + 1).join('') + text;
74       captured = captured.slice(0, tmp);
75     }
76
77     // The limit has been reached. Push captured string onto result array.
78     result.push(captured.join(''));
79
80     // Reset captured array and charlen.
81     captured = [];
82     charlen = 0;
83   }
84
85   result.push(captured.join(''));
86   return result.join('\n');
87 };
88
89 // Format output into columns, wrapping words as-necessary.
90 exports.table = function(widths, texts) {
91   var rows = [];
92   widths.forEach(function(width, i) {
93     var lines = this.wraptext(width, texts[i]).split('\n');
94     lines.forEach(function(line, j) {
95       var row = rows[j];
96       if (!row) { row = rows[j] = []; }
97       row[i] = line;
98     });
99   }, this);
100
101   var lines = [];
102   rows.forEach(function(row) {
103     var txt = '';
104     var column;
105     for (var i = 0; i < row.length; i++) {
106       column = row[i] || '';
107       txt += column;
108       var diff = widths[i] - this.uncolor(column).length;
109       if (diff > 0) { txt += _.repeat(' ', diff); }
110     }
111     lines.push(txt);
112   }, this);
113
114   return lines.join('\n');
115 };