"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/cliui/index.js" (7 Feb 2017, 8054 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 var stringWidth = require('string-width')
    2 var stripAnsi = require('strip-ansi')
    3 var wrap = require('wrap-ansi')
    4 var align = {
    5   right: alignRight,
    6   center: alignCenter
    7 }
    8 var top = 0
    9 var right = 1
   10 var bottom = 2
   11 var left = 3
   12 
   13 function UI (opts) {
   14   this.width = opts.width
   15   this.wrap = opts.wrap
   16   this.rows = []
   17 }
   18 
   19 UI.prototype.span = function () {
   20   var cols = this.div.apply(this, arguments)
   21   cols.span = true
   22 }
   23 
   24 UI.prototype.div = function () {
   25   if (arguments.length === 0) this.div('')
   26   if (this.wrap && this._shouldApplyLayoutDSL.apply(this, arguments)) {
   27     return this._applyLayoutDSL(arguments[0])
   28   }
   29 
   30   var cols = []
   31 
   32   for (var i = 0, arg; (arg = arguments[i]) !== undefined; i++) {
   33     if (typeof arg === 'string') cols.push(this._colFromString(arg))
   34     else cols.push(arg)
   35   }
   36 
   37   this.rows.push(cols)
   38   return cols
   39 }
   40 
   41 UI.prototype._shouldApplyLayoutDSL = function () {
   42   return arguments.length === 1 && typeof arguments[0] === 'string' &&
   43     /[\t\n]/.test(arguments[0])
   44 }
   45 
   46 UI.prototype._applyLayoutDSL = function (str) {
   47   var _this = this
   48   var rows = str.split('\n')
   49   var leftColumnWidth = 0
   50 
   51   // simple heuristic for layout, make sure the
   52   // second column lines up along the left-hand.
   53   // don't allow the first column to take up more
   54   // than 50% of the screen.
   55   rows.forEach(function (row) {
   56     var columns = row.split('\t')
   57     if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
   58       leftColumnWidth = Math.min(
   59         Math.floor(_this.width * 0.5),
   60         stringWidth(columns[0])
   61       )
   62     }
   63   })
   64 
   65   // generate a table:
   66   //  replacing ' ' with padding calculations.
   67   //  using the algorithmically generated width.
   68   rows.forEach(function (row) {
   69     var columns = row.split('\t')
   70     _this.div.apply(_this, columns.map(function (r, i) {
   71       return {
   72         text: r.trim(),
   73         padding: _this._measurePadding(r),
   74         width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined
   75       }
   76     }))
   77   })
   78 
   79   return this.rows[this.rows.length - 1]
   80 }
   81 
   82 UI.prototype._colFromString = function (str) {
   83   return {
   84     text: str,
   85     padding: this._measurePadding(str)
   86   }
   87 }
   88 
   89 UI.prototype._measurePadding = function (str) {
   90   // measure padding without ansi escape codes
   91   var noAnsi = stripAnsi(str)
   92   return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]
   93 }
   94 
   95 UI.prototype.toString = function () {
   96   var _this = this
   97   var lines = []
   98 
   99   _this.rows.forEach(function (row, i) {
  100     _this.rowToString(row, lines)
  101   })
  102 
  103   // don't display any lines with the
  104   // hidden flag set.
  105   lines = lines.filter(function (line) {
  106     return !line.hidden
  107   })
  108 
  109   return lines.map(function (line) {
  110     return line.text
  111   }).join('\n')
  112 }
  113 
  114 UI.prototype.rowToString = function (row, lines) {
  115   var _this = this
  116   var padding
  117   var rrows = this._rasterize(row)
  118   var str = ''
  119   var ts
  120   var width
  121   var wrapWidth
  122 
  123   rrows.forEach(function (rrow, r) {
  124     str = ''
  125     rrow.forEach(function (col, c) {
  126       ts = '' // temporary string used during alignment/padding.
  127       width = row[c].width // the width with padding.
  128       wrapWidth = _this._negatePadding(row[c]) // the width without padding.
  129 
  130       ts += col
  131 
  132       for (var i = 0; i < wrapWidth - stringWidth(col); i++) {
  133         ts += ' '
  134       }
  135 
  136       // align the string within its column.
  137       if (row[c].align && row[c].align !== 'left' && _this.wrap) {
  138         ts = align[row[c].align](ts, wrapWidth)
  139         if (stringWidth(ts) < wrapWidth) ts += new Array(width - stringWidth(ts)).join(' ')
  140       }
  141 
  142       // apply border and padding to string.
  143       padding = row[c].padding || [0, 0, 0, 0]
  144       if (padding[left]) str += new Array(padding[left] + 1).join(' ')
  145       str += addBorder(row[c], ts, '| ')
  146       str += ts
  147       str += addBorder(row[c], ts, ' |')
  148       if (padding[right]) str += new Array(padding[right] + 1).join(' ')
  149 
  150       // if prior row is span, try to render the
  151       // current row on the prior line.
  152       if (r === 0 && lines.length > 0) {
  153         str = _this._renderInline(str, lines[lines.length - 1])
  154       }
  155     })
  156 
  157     // remove trailing whitespace.
  158     lines.push({
  159       text: str.replace(/ +$/, ''),
  160       span: row.span
  161     })
  162   })
  163 
  164   return lines
  165 }
  166 
  167 function addBorder (col, ts, style) {
  168   if (col.border) {
  169     if (/[.']-+[.']/.test(ts)) return ''
  170     else if (ts.trim().length) return style
  171     else return '  '
  172   }
  173   return ''
  174 }
  175 
  176 // if the full 'source' can render in
  177 // the target line, do so.
  178 UI.prototype._renderInline = function (source, previousLine) {
  179   var leadingWhitespace = source.match(/^ */)[0].length
  180   var target = previousLine.text
  181   var targetTextWidth = stringWidth(target.trimRight())
  182 
  183   if (!previousLine.span) return source
  184 
  185   // if we're not applying wrapping logic,
  186   // just always append to the span.
  187   if (!this.wrap) {
  188     previousLine.hidden = true
  189     return target + source
  190   }
  191 
  192   if (leadingWhitespace < targetTextWidth) return source
  193 
  194   previousLine.hidden = true
  195 
  196   return target.trimRight() + new Array(leadingWhitespace - targetTextWidth + 1).join(' ') + source.trimLeft()
  197 }
  198 
  199 UI.prototype._rasterize = function (row) {
  200   var _this = this
  201   var i
  202   var rrow
  203   var rrows = []
  204   var widths = this._columnWidths(row)
  205   var wrapped
  206 
  207   // word wrap all columns, and create
  208   // a data-structure that is easy to rasterize.
  209   row.forEach(function (col, c) {
  210     // leave room for left and right padding.
  211     col.width = widths[c]
  212     if (_this.wrap) wrapped = wrap(col.text, _this._negatePadding(col), {hard: true}).split('\n')
  213     else wrapped = col.text.split('\n')
  214 
  215     if (col.border) {
  216       wrapped.unshift('.' + new Array(_this._negatePadding(col) + 3).join('-') + '.')
  217       wrapped.push("'" + new Array(_this._negatePadding(col) + 3).join('-') + "'")
  218     }
  219 
  220     // add top and bottom padding.
  221     if (col.padding) {
  222       for (i = 0; i < (col.padding[top] || 0); i++) wrapped.unshift('')
  223       for (i = 0; i < (col.padding[bottom] || 0); i++) wrapped.push('')
  224     }
  225 
  226     wrapped.forEach(function (str, r) {
  227       if (!rrows[r]) rrows.push([])
  228 
  229       rrow = rrows[r]
  230 
  231       for (var i = 0; i < c; i++) {
  232         if (rrow[i] === undefined) rrow.push('')
  233       }
  234       rrow.push(str)
  235     })
  236   })
  237 
  238   return rrows
  239 }
  240 
  241 UI.prototype._negatePadding = function (col) {
  242   var wrapWidth = col.width
  243   if (col.padding) wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0)
  244   if (col.border) wrapWidth -= 4
  245   return wrapWidth
  246 }
  247 
  248 UI.prototype._columnWidths = function (row) {
  249   var _this = this
  250   var widths = []
  251   var unset = row.length
  252   var unsetWidth
  253   var remainingWidth = this.width
  254 
  255   // column widths can be set in config.
  256   row.forEach(function (col, i) {
  257     if (col.width) {
  258       unset--
  259       widths[i] = col.width
  260       remainingWidth -= col.width
  261     } else {
  262       widths[i] = undefined
  263     }
  264   })
  265 
  266   // any unset widths should be calculated.
  267   if (unset) unsetWidth = Math.floor(remainingWidth / unset)
  268   widths.forEach(function (w, i) {
  269     if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text)
  270     else if (w === undefined) widths[i] = Math.max(unsetWidth, _minWidth(row[i]))
  271   })
  272 
  273   return widths
  274 }
  275 
  276 // calculates the minimum width of
  277 // a column, based on padding preferences.
  278 function _minWidth (col) {
  279   var padding = col.padding || []
  280   var minWidth = 1 + (padding[left] || 0) + (padding[right] || 0)
  281   if (col.border) minWidth += 4
  282   return minWidth
  283 }
  284 
  285 function alignRight (str, width) {
  286   str = str.trim()
  287   var padding = ''
  288   var strWidth = stringWidth(str)
  289 
  290   if (strWidth < width) {
  291     padding = new Array(width - strWidth + 1).join(' ')
  292   }
  293 
  294   return padding + str
  295 }
  296 
  297 function alignCenter (str, width) {
  298   str = str.trim()
  299   var padding = ''
  300   var strWidth = stringWidth(str.trim())
  301 
  302   if (strWidth < width) {
  303     padding = new Array(parseInt((width - strWidth) / 2, 10) + 1).join(' ')
  304   }
  305 
  306   return padding + str
  307 }
  308 
  309 module.exports = function (opts) {
  310   opts = opts || {}
  311 
  312   return new UI({
  313     width: (opts || {}).width || 80,
  314     wrap: typeof opts.wrap === 'boolean' ? opts.wrap : true
  315   })
  316 }