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