• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# columnify
2
3[![NPM](https://nodei.co/npm/columnify.png?downloads=true&downloadRank=true&stars=true&chrome)](https://nodei.co/npm-dl/columnify/)
4[![NPM](https://nodei.co/npm-dl/columnify.png?months=3&height=3&chrome)](https://nodei.co/npm/columnify/)
5
6[![Build Status](https://img.shields.io/travis/timoxley/columnify.svg?style=flat)](https://travis-ci.org/timoxley/columnify)
7[![NPM Version](https://img.shields.io/npm/v/columnify.svg?style=flat)](https://npmjs.org/package/columnify)
8[![License](http://img.shields.io/npm/l/columnify.svg?style=flat)](LICENSE)
9[![Dependency Status](https://david-dm.org/timoxley/columnify.svg)](https://david-dm.org/timoxley/columnify)
10[![devDependency Status](https://david-dm.org/timoxley/columnify/dev-status.svg)](https://david-dm.org/timoxley/columnify#info=devDependencies)
11
12Create text-based columns suitable for console output from objects or
13arrays of objects.
14
15Columns are automatically resized to fit the content of the largest
16cell. Each cell will be padded with spaces to fill the available space
17and ensure column contents are left-aligned.
18
19Designed to [handle sensible wrapping in npm search results](https://github.com/isaacs/npm/pull/2328).
20
21`npm search` before & after integrating columnify:
22
23![npm-tidy-search](https://f.cloud.github.com/assets/43438/1848959/ae02ad04-76a1-11e3-8255-4781debffc26.gif)
24
25## Installation & Update
26
27```
28$ npm install --save columnify@latest
29```
30
31## Usage
32
33```javascript
34var columnify = require('columnify')
35var columns = columnify(data, options)
36console.log(columns)
37```
38
39## Examples
40
41### Columnify Objects
42
43Objects are converted to a list of key/value pairs:
44
45```javascript
46var data = {
47  "commander@0.6.1": 1,
48  "minimatch@0.2.14": 3,
49  "mkdirp@0.3.5": 2,
50  "sigmund@1.0.0": 3
51}
52
53console.log(columnify(data))
54```
55#### Output:
56```
57KEY               VALUE
58commander@0.6.1   1
59minimatch@0.2.14  3
60mkdirp@0.3.5      2
61sigmund@1.0.0     3
62```
63
64### Custom Column Names
65
66```javascript
67var data = {
68  "commander@0.6.1": 1,
69  "minimatch@0.2.14": 3,
70  "mkdirp@0.3.5": 2,
71  "sigmund@1.0.0": 3
72}
73
74console.log(columnify(data, {columns: ['MODULE', 'COUNT']}))
75```
76#### Output:
77```
78MODULE            COUNT
79commander@0.6.1   1
80minimatch@0.2.14  3
81mkdirp@0.3.5      2
82sigmund@1.0.0     3
83```
84
85### Columnify Arrays of Objects
86
87Column headings are extracted from the keys in supplied objects.
88
89```javascript
90var columnify = require('columnify')
91
92var columns = columnify([{
93  name: 'mod1',
94  version: '0.0.1'
95}, {
96  name: 'module2',
97  version: '0.2.0'
98}])
99
100console.log(columns)
101```
102#### Output:
103```
104NAME    VERSION
105mod1    0.0.1
106module2 0.2.0
107```
108
109### Filtering & Ordering Columns
110
111By default, all properties are converted into columns, whether or not
112they exist on every object or not.
113
114To explicitly specify which columns to include, and in which order,
115supply a "columns" or "include" array ("include" is just an alias).
116
117```javascript
118var data = [{
119  name: 'module1',
120  description: 'some description',
121  version: '0.0.1',
122}, {
123  name: 'module2',
124  description: 'another description',
125  version: '0.2.0',
126}]
127
128var columns = columnify(data, {
129  columns: ['name', 'version']
130})
131
132console.log(columns)
133```
134
135#### Output:
136```
137NAME    VERSION
138module1 0.0.1
139module2 0.2.0
140```
141
142## Global and Per Column Options
143You can set a number of options at a global level (ie. for all columns) or on a per column basis.
144
145Set options on a per column basis by using the `config` option to specify individual columns:
146
147```javascript
148var columns = columnify(data, {
149  optionName: optionValue,
150  config: {
151    columnName: {optionName: optionValue},
152    columnName: {optionName: optionValue},
153  }
154})
155```
156
157### Maximum and Minimum Column Widths
158As with all options, you can define the `maxWidth` and `minWidth` globally, or for specified columns. By default, wrapping will happen at word boundaries. Empty cells or those which do not fill the `minWidth` will be padded with spaces.
159
160```javascript
161var columns = columnify([{
162  name: 'mod1',
163  description: 'some description which happens to be far larger than the max',
164  version: '0.0.1',
165}, {
166  name: 'module-two',
167  description: 'another description larger than the max',
168  version: '0.2.0',
169}], {
170  minWidth: 20,
171  config: {
172    description: {maxWidth: 30}
173  }
174})
175
176console.log(columns)
177```
178
179#### Output:
180```
181NAME                 DESCRIPTION                    VERSION
182mod1                 some description which happens 0.0.1
183                     to be far larger than the max
184module-two           another description larger     0.2.0
185                     than the max
186```
187
188#### Maximum Line Width
189
190You can set a hard maximum line width using the `maxLineWidth` option.
191Beyond this value data is unceremoniously truncated with no truncation
192marker.
193
194This can either be a number or 'auto' to set the value to the width of
195stdout.
196
197Setting this value to 'auto' prevent TTY-imposed line-wrapping when
198lines exceed the screen width.
199
200#### Truncating Column Cells Instead of Wrapping
201
202You can disable wrapping and instead truncate content at the maximum
203column width by using the `truncate` option. Truncation respects word boundaries.  A truncation marker, `…`, will appear next to the last word in any truncated line.
204
205```javascript
206var columns = columnify(data, {
207  truncate: true,
208  config: {
209    description: {
210      maxWidth: 20
211    }
212  }
213})
214
215console.log(columns)
216```
217#### Output:
218```
219NAME       DESCRIPTION          VERSION
220mod1       some description…    0.0.1
221module-two another description… 0.2.0
222```
223
224
225### Align Right/Center
226You can set the alignment of the column data by using the `align` option.
227
228```js
229var data = {
230  "mocha@1.18.2": 1,
231  "commander@2.0.0": 1,
232  "debug@0.8.1": 1
233}
234
235columnify(data, {config: {value: {align: 'right'}}})
236```
237
238####  Output:
239```
240KEY                  VALUE
241mocha@1.18.2             1
242commander@2.0.0          1
243debug@0.8.1              1
244```
245
246`align: 'center'` works in a similar way.
247
248
249### Padding Character
250
251Set a character to fill whitespace within columns with the `paddingChr` option.
252
253```js
254var data = {
255  "shortKey": "veryVeryVeryVeryVeryLongVal",
256  "veryVeryVeryVeryVeryLongKey": "shortVal"
257}
258
259columnify(data, { paddingChr: '.'})
260```
261
262####  Output:
263```
264KEY........................ VALUE......................
265shortKey................... veryVeryVeryVeryVeryLongVal
266veryVeryVeryVeryVeryLongKey shortVal...................
267```
268
269### Preserve Existing Newlines
270
271By default, `columnify` sanitises text by replacing any occurance of 1 or more whitespace characters with a single space.
272
273`columnify` can be configured to respect existing new line characters using the `preserveNewLines` option. Note this will still collapse all other whitespace.
274
275```javascript
276var data = [{
277  name: "glob@3.2.9",
278  paths: [
279    "node_modules/tap/node_modules/glob",
280    "node_modules/tape/node_modules/glob"
281  ].join('\n')
282}, {
283  name: "nopt@2.2.1",
284  paths: [
285    "node_modules/tap/node_modules/nopt"
286  ]
287}, {
288  name: "runforcover@0.0.2",
289  paths: "node_modules/tap/node_modules/runforcover"
290}]
291
292console.log(columnify(data, {preserveNewLines: true}))
293```
294#### Output:
295```
296NAME              PATHS
297glob@3.2.9        node_modules/tap/node_modules/glob
298                  node_modules/tape/node_modules/glob
299nopt@2.2.1        node_modules/tap/node_modules/nopt
300runforcover@0.0.2 node_modules/tap/node_modules/runforcover
301```
302
303Compare this with output without `preserveNewLines`:
304
305```javascript
306console.log(columnify(data, {preserveNewLines: false}))
307// or just
308console.log(columnify(data))
309```
310
311```
312NAME              PATHS
313glob@3.2.9        node_modules/tap/node_modules/glob node_modules/tape/node_modules/glob
314nopt@2.2.1        node_modules/tap/node_modules/nopt
315runforcover@0.0.2 node_modules/tap/node_modules/runforcover
316```
317
318### Custom Truncation Marker
319
320You can change the truncation marker to something other than the default
321`…` by using the `truncateMarker` option.
322
323```javascript
324var columns = columnify(data, {
325  truncate: true,
326  truncateMarker: '>',
327  widths: {
328    description: {
329      maxWidth: 20
330    }
331  }
332})
333
334console.log(columns)
335```
336#### Output:
337```
338NAME       DESCRIPTION          VERSION
339mod1       some description>    0.0.1
340module-two another description> 0.2.0
341```
342
343### Custom Column Splitter
344
345If your columns need some bling, you can split columns with custom
346characters by using the `columnSplitter` option.
347
348```javascript
349var columns = columnify(data, {
350  columnSplitter: ' | '
351})
352
353console.log(columns)
354```
355#### Output:
356```
357NAME       | DESCRIPTION                                                  | VERSION
358mod1       | some description which happens to be far larger than the max | 0.0.1
359module-two | another description larger than the max                      | 0.2.0
360```
361
362### Control Header Display
363
364Control whether column headers are displayed by using the `showHeaders` option.
365
366```javascript
367var columns = columnify(data, {
368  showHeaders: false
369})
370```
371
372This also works well for hiding a single column header, like an `id` column:
373```javascript
374var columns = columnify(data, {
375  config: {
376    id: { showHeaders: false }
377  }
378})
379```
380
381### Transforming Column Data and Headers
382If you need to modify the presentation of column content or heading content there are two useful options for doing that: `dataTransform` and `headerTransform`. Both of these take a function and need to return a valid string.
383
384```javascript
385var columns = columnify([{
386    name: 'mod1',
387    description: 'SOME DESCRIPTION TEXT.'
388}, {
389    name: 'module-two',
390    description: 'SOME SLIGHTLY LONGER DESCRIPTION TEXT.'
391}], {
392    dataTransform: function(data) {
393        return data.toLowerCase()
394    },
395    config: {
396        name: {
397            headingTransform: function(heading) {
398              heading = "module " + heading
399              return "*" +  heading.toUpperCase() + "*"
400            }
401        }
402    }
403})
404```
405#### Output:
406```
407*MODULE NAME* DESCRIPTION
408mod1          some description text.
409module-two    some slightly longer description text.
410```
411
412
413## Multibyte Character Support
414
415`columnify` uses [mycoboco/wcwidth.js](https://github.com/mycoboco/wcwidth.js) to calculate length of multibyte characters:
416
417```javascript
418var data = [{
419  name: 'module-one',
420  description: 'some description',
421  version: '0.0.1',
422}, {
423  name: '这是一个很长的名字的模块',
424  description: '这真的是一个描述的内容这个描述很长',
425  version: "0.3.3"
426}]
427
428console.log(columnify(data))
429```
430
431#### Without multibyte handling:
432
433i.e. before columnify added this feature
434
435```
436NAME         DESCRIPTION       VERSION
437module-one   some description  0.0.1
438这是一个很长的名字的模块 这真的是一个描述的内容这个描述很长 0.3.3
439```
440
441#### With multibyte handling:
442
443```
444NAME                     DESCRIPTION                        VERSION
445module-one               some description                   0.0.1
446这是一个很长的名字的模块 这真的是一个描述的内容这个描述很长 0.3.3
447```
448
449## Contributions
450
451```
452 project  : columnify
453 repo age : 1 year, 2 months
454 active   : 32 days
455 commits  : 120
456 files    : 54
457 authors  :
458    90	Tim Oxley           75.0%
459     8	Tim                 6.7%
460     7	Arjun Mehta         5.8%
461     6	Dany                5.0%
462     5	Wei Gao             4.2%
463     2	Dany Shaanan        1.7%
464     1	Seth Miller         0.8%
465     1	Isaac Z. Schlueter  0.8%
466```
467
468## License
469
470MIT
471