Skip to content

Commit

Permalink
Wrapping text - fixed alignment and added examples
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszmn committed Mar 31, 2020
1 parent 33269ab commit e3ac2d7
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 3 deletions.
10 changes: 10 additions & 0 deletions example.js
Expand Up @@ -44,3 +44,13 @@ console.log('\n\n' + boxen(chalk.black('unicorn'), {
vertical: '|'
}
}) + '\n');

const sentences = 'Unbreakable_text_because_it_has_no_spaces '.repeat(5);
console.log('\n\n' + boxen(sentences, {align: 'left'}) + '\n');

console.log('\n\n' + boxen(sentences, {align: 'center'}) + '\n');

console.log('\n\n' + boxen(sentences, {align: 'right', padding: {left: 1, right: 1, top: 0, bottom: 0}}) + '\n');

const longWord = 'x'.repeat(process.stdout.columns + 20);
console.log('\n\n' + boxen(longWord, {align: 'center'}) + '\n');
22 changes: 19 additions & 3 deletions index.js
Expand Up @@ -114,9 +114,25 @@ module.exports = (text, options) => {
for (const line of lines) {
const createdLines = wrapAnsi(line, max, {hard: true});
const alignedLines = ansiAlign(createdLines, {align: options.align});
newLines.push(
...alignedLines.split('\n')
);
const alignedLinesArr = alignedLines.split('\n');
const longestLength = Math.max(...alignedLinesArr.map(s => s.length));

for (const alignedLine of alignedLinesArr) {
let paddedLine;
switch (options.align) {
case 'center':
paddedLine = PAD.repeat((max - longestLength) / 2) + alignedLine;
break;
case 'right':
paddedLine = PAD.repeat(max - longestLength) + alignedLine;
break;
default:
paddedLine = alignedLine;
break;
}

newLines.push(paddedLine);
}
}

lines = newLines;
Expand Down
128 changes: 128 additions & 0 deletions test.js
Expand Up @@ -496,3 +496,131 @@ test('text is right-aligned after wrapping', t => {
const expected = '│' + ' '.repeat(padding) + 'x│';
t.is(lines[2], expected);
});

test('text is centered after wrapping when using words', t => {
const width = process.stdout.columns || 120;
const sentence = 'x'.repeat(width / 3) + ' ';
const longContent = sentence.repeat(3).trim();
const box = boxen(longContent, {align: 'center'});

t.is(box.length, width * 4);

const lines = [];
for (let index = 0; index < 4; ++index) {
const line = box.slice(index * width, (index + 1) * width);
t.is(line.length, width, 'Length of line #' + index);
t.is(line, line.trim(), 'No margin of line #' + index);

lines.push(line);
}

const checkAlign = index => {
const line = lines[index];
const lineWithoutBorders = line.slice(1, line.length - 1);
const paddingLeft = lineWithoutBorders.length - lineWithoutBorders.trimStart().length;
const paddingRight = lineWithoutBorders.length - lineWithoutBorders.trimEnd().length;

t.true(paddingLeft > 0, 'Padding left in line #' + index);
t.true(paddingRight > 0, 'Padding right in line #' + index);
t.true(Math.abs(paddingLeft - paddingRight) <= 1, 'Left and right padding are not (almost) equal in line #' + index);
};

checkAlign(1);
checkAlign(2);
});

test('text is left-aligned after wrapping when using words', t => {
const width = process.stdout.columns || 120;
const sentence = 'x'.repeat(width / 3) + ' ';
const longContent = sentence.repeat(3).trim();
const box = boxen(longContent, {align: 'left'});

t.is(box.length, width * 4);

const lines = [];
for (let index = 0; index < 4; ++index) {
const line = box.slice(index * width, (index + 1) * width);
t.is(line.length, width, 'Length of line #' + index);
t.is(line, line.trim(), 'No margin of line #' + index);

lines.push(line);
}

const checkAlign = index => {
const line = lines[index];
const lineWithoutBorders = line.slice(1, line.length - 1);
const paddingLeft = lineWithoutBorders.length - lineWithoutBorders.trimStart().length;
const paddingRight = lineWithoutBorders.length - lineWithoutBorders.trimEnd().length;

t.is(paddingLeft, 0, 'Padding left in line #' + index);
t.true(paddingRight > 0, 'Padding right in line #' + index);
};

checkAlign(1);
checkAlign(2);
});

test('text is right-aligned after wrapping when using words', t => {
const width = process.stdout.columns || 120;
const sentence = 'x'.repeat(width / 3) + ' ';
const longContent = sentence.repeat(3).trim();
const box = boxen(longContent, {align: 'right'});

t.is(box.length, width * 4);

const lines = [];
for (let index = 0; index < 4; ++index) {
const line = box.slice(index * width, (index + 1) * width);
t.is(line.length, width, 'Length of line #' + index);
t.is(line, line.trim(), 'No margin of line #' + index);

lines.push(line);
}

const checkAlign = index => {
const line = lines[index];
const lineWithoutBorders = line.slice(1, line.length - 1);
const paddingLeft = lineWithoutBorders.length - lineWithoutBorders.trimStart().length;
const paddingRight = lineWithoutBorders.length - lineWithoutBorders.trimEnd().length;

t.true(paddingLeft > 0, 'Padding left in line #' + index);
t.is(paddingRight, 0, 'Padding right in line #' + index);
};

checkAlign(1);
checkAlign(2);
});

test('text is right-aligned after wrapping when using words, with padding', t => {
const width = process.stdout.columns || 120;
const sentence = 'x'.repeat(width / 3) + ' ';
const longContent = sentence.repeat(3).trim();
const box = boxen(longContent, {
align: 'right',
padding: {left: 1, right: 1, top: 0, bottom: 0}
});

t.is(box.length, width * 4);

const lines = [];
for (let index = 0; index < 4; ++index) {
const line = box.slice(index * width, (index + 1) * width);
t.is(line.length, width, 'Length of line #' + index);
t.is(line, line.trim(), 'No margin of line #' + index);

lines.push(line);
}

const checkAlign = index => {
const line = lines[index];
const lineWithoutBorders = line.slice(1, line.length - 1);
const paddingLeft = lineWithoutBorders.length - lineWithoutBorders.trimStart().length;
const paddingRight = lineWithoutBorders.length - lineWithoutBorders.trimEnd().length;

t.true(paddingLeft > 0, 'Padding left in line #' + index);
t.is(paddingRight, 1, 'Padding right in line #' + index);
};

checkAlign(1);
checkAlign(2);
});

0 comments on commit e3ac2d7

Please sign in to comment.