columnify icon indicating copy to clipboard operation
columnify copied to clipboard

Wrapping doesn't take into account ansi color sequences.

Open muffinresearch opened this issue 9 years ago • 6 comments

If the text that's being wrapped has ansi color codes the colors bleed into the other columns because the colorized string is split when it's wrapped and as a result the color codes are wrapping more than the intended text when the output lines are assembled.

Here's a test case (using chalk for the ansi colours):

var columnify = require('columnify');
var chalk = require('chalk');

var data = [
  { foo: chalk.red('This is a red string that will be wrapped'),
    bar: 'This is just a normal string which should not have colorized output', },
  { foo: 'This is a normal string that will be wrapped',
    bar: 'This is just a normal string which should not have colorized output', }
];

console.log(columnify(data, {
  columns: ['foo', 'bar'],
  config: {
    foo: {
      maxWidth: 20,
    },
  }
}));

Here's the output:

Test case output

muffinresearch avatar Oct 07 '15 16:10 muffinresearch

Related to https://github.com/timoxley/columnify/issues/17

danyshaanan avatar Oct 07 '15 21:10 danyshaanan

@muffinresearch I think that you've demonstrated well that in order to fix this, some ansi-color-parser should be used, as this will require to figure out the style of each part, and to be able to re-apply it on wrapped parts of the text. (It makes me think of the complexity of html rich text editors).

Another possible solution would be to enable passing chalk or chalk-like function to be used on the text after the wrapping, but since this was "Designed to handle sensible wrapping in npm search results.", I'm unsure as to what non-trivial features would be added if not to serve the that intended purpose, so we'll have to wait for Tim's take on this to be sure.

danyshaanan avatar Oct 07 '15 21:10 danyshaanan

fwiw and in-case it's useful for inspiration - there's wrap-ansi [1] that performs a similar operation in terms of splitting strings for wrapping and and handling ansi escape codes.

[1] https://github.com/chalk/wrap-ansi

muffinresearch avatar Oct 08 '15 06:10 muffinresearch

Yes, this might make it pretty simple, and could also be used to fix #17.

danyshaanan avatar Oct 08 '15 06:10 danyshaanan

A partial work-around suggestion for anyone who ends up here: truncate your strings before passing them to columnify() and before passing them to any coloring functions like chalk.green(). Note that this does not help wrapping; only truncation. For example:

const truncateString = (string, len) => (string.length <= len) ? string : string.substr(0, len - 1)+'…';
const data = {
	date: chalk.bold.yellow(date),
	repo: chalk.green(truncateString(repo, 25)),
	title: truncateString(title, 50),
};
console.log(columnify(data));
}

sirbrillig avatar May 12 '17 22:05 sirbrillig

const columnify = require('columnify');
const chalk = require('chalk');

const data = [
  {
     name: 'some name',
     value: 'some value'
  },{
     name: 'another name',
     value: 'another value'
  }
];
console.log(columnify(data,  {
    headingTransform: function(header){
        return chalk.red(header.charAt(0).toUpperCase + header.slice(1).toLowerCase());
    },
    dataTransform: function(data){
      return chalk.white(data);
   }
}));

xochilpili avatar Feb 27 '19 19:02 xochilpili