Completely updated React, fixed #11, (hopefully)

This commit is contained in:
2018-03-04 19:11:49 -05:00
parent 6e0afd6e2a
commit 34e5f5139a
13674 changed files with 333464 additions and 473223 deletions

View File

@@ -21,9 +21,7 @@
"saveSpec": null,
"fetchSpec": "2.1.1"
},
"_requiredBy": [
"/webpack"
],
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
"_spec": "2.1.1",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",

View File

@@ -21,9 +21,7 @@
"saveSpec": null,
"fetchSpec": "5.3.0"
},
"_requiredBy": [
"/webpack"
],
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz",
"_spec": "5.3.0",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",

View File

@@ -1,27 +1,64 @@
'use strict';
module.exports = function () {
var str = [].map.call(arguments, function (str) {
return str.trim();
}).filter(function (str) {
return str.length;
}).join('-');
if (!str.length) {
function preserveCamelCase(str) {
let isLastCharLower = false;
let isLastCharUpper = false;
let isLastLastCharUpper = false;
for (let i = 0; i < str.length; i++) {
const c = str[i];
if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) {
str = str.substr(0, i) + '-' + str.substr(i);
isLastCharLower = false;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = true;
i++;
} else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) {
str = str.substr(0, i - 1) + '-' + str.substr(i - 1);
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = false;
isLastCharLower = true;
} else {
isLastCharLower = c.toLowerCase() === c;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = c.toUpperCase() === c;
}
}
return str;
}
module.exports = function (str) {
if (arguments.length > 1) {
str = Array.from(arguments)
.map(x => x.trim())
.filter(x => x.length)
.join('-');
} else {
str = str.trim();
}
if (str.length === 0) {
return '';
}
if (str.length === 1 || !(/[_.\- ]+/).test(str) ) {
if (str[0] === str[0].toLowerCase() && str.slice(1) !== str.slice(1).toLowerCase()) {
return str;
}
if (str.length === 1) {
return str.toLowerCase();
}
if (/^[a-z0-9]+$/.test(str)) {
return str;
}
const hasUpperCase = str !== str.toLowerCase();
if (hasUpperCase) {
str = preserveCamelCase(str);
}
return str
.replace(/^[_.\- ]+/, '')
.toLowerCase()
.replace(/[_.\- ]+(\w|$)/g, function (m, p1) {
return p1.toUpperCase();
});
.replace(/^[_.\- ]+/, '')
.toLowerCase()
.replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase());
};

View File

@@ -1,46 +1,45 @@
{
"_args": [
[
"camelcase@1.2.1",
"camelcase@4.1.0",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI"
]
],
"_from": "camelcase@1.2.1",
"_id": "camelcase@1.2.1",
"_from": "camelcase@4.1.0",
"_id": "camelcase@4.1.0",
"_inBundle": false,
"_integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
"_integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
"_location": "/webpack/camelcase",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "camelcase@1.2.1",
"raw": "camelcase@4.1.0",
"name": "camelcase",
"escapedName": "camelcase",
"rawSpec": "1.2.1",
"rawSpec": "4.1.0",
"saveSpec": null,
"fetchSpec": "1.2.1"
"fetchSpec": "4.1.0"
},
"_requiredBy": [
"/webpack/uglify-js/yargs"
],
"_resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
"_spec": "1.2.1",
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
"_spec": "4.1.0",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "http://sindresorhus.com"
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/camelcase/issues"
},
"description": "Convert a dash/dot/underscore/space separated string to camelCase: foo-bar → fooBar",
"devDependencies": {
"ava": "0.0.4"
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=0.10.0"
"node": ">=4"
},
"files": [
"index.js"
@@ -67,7 +66,10 @@
"url": "git+https://github.com/sindresorhus/camelcase.git"
},
"scripts": {
"test": "node test.js"
"test": "xo && ava"
},
"version": "1.2.1"
"version": "4.1.0",
"xo": {
"esnext": true
}
}

View File

@@ -5,7 +5,7 @@
## Install
```sh
```
$ npm install --save camelcase
```
@@ -13,44 +13,45 @@ $ npm install --save camelcase
## Usage
```js
var camelCase = require('camelcase');
const camelCase = require('camelcase');
camelCase('foo-bar');
//=> fooBar
//=> 'fooBar'
camelCase('foo_bar');
//=> fooBar
//=> 'fooBar'
camelCase('Foo-Bar');
//=> fooBar
//=> 'fooBar'
camelCase('--foo.bar');
//=> fooBar
//=> 'fooBar'
camelCase('__foo__bar__');
//=> fooBar
//=> 'fooBar'
camelCase('foo bar');
//=> fooBar
//=> 'fooBar'
console.log(process.argv[3]);
//=> --foo-bar
//=> '--foo-bar'
camelCase(process.argv[3]);
//=> fooBar
//=> 'fooBar'
camelCase('foo', 'bar');
//=> fooBar
//=> 'fooBar'
camelCase('__foo__', '--bar');
//=> fooBar
//=> 'fooBar'
```
## Related
See [`decamelize`](https://github.com/sindresorhus/decamelize) for the inverse.
- [decamelize](https://github.com/sindresorhus/decamelize) - The inverse of this module
- [uppercamelcase](https://github.com/SamVerschueren/uppercamelcase) - Like this module, but to PascalCase instead of camelCase
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -21,9 +21,7 @@
"saveSpec": null,
"fetchSpec": "0.1.3"
},
"_requiredBy": [
"/webpack/cliui"
],
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
"_spec": "0.1.3",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",

View File

@@ -1 +0,0 @@
repo_token: NiRhyj91Z2vtgob6XdEAqs83rzNnbMZUu

View File

@@ -1,2 +0,0 @@
.DS_Store
node_modules

View File

@@ -1,7 +0,0 @@
language: node_js
node_js:
- "0.10"
- "0.11"
- "0.12"
- "iojs"
after_script: "NODE_ENV=test YOURPACKAGE_COVERAGE=1 ./node_modules/.bin/mocha --require patched-blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js"

View File

@@ -0,0 +1,15 @@
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
<a name="3.2.0"></a>
# [3.2.0](https://github.com/yargs/cliui/compare/v3.1.2...v3.2.0) (2016-04-11)
### Bug Fixes
* reduces tarball size ([acc6c33](https://github.com/yargs/cliui/commit/acc6c33))
### Features
* adds standard-version for release management ([ff84e32](https://github.com/yargs/cliui/commit/ff84e32))

View File

@@ -1,8 +1,9 @@
# cliui
[![Build Status](https://travis-ci.org/bcoe/cliui.png)](https://travis-ci.org/bcoe/cliui)
[![Coverage Status](https://coveralls.io/repos/bcoe/cliui/badge.svg?branch=)](https://coveralls.io/r/bcoe/cliui?branch=)
[![Build Status](https://travis-ci.org/yargs/cliui.svg)](https://travis-ci.org/yargs/cliui)
[![Coverage Status](https://coveralls.io/repos/yargs/cliui/badge.svg?branch=)](https://coveralls.io/r/yargs/cliui?branch=)
[![NPM version](https://img.shields.io/npm/v/cliui.svg)](https://www.npmjs.com/package/cliui)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
easily create complex multi-column command-line-interfaces.
@@ -23,15 +24,17 @@ ui.div({
ui.div(
{
text: "-f, --file",
width: 40,
width: 20,
padding: [0, 4, 0, 4]
},
{
text: "the file to load",
width: 25
text: "the file to load." +
chalk.green("(if this description is long it wraps).")
,
width: 20
},
{
text: "[required]",
text: chalk.red("[required]"),
align: 'right'
}
)
@@ -39,6 +42,8 @@ ui.div(
console.log(ui.toString())
```
<img width="500" src="screenshot.png">
## Layout DSL
cliui exposes a simple layout DSL:
@@ -48,7 +53,7 @@ object:
* `\n`: characters will be interpreted as new rows.
* `\t`: characters will be interpreted as new columns.
* ` `: characters will be interpreted as padding.
* `\s`: characters will be interpreted as padding.
**as an example...**
@@ -97,6 +102,7 @@ options:
* **width:** the width of a column.
* **align:** alignment, `right` or `center`.
* **padding:** `[top, right, bottom, left]`.
* **border:** should a border be placed around the div?
### cliui.span(column, column, column)

View File

@@ -1,12 +1,14 @@
var wrap = require('wordwrap'),
align = {
right: require('right-align'),
center: require('center-align')
},
top = 0,
right = 1,
bottom = 2,
left = 3
var stringWidth = require('string-width')
var stripAnsi = require('strip-ansi')
var wrap = require('wrap-ansi')
var align = {
right: alignRight,
center: alignCenter
}
var top = 0
var right = 1
var bottom = 2
var left = 3
function UI (opts) {
this.width = opts.width
@@ -42,9 +44,9 @@ UI.prototype._shouldApplyLayoutDSL = function () {
}
UI.prototype._applyLayoutDSL = function (str) {
var _this = this,
rows = str.split('\n'),
leftColumnWidth = 0
var _this = this
var rows = str.split('\n')
var leftColumnWidth = 0
// simple heuristic for layout, make sure the
// second column lines up along the left-hand.
@@ -52,10 +54,10 @@ UI.prototype._applyLayoutDSL = function (str) {
// than 50% of the screen.
rows.forEach(function (row) {
var columns = row.split('\t')
if (columns.length > 1 && columns[0].length > leftColumnWidth) {
if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
leftColumnWidth = Math.min(
Math.floor(_this.width * 0.5),
columns[0].length
stringWidth(columns[0])
)
}
})
@@ -68,7 +70,7 @@ UI.prototype._applyLayoutDSL = function (str) {
_this.div.apply(_this, columns.map(function (r, i) {
return {
text: r.trim(),
padding: [0, r.match(/\s*$/)[0].length, 0, r.match(/^\s*/)[0].length],
padding: _this._measurePadding(r),
width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined
}
}))
@@ -79,13 +81,20 @@ UI.prototype._applyLayoutDSL = function (str) {
UI.prototype._colFromString = function (str) {
return {
text: str
text: str,
padding: this._measurePadding(str)
}
}
UI.prototype._measurePadding = function (str) {
// measure padding without ansi escape codes
var noAnsi = stripAnsi(str)
return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]
}
UI.prototype.toString = function () {
var _this = this,
lines = []
var _this = this
var lines = []
_this.rows.forEach(function (row, i) {
_this.rowToString(row, lines)
@@ -103,13 +112,13 @@ UI.prototype.toString = function () {
}
UI.prototype.rowToString = function (row, lines) {
var _this = this,
paddingLeft,
rrows = this._rasterize(row),
str = '',
ts,
width,
wrapWidth
var _this = this
var padding
var rrows = this._rasterize(row)
var str = ''
var ts
var width
var wrapWidth
rrows.forEach(function (rrow, r) {
str = ''
@@ -118,27 +127,30 @@ UI.prototype.rowToString = function (row, lines) {
width = row[c].width // the width with padding.
wrapWidth = _this._negatePadding(row[c]) // the width without padding.
for (var i = 0; i < Math.max(wrapWidth, col.length); i++) {
ts += col.charAt(i) || ' '
ts += col
for (var i = 0; i < wrapWidth - stringWidth(col); i++) {
ts += ' '
}
// align the string within its column.
if (row[c].align && row[c].align !== 'left' && _this.wrap) {
ts = align[row[c].align](ts.trim() + '\n' + new Array(wrapWidth + 1).join(' '))
.split('\n')[0]
if (ts.length < wrapWidth) ts += new Array(width - ts.length).join(' ')
ts = align[row[c].align](ts, wrapWidth)
if (stringWidth(ts) < wrapWidth) ts += new Array(width - stringWidth(ts)).join(' ')
}
// add left/right padding and print string.
paddingLeft = (row[c].padding || [0, 0, 0, 0])[left]
if (paddingLeft) str += new Array(row[c].padding[left] + 1).join(' ')
// apply border and padding to string.
padding = row[c].padding || [0, 0, 0, 0]
if (padding[left]) str += new Array(padding[left] + 1).join(' ')
str += addBorder(row[c], ts, '| ')
str += ts
if (row[c].padding && row[c].padding[right]) str += new Array(row[c].padding[right] + 1).join(' ')
str += addBorder(row[c], ts, ' |')
if (padding[right]) str += new Array(padding[right] + 1).join(' ')
// if prior row is span, try to render the
// current row on the prior line.
if (r === 0 && lines.length > 0) {
str = _this._renderInline(str, lines[lines.length - 1], paddingLeft)
str = _this._renderInline(str, lines[lines.length - 1])
}
})
@@ -152,11 +164,21 @@ UI.prototype.rowToString = function (row, lines) {
return lines
}
function addBorder (col, ts, style) {
if (col.border) {
if (/[.']-+[.']/.test(ts)) return ''
else if (ts.trim().length) return style
else return ' '
}
return ''
}
// if the full 'source' can render in
// the target line, do so.
UI.prototype._renderInline = function (source, previousLine, paddingLeft) {
var target = previousLine.text,
str = ''
UI.prototype._renderInline = function (source, previousLine) {
var leadingWhitespace = source.match(/^ */)[0].length
var target = previousLine.text
var targetTextWidth = stringWidth(target.trimRight())
if (!previousLine.span) return source
@@ -167,39 +189,34 @@ UI.prototype._renderInline = function (source, previousLine, paddingLeft) {
return target + source
}
for (var i = 0, tc, sc; i < Math.max(source.length, target.length); i++) {
tc = target.charAt(i) || ' '
sc = source.charAt(i) || ' '
// we tried to overwrite a character in the other string.
if (tc !== ' ' && sc !== ' ') return source
// there is not enough whitespace to maintain padding.
if (sc !== ' ' && i < paddingLeft + target.length) return source
// :thumbsup:
if (tc === ' ') str += sc
else str += tc
}
if (leadingWhitespace < targetTextWidth) return source
previousLine.hidden = true
return str
return target.trimRight() + new Array(leadingWhitespace - targetTextWidth + 1).join(' ') + source.trimLeft()
}
UI.prototype._rasterize = function (row) {
var _this = this,
i,
rrow,
rrows = [],
widths = this._columnWidths(row),
wrapped
var _this = this
var i
var rrow
var rrows = []
var widths = this._columnWidths(row)
var wrapped
// word wrap all columns, and create
// a data-structure that is easy to rasterize.
row.forEach(function (col, c) {
// leave room for left and right padding.
col.width = widths[c]
if (_this.wrap) wrapped = wrap.hard(_this._negatePadding(col))(col.text).split('\n')
if (_this.wrap) wrapped = wrap(col.text, _this._negatePadding(col), {hard: true}).split('\n')
else wrapped = col.text.split('\n')
if (col.border) {
wrapped.unshift('.' + new Array(_this._negatePadding(col) + 3).join('-') + '.')
wrapped.push("'" + new Array(_this._negatePadding(col) + 3).join('-') + "'")
}
// add top and bottom padding.
if (col.padding) {
for (i = 0; i < (col.padding[top] || 0); i++) wrapped.unshift('')
@@ -224,15 +241,16 @@ UI.prototype._rasterize = function (row) {
UI.prototype._negatePadding = function (col) {
var wrapWidth = col.width
if (col.padding) wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0)
if (col.border) wrapWidth -= 4
return wrapWidth
}
UI.prototype._columnWidths = function (row) {
var _this = this,
widths = [],
unset = row.length,
unsetWidth,
remainingWidth = this.width
var _this = this
var widths = []
var unset = row.length
var unsetWidth
var remainingWidth = this.width
// column widths can be set in config.
row.forEach(function (col, i) {
@@ -248,7 +266,7 @@ UI.prototype._columnWidths = function (row) {
// any unset widths should be calculated.
if (unset) unsetWidth = Math.floor(remainingWidth / unset)
widths.forEach(function (w, i) {
if (!_this.wrap) widths[i] = row[i].width || row[i].text.length
if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text)
else if (w === undefined) widths[i] = Math.max(unsetWidth, _minWidth(row[i]))
})
@@ -259,8 +277,33 @@ UI.prototype._columnWidths = function (row) {
// a column, based on padding preferences.
function _minWidth (col) {
var padding = col.padding || []
var minWidth = 1 + (padding[left] || 0) + (padding[right] || 0)
if (col.border) minWidth += 4
return minWidth
}
return 1 + (padding[left] || 0) + (padding[right] || 0)
function alignRight (str, width) {
str = str.trim()
var padding = ''
var strWidth = stringWidth(str)
if (strWidth < width) {
padding = new Array(width - strWidth + 1).join(' ')
}
return padding + str
}
function alignCenter (str, width) {
str = str.trim()
var padding = ''
var strWidth = stringWidth(str.trim())
if (strWidth < width) {
padding = new Array(parseInt((width - strWidth) / 2, 10) + 1).join(' ')
}
return padding + str
}
module.exports = function (opts) {

View File

@@ -0,0 +1,37 @@
'use strict';
var stripAnsi = require('strip-ansi');
var codePointAt = require('code-point-at');
var isFullwidthCodePoint = require('is-fullwidth-code-point');
// https://github.com/nodejs/io.js/blob/cff7300a578be1b10001f2d967aaedc88aee6402/lib/readline.js#L1345
module.exports = function (str) {
if (typeof str !== 'string' || str.length === 0) {
return 0;
}
var width = 0;
str = stripAnsi(str);
for (var i = 0; i < str.length; i++) {
var code = codePointAt(str, i);
// ignore control characters
if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) {
continue;
}
// surrogates
if (code >= 0x10000) {
i++;
}
if (isFullwidthCodePoint(code)) {
width += 2;
} else {
width++;
}
}
return width;
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,91 @@
{
"_args": [
[
"string-width@1.0.2",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI"
]
],
"_from": "string-width@1.0.2",
"_id": "string-width@1.0.2",
"_inBundle": false,
"_integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"_location": "/webpack/cliui/string-width",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "string-width@1.0.2",
"name": "string-width",
"escapedName": "string-width",
"rawSpec": "1.0.2",
"saveSpec": null,
"fetchSpec": "1.0.2"
},
"_requiredBy": [
"/webpack/cliui"
],
"_resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"_spec": "1.0.2",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/string-width/issues"
},
"dependencies": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
},
"description": "Get the visual width of a string - the number of columns required to display it",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/string-width#readme",
"keywords": [
"string",
"str",
"character",
"char",
"unicode",
"width",
"visual",
"column",
"columns",
"fullwidth",
"full-width",
"full",
"ansi",
"escape",
"codes",
"cli",
"command-line",
"terminal",
"console",
"cjk",
"chinese",
"japanese",
"korean",
"fixed-width"
],
"license": "MIT",
"name": "string-width",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/string-width.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "1.0.2"
}

View File

@@ -0,0 +1,42 @@
# string-width [![Build Status](https://travis-ci.org/sindresorhus/string-width.svg?branch=master)](https://travis-ci.org/sindresorhus/string-width)
> Get the visual width of a string - the number of columns required to display it
Some Unicode characters are [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) and use double the normal width. [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) are stripped and doesn't affect the width.
Useful to be able to measure the actual width of command-line output.
## Install
```
$ npm install --save string-width
```
## Usage
```js
const stringWidth = require('string-width');
stringWidth('古');
//=> 2
stringWidth('\u001b[1m古\u001b[22m');
//=> 2
stringWidth('a');
//=> 1
```
## Related
- [string-width-cli](https://github.com/sindresorhus/string-width-cli) - CLI for this module
- [string-length](https://github.com/sindresorhus/string-length) - Get the real length of a string
- [widest-line](https://github.com/sindresorhus/widest-line) - Get the visual width of the widest line in a string
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -1,38 +1,40 @@
{
"_args": [
[
"cliui@2.1.0",
"cliui@3.2.0",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI"
]
],
"_from": "cliui@2.1.0",
"_id": "cliui@2.1.0",
"_from": "cliui@3.2.0",
"_id": "cliui@3.2.0",
"_inBundle": false,
"_integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
"_integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"_location": "/webpack/cliui",
"_phantomChildren": {},
"_phantomChildren": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
},
"_requested": {
"type": "version",
"registry": true,
"raw": "cliui@2.1.0",
"raw": "cliui@3.2.0",
"name": "cliui",
"escapedName": "cliui",
"rawSpec": "2.1.0",
"rawSpec": "3.2.0",
"saveSpec": null,
"fetchSpec": "2.1.0"
"fetchSpec": "3.2.0"
},
"_requiredBy": [
"/webpack/uglify-js/yargs"
],
"_resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
"_spec": "2.1.0",
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"_spec": "3.2.0",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",
"author": {
"name": "Ben Coe",
"email": "ben@npmjs.com"
},
"bugs": {
"url": "https://github.com/bcoe/cliui/issues"
"url": "https://github.com/yargs/cliui/issues"
},
"config": {
"blanket": {
@@ -47,22 +49,24 @@
}
},
"dependencies": {
"center-align": "^0.1.1",
"right-align": "^0.1.1",
"wordwrap": "0.0.2"
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wrap-ansi": "^2.0.0"
},
"description": "easily create complex multi-column command-line-interfaces",
"devDependencies": {
"blanket": "^1.1.6",
"chai": "^2.2.0",
"coveralls": "^2.11.2",
"mocha": "^2.2.4",
"mocha-lcov-reporter": "0.0.2",
"mocoverage": "^1.0.0",
"patched-blanket": "^1.0.1",
"standard": "^3.6.1"
"chai": "^3.5.0",
"chalk": "^1.1.2",
"coveralls": "^2.11.8",
"mocha": "^2.4.5",
"nyc": "^6.4.0",
"standard": "^6.0.8",
"standard-version": "^2.1.2"
},
"homepage": "https://github.com/bcoe/cliui#readme",
"files": [
"index.js"
],
"homepage": "https://github.com/yargs/cliui#readme",
"keywords": [
"cli",
"command-line",
@@ -77,10 +81,13 @@
"name": "cliui",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/bcoe/cliui.git"
"url": "git+ssh://git@github.com/yargs/cliui.git"
},
"scripts": {
"test": "standard && mocha --check-leaks --ui exports --require patched-blanket -R mocoverage"
"coverage": "nyc --reporter=text-lcov mocha | coveralls",
"pretest": "standard",
"test": "nyc mocha",
"version": "standard-version"
},
"standard": {
"ignore": [
@@ -90,5 +97,5 @@
"it"
]
},
"version": "2.1.0"
"version": "3.2.0"
}

View File

@@ -1,349 +0,0 @@
/* global describe, it */
require('chai').should()
var cliui = require('../')
describe('cliui', function () {
describe('div', function () {
it("wraps text at 'width' if a single column is given", function () {
var ui = cliui({
width: 10
})
ui.div('i am a string that should be wrapped')
ui.toString().split('\n').forEach(function (row) {
row.length.should.be.lte(10)
})
})
it('evenly divides text across columns if multiple columns are given', function () {
var ui = cliui({
width: 40
})
ui.div(
{text: 'i am a string that should be wrapped', width: 15},
'i am a second string that should be wrapped',
'i am a third string that should be wrapped'
)
// total width of all columns is <=
// the width cliui is initialized with.
ui.toString().split('\n').forEach(function (row) {
row.length.should.be.lte(40)
})
// it should wrap each column appropriately.
var expected = [
'i am a string i am a i am a third',
'that should be second string that',
'wrapped string that should be',
' should be wrapped',
' wrapped'
]
ui.toString().split('\n').should.eql(expected)
})
it('allows for a blank row to be appended', function () {
var ui = cliui({
width: 40
})
ui.div()
// it should wrap each column appropriately.
var expected = ['']
ui.toString().split('\n').should.eql(expected)
})
})
describe('_columnWidths', function () {
it('uses same width for each column by default', function () {
var ui = cliui({
width: 40
}),
widths = ui._columnWidths([{}, {}, {}])
widths[0].should.equal(13)
widths[1].should.equal(13)
widths[2].should.equal(13)
})
it('divides width over remaining columns if first column has width specified', function () {
var ui = cliui({
width: 40
}),
widths = ui._columnWidths([{width: 20}, {}, {}])
widths[0].should.equal(20)
widths[1].should.equal(10)
widths[2].should.equal(10)
})
it('divides width over remaining columns if middle column has width specified', function () {
var ui = cliui({
width: 40
}),
widths = ui._columnWidths([{}, {width: 10}, {}])
widths[0].should.equal(15)
widths[1].should.equal(10)
widths[2].should.equal(15)
})
it('keeps track of remaining width if multiple columns have width specified', function () {
var ui = cliui({
width: 40
}),
widths = ui._columnWidths([{width: 20}, {width: 12}, {}])
widths[0].should.equal(20)
widths[1].should.equal(12)
widths[2].should.equal(8)
})
it('uses a sane default if impossible widths are specified', function () {
var ui = cliui({
width: 40
}),
widths = ui._columnWidths([{width: 30}, {width: 30}, {padding: [0, 2, 0, 1]}])
widths[0].should.equal(30)
widths[1].should.equal(30)
widths[2].should.equal(4)
})
})
describe('alignment', function () {
it('allows a column to be right aligned', function () {
var ui = cliui({
width: 40
})
ui.div(
'i am a string',
{text: 'i am a second string', align: 'right'},
'i am a third string that should be wrapped'
)
// it should right-align the second column.
var expected = [
'i am a stringi am a secondi am a third',
' stringstring that',
' should be',
' wrapped'
]
ui.toString().split('\n').should.eql(expected)
})
it('allows a column to be center aligned', function () {
var ui = cliui({
width: 60
})
ui.div(
'i am a string',
{text: 'i am a second string', align: 'center', padding: [0, 2, 0, 2]},
'i am a third string that should be wrapped'
)
// it should right-align the second column.
var expected = [
'i am a string i am a second i am a third string',
' string that should be',
' wrapped'
]
ui.toString().split('\n').should.eql(expected)
})
})
describe('padding', function () {
it('handles left/right padding', function () {
var ui = cliui({
width: 40
})
ui.div(
{text: 'i have padding on my left', padding: [0, 0, 0, 4]},
{text: 'i have padding on my right', padding: [0, 2, 0, 0], align: 'center'},
{text: 'i have no padding', padding: [0, 0, 0, 0]}
)
// it should add left/right padding to columns.
var expected = [
' i have i have i have no',
' padding padding on padding',
' on my my right',
' left'
]
ui.toString().split('\n').should.eql(expected)
})
it('handles top/bottom padding', function () {
var ui = cliui({
width: 40
})
ui.div(
'i am a string',
{text: 'i am a second string', padding: [2, 0, 0, 0]},
{text: 'i am a third string that should be wrapped', padding: [0, 0, 1, 0]}
)
// it should add top/bottom padding to second
// and third columns.
var expected = [
'i am a string i am a third',
' string that',
' i am a secondshould be',
' string wrapped',
''
]
ui.toString().split('\n').should.eql(expected)
})
})
describe('wrap', function () {
it('allows wordwrap to be disabled', function () {
var ui = cliui({
wrap: false
})
ui.div(
{text: 'i am a string', padding: [0, 1, 0, 0]},
{text: 'i am a second string', padding: [0, 2, 0, 0]},
{text: 'i am a third string that should not be wrapped', padding: [0, 0, 0, 2]}
)
ui.toString().should.equal('i am a string i am a second string i am a third string that should not be wrapped')
})
})
describe('span', function () {
it('appends the next row to the end of the prior row if it fits', function () {
var ui = cliui({
width: 40
})
ui.span(
{text: 'i am a string that will be wrapped', width: 30}
)
ui.div(
{text: ' [required] [default: 99]', align: 'right'}
)
var expected = [
'i am a string that will be',
'wrapped [required] [default: 99]'
]
ui.toString().split('\n').should.eql(expected)
})
it('does not append the string if it does not fit on the prior row', function () {
var ui = cliui({
width: 40
})
ui.span(
{text: 'i am a string that will be wrapped', width: 30}
)
ui.div(
{text: 'i am a second row', align: 'left'}
)
var expected = [
'i am a string that will be',
'wrapped',
'i am a second row'
]
ui.toString().split('\n').should.eql(expected)
})
it('always appends text to prior span if wrap is disabled', function () {
var ui = cliui({
wrap: false,
width: 40
})
ui.span(
{text: 'i am a string that will be wrapped', width: 30}
)
ui.div(
{text: 'i am a second row', align: 'left', padding: [0, 0, 0, 3]}
)
ui.div('a third line')
var expected = [
'i am a string that will be wrapped i am a second row',
'a third line'
]
ui.toString().split('\n').should.eql(expected)
})
})
describe('layoutDSL', function () {
it('turns tab into multiple columns', function () {
var ui = cliui({
width: 60
})
ui.div(
' <regex> \tmy awesome regex\n <my second thing> \tanother row\t a third column'
)
var expected = [
' <regex> my awesome regex',
' <my second thing> another row a third column'
]
ui.toString().split('\n').should.eql(expected)
})
it('turns newline into multiple rows', function () {
var ui = cliui({
width: 40
})
ui.div(
'Usage: $0\n <regex>\t my awesome regex\n <glob>\t my awesome glob\t [required]'
)
var expected = [
'Usage: $0',
' <regex> my awesome regex',
' <glob> my awesome [required]',
' glob'
]
ui.toString().split('\n').should.eql(expected)
})
it('does not apply DSL if wrap is false', function () {
var ui = cliui({
width: 40,
wrap: false
})
ui.div(
'Usage: $0\ttwo\tthree'
)
ui.toString().should.eql('Usage: $0\ttwo\tthree')
})
})
})

View File

@@ -22,6 +22,7 @@
"fetchSpec": "1.1.0"
},
"_requiredBy": [
"/webpack/cliui/string-width",
"/webpack/wrap-ansi/string-width",
"/webpack/yargs/cliui/string-width"
],

View File

@@ -22,6 +22,7 @@
"fetchSpec": "1.0.0"
},
"_requiredBy": [
"/webpack/cliui/string-width",
"/webpack/wrap-ansi/string-width",
"/webpack/yargs/cliui/string-width"
],

View File

@@ -21,9 +21,7 @@
"saveSpec": null,
"fetchSpec": "0.1.3"
},
"_requiredBy": [
"/webpack/cliui"
],
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
"_spec": "0.1.3",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",

View File

@@ -22,6 +22,8 @@
"fetchSpec": "3.0.1"
},
"_requiredBy": [
"/webpack/cliui",
"/webpack/cliui/string-width",
"/webpack/wrap-ansi",
"/webpack/wrap-ansi/string-width",
"/webpack/yargs/cliui",

View File

@@ -11,8 +11,6 @@
"_integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
"_location": "/webpack/uglify-js",
"_phantomChildren": {
"camelcase": "1.2.1",
"cliui": "2.1.0",
"decamelize": "1.2.0",
"window-size": "0.1.0"
},

View File

@@ -21,9 +21,7 @@
"saveSpec": null,
"fetchSpec": "0.0.2"
},
"_requiredBy": [
"/webpack/cliui"
],
"_requiredBy": [],
"_resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
"_spec": "0.0.2",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\goTorrentWebUI",

View File

@@ -26,6 +26,7 @@
"fetchSpec": "2.1.0"
},
"_requiredBy": [
"/webpack/cliui",
"/webpack/yargs/cliui"
],
"_resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",