printable.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*!
  2. * fprint - lib/fprint.js
  3. * Copyright(c) 2012 dead_horse<dead_horse@qq.com>
  4. */
  5. /**
  6. * print [['helloworld', '你好'], ['hello', 'world']] =>
  7. * helloworld 你好
  8. * hello world
  9. * @param {Array} lines source array
  10. * @param {String|Number} string border or length of space border
  11. * @param {Number} max each word max length
  12. * @return {String}
  13. */
  14. exports.print = function(lines, border, max) {
  15. border = border || 3;
  16. var eachMax = max ? [] : _getMax(lines);
  17. var result = [];
  18. if (typeof border === 'number') {
  19. border = _wrapSpace('', border);
  20. }
  21. for (var i = 0, ls = lines.length; i < ls; i++) {
  22. var line = lines[i];
  23. var words = new Array(line.length);
  24. for (var j = 0, l = line.length; j < l; j++) {
  25. words[j] = _wrapSpace(line[j], eachMax[j] || max);
  26. }
  27. result.push(words.join(border));
  28. }
  29. return result.join('\n');
  30. }
  31. /**
  32. * make words have a length of max.
  33. * example:
  34. * ```
  35. * _wrapSpace('hello', 7); // 'hello '
  36. * _wrapSpace('hello', 3); // 'hel'
  37. * ```
  38. * @param {String} word input word
  39. * @param {Number} max max length
  40. * @return {String} ouput word
  41. */
  42. var _wrapSpace = function(word, max) {
  43. if (typeof word !== 'string') {
  44. word = JSON.stringify(word);
  45. }
  46. var length = _getLength(word);
  47. if (length < max) {
  48. for (var i = length; i < max; i++) {
  49. word += ' ';
  50. }
  51. return word;
  52. } else {
  53. return _slice(word, 0, max);
  54. }
  55. }
  56. /**
  57. * slice word, make chinese symblos have length of 2
  58. * example:
  59. * ```
  60. * slice('abcd', 0, 3); // 'abc'
  61. * slice('中国', 0, 3); // '中 '
  62. * ```
  63. * @param {String} str
  64. * @param {Number} start
  65. * @param {Number} max
  66. * @return {String}
  67. */
  68. function _slice(str, start, max) {
  69. var length = max;
  70. var tmp = str.slice(start, length);
  71. var realLength = _getLength(tmp);
  72. while(realLength > max) {
  73. tmp = str.slice(start, --length);
  74. realLength = _getLength(tmp);
  75. }
  76. if (realLength < max) {
  77. tmp += ' ';
  78. }
  79. return tmp;
  80. }
  81. /**
  82. * get each column's max length
  83. * example:
  84. * ```
  85. * _getMax([['hello', 'world'], ['for', 'bar']]); // [4, 4]
  86. * ```
  87. * @param {Array} lines
  88. * @return {Array}
  89. */
  90. var _getMax = function(lines) {
  91. var eachMax = [];
  92. for (var i = 0, ls = lines.length; i < ls; i++) {
  93. var line = lines[i];
  94. for (var j = 0, l = line.length; j < l; j++) {
  95. var word = line[j];
  96. var wordLength = typeof word === 'string' ? word.length : JSON.stringify(word).length;
  97. if (eachMax[j] === undefined || wordLength > eachMax[j]) {
  98. eachMax[j] = wordLength;
  99. }
  100. }
  101. }
  102. return eachMax;
  103. }
  104. /**
  105. * get display length of string
  106. * @param {String} str input string
  107. * @return {String} output string
  108. */
  109. function _getLength(str) {
  110. return Math.round(str.replace(/[^\x00-\xff]/g, 'qq').length);
  111. }