| "use strict" |
| |
| var wcwidth = require('./width') |
| |
| /** |
| * repeat string `str` up to total length of `len` |
| * |
| * @param String str string to repeat |
| * @param Number len total length of output string |
| */ |
| |
| function repeatString(str, len) { |
| return Array.apply(null, {length: len + 1}).join(str).slice(0, len) |
| } |
| |
| /** |
| * Pad `str` up to total length `max` with `chr`. |
| * If `str` is longer than `max`, padRight will return `str` unaltered. |
| * |
| * @param String str string to pad |
| * @param Number max total length of output string |
| * @param String chr optional. Character to pad with. default: ' ' |
| * @return String padded str |
| */ |
| |
| function padRight(str, max, chr) { |
| str = str != null ? str : '' |
| str = String(str) |
| var length = max - wcwidth(str) |
| if (length <= 0) return str |
| return str + repeatString(chr || ' ', length) |
| } |
| |
| /** |
| * Pad `str` up to total length `max` with `chr`. |
| * If `str` is longer than `max`, padCenter will return `str` unaltered. |
| * |
| * @param String str string to pad |
| * @param Number max total length of output string |
| * @param String chr optional. Character to pad with. default: ' ' |
| * @return String padded str |
| */ |
| |
| function padCenter(str, max, chr) { |
| str = str != null ? str : '' |
| str = String(str) |
| var length = max - wcwidth(str) |
| if (length <= 0) return str |
| var lengthLeft = Math.floor(length/2) |
| var lengthRight = length - lengthLeft |
| return repeatString(chr || ' ', lengthLeft) + str + repeatString(chr || ' ', lengthRight) |
| } |
| |
| /** |
| * Pad `str` up to total length `max` with `chr`, on the left. |
| * If `str` is longer than `max`, padRight will return `str` unaltered. |
| * |
| * @param String str string to pad |
| * @param Number max total length of output string |
| * @param String chr optional. Character to pad with. default: ' ' |
| * @return String padded str |
| */ |
| |
| function padLeft(str, max, chr) { |
| str = str != null ? str : '' |
| str = String(str) |
| var length = max - wcwidth(str) |
| if (length <= 0) return str |
| return repeatString(chr || ' ', length) + str |
| } |
| |
| /** |
| * Split a String `str` into lines of maxiumum length `max`. |
| * Splits on word boundaries. Preserves existing new lines. |
| * |
| * @param String str string to split |
| * @param Number max length of each line |
| * @return Array Array containing lines. |
| */ |
| |
| function splitIntoLines(str, max) { |
| function _splitIntoLines(str, max) { |
| return str.trim().split(' ').reduce(function(lines, word) { |
| var line = lines[lines.length - 1] |
| if (line && wcwidth(line.join(' ')) + wcwidth(word) < max) { |
| lines[lines.length - 1].push(word) // add to line |
| } |
| else lines.push([word]) // new line |
| return lines |
| }, []).map(function(l) { |
| return l.join(' ') |
| }) |
| } |
| return str.split('\n').map(function(str) { |
| return _splitIntoLines(str, max) |
| }).reduce(function(lines, line) { |
| return lines.concat(line) |
| }, []) |
| } |
| |
| /** |
| * Add spaces and `truncationChar` between words of |
| * `str` which are longer than `max`. |
| * |
| * @param String str string to split |
| * @param Number max length of each line |
| * @param Number truncationChar character to append to split words |
| * @return String |
| */ |
| |
| function splitLongWords(str, max, truncationChar) { |
| str = str.trim() |
| var result = [] |
| var words = str.split(' ') |
| var remainder = '' |
| |
| var truncationWidth = wcwidth(truncationChar) |
| |
| while (remainder || words.length) { |
| if (remainder) { |
| var word = remainder |
| remainder = '' |
| } else { |
| var word = words.shift() |
| } |
| |
| if (wcwidth(word) > max) { |
| // slice is based on length no wcwidth |
| var i = 0 |
| var wwidth = 0 |
| var limit = max - truncationWidth |
| while (i < word.length) { |
| var w = wcwidth(word.charAt(i)) |
| if (w + wwidth > limit) { |
| break |
| } |
| wwidth += w |
| ++i |
| } |
| |
| remainder = word.slice(i) // get remainder |
| // save remainder for next loop |
| |
| word = word.slice(0, i) // grab truncated word |
| word += truncationChar // add trailing … or whatever |
| } |
| result.push(word) |
| } |
| |
| return result.join(' ') |
| } |
| |
| |
| /** |
| * Truncate `str` into total width `max` |
| * If `str` is shorter than `max`, will return `str` unaltered. |
| * |
| * @param String str string to truncated |
| * @param Number max total wcwidth of output string |
| * @return String truncated str |
| */ |
| |
| function truncateString(str, max) { |
| |
| str = str != null ? str : '' |
| str = String(str) |
| |
| if(max == Infinity) return str |
| |
| var i = 0 |
| var wwidth = 0 |
| while (i < str.length) { |
| var w = wcwidth(str.charAt(i)) |
| if(w + wwidth > max) |
| break |
| wwidth += w |
| ++i |
| } |
| return str.slice(0, i) |
| } |
| |
| |
| |
| /** |
| * Exports |
| */ |
| |
| module.exports.padRight = padRight |
| module.exports.padCenter = padCenter |
| module.exports.padLeft = padLeft |
| module.exports.splitIntoLines = splitIntoLines |
| module.exports.splitLongWords = splitLongWords |
| module.exports.truncateString = truncateString |