Readme.md
1# columnify
2
3[](https://nodei.co/npm-dl/columnify/)
4[](https://nodei.co/npm/columnify/)
5
6[](https://travis-ci.org/timoxley/columnify)
7[](https://npmjs.org/package/columnify)
8[](LICENSE)
9[](https://david-dm.org/timoxley/columnify)
10[](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
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