All files wordwrap.ts

100% Statements 45/45
100% Branches 17/17
100% Functions 1/1
100% Lines 45/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 921x 1x                                                           1x 7x 7x 7x 7x 1x 7x 2x     2x 208x 2x 2x 208x 208x     2x 1x 1x   2x 2x 4x 4x   7x   72x 4x   1x 1x     4x 4x 4x     72x 64x 64x 64x     72x 72x 72x     7x 1x 45x 45x 1x   4x 4x  
import { splitWords } from './split-words.ts';
import { empty, space } from './unicode.ts';
 
/**
 * Options for the {@link wordwrap} function
 * @group String
 * @category Operations
 */
export type WordwrapOptions = {
  /** The width to wrap to */
  width?: number;
  /** Line separator */
  separator?: string;
  /** If true, don't limit breaks to word boundaries */
  cut?: boolean;
  /** If true, spaces are added to the end of each line to make all lines equal width, ignored if cut or preserveSpaces is true */
  trailingSpaces?: boolean;
};
 
/**
 * Wrap text so that it fits within a area of fixed width
 * @param input - the text to wrap
 * @param options - see {@link WordwrapOptions}
 * @defaultValue width 75
 * @defaultValue separator \\n
 * @defaultValue cut default false
 * @defaultValue trailingSpaces false
 * @returns wrapped text
 * @group String
 * @category Operations
 */
export function wordwrap(
  input: string,
  { width = 75, separator = '\n', cut = false, trailingSpaces = false }: WordwrapOptions = {},
): string {
  if (width <= 0) {
    return input;
  } else if (cut) {
    let result = empty;
 
    // walk through each character and add separators where appropriate
    for (let i = 0; i < input.length; ++i) {
      if (i % width === 0 && i > 0) {
        result += separator;
      }
      result += input.charAt(i);
    }
 
    // fill the rest of the line with spaces if trailingSpaces option is true
    if (trailingSpaces) {
      result += space.repeat(width - (input.length % width));
    }
 
    return result;
  }
  let currentColumn = 0;
  let result = empty;
 
  for (const word of splitWords(input)) {
    // if adding a space and the next word would cause this line to be longer than width...
    if (word.length + currentColumn > width) {
      if (trailingSpaces) {
        // fill the rest of the line with spaces if trailingSpaces option is true
        result += space.repeat(width - currentColumn);
      }
 
      //start new line
      result += separator;
      currentColumn = 0;
    }
 
    // if not at the beginning of the line, add a space in front of the word
    if (currentColumn > 0) {
      result += space;
      currentColumn++;
    }
 
    // tack on the next word, update current column, a pop words array
    result += word;
    currentColumn += word.length;
  }
 
  // fill the rest of the line with spaces if trailingSpaces option is true
  if (trailingSpaces) {
    while (currentColumn++ < width) {
      result += space;
    }
  }
 
  return result;
}