All files / src/shared/lib/helpers trimlines.ts

92% Statements 46/50
47.37% Branches 9/19
55.56% Functions 5/9
91.11% Lines 41/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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109  8x 8x 8x 8x   8x 8x 8x 8x   8x             8x 213x           8x               8x 33x 33x 15x   18x 18x 18x     8x           40x   40x         80x 60x     20x   20x   13x 5x 12x 12x 12x 5x                     15x         88x 88x 3x 3x   85x                 8x     8x         8x  
/* eslint-disable no-control-regex */
const LINE_MAX = 4;
const LINE_MIN = 2;
const CHARS_PER_LINE = 18;
const CHARS_MAX_TOTAL = 18 + 18 + 16;
 
export const varRegex = new RegExp("\\$[VLT]?[0-9]+\\$", "g");
export const varCharRegex = new RegExp("#[VLT]?[0-9]+#", "g");
export const commandRegex = new RegExp("\\!S[0-5]\\!", "g");
export const newlineRegex = new RegExp("\n", "g");
 
export const dummyText = (text: string) => {
  return text
    .replace(varRegex, "$$$$$")
    .replace(varCharRegex, "#")
    .replace(commandRegex, "");
};
 
export const lineLength = (line: string) => {
  return line
    .replace(varRegex, "255")
    .replace(varCharRegex, "C")
    .replace(commandRegex, "").length;
};
 
export const totalLength = (line: string) => {
  return line
    .replace(newlineRegex, "")
    .replace(varRegex, "255")
    .replace(varCharRegex, "C")
    .replace(commandRegex, "").length;
};
 
const cropLine = (line: string, maxLength: number): string => {
  const len = lineLength(line);
  if (len <= maxLength) {
    return line;
  }
  const lenDiff = len - maxLength;
  const cropped = line.substring(0, line.length - lenDiff);
  return cropLine(cropped, maxLength);
};
 
const trimlines = (
  string: string,
  maxCharsPerLine = CHARS_PER_LINE,
  maxLines = LINE_MAX,
  maxTotal = CHARS_MAX_TOTAL
): string => {
  let lengthCount = 0;
 
  return (
    string
      .split("\n")
      .map((line, lineIndex) => {
        // Include whole line if under limits
        if (lineLength(line) <= maxCharsPerLine) {
          return line;
        }
 
        let cropped = line;
        // If not last line
        if (lineIndex < maxLines - 1) {
          // Crop to last space if possible
          if (cropped.indexOf(" ") > -1) {
            while (cropped.indexOf(" ") > -1) {
              const lastBreakSymbol = cropped.lastIndexOf(" ");
              cropped = cropped.substring(0, lastBreakSymbol);
              if (lineLength(cropped) <= maxCharsPerLine) {
                return `${cropped}\n${trimlines(
                  line.substring(cropped.length + 1, line.length),
                  maxCharsPerLine,
                  maxLines
                )}`;
              }
            }
          }
        }
 
        // Fallback to just cropping the line to fit mid word
        return cropLine(line, maxCharsPerLine);
      })
      .join("\n")
      .split("\n")
      .map((line) => {
        lengthCount += lineLength(line);
        if (lengthCount > maxTotal) {
          const amountOver = lengthCount - maxTotal;
          return line.substring(0, line.length - amountOver);
        }
        return line;
      })
      .slice(0, maxLines)
      .join("\n")
      // Crop to max 80 characters used in C string buffer
      .substring(0, 80)
  );
};
 
export const textNumLines = (string: string) =>
  Math.max(LINE_MIN, (string || "").split("\n").length);
 
export const textNumNewlines = (input: string): number => {
  // eslint-disable-next-line no-control-regex
  return (input.match(/(\n|\r|\x0a|\x0d|\\012|\\015)/g)?.length ?? 0) + 1;
};
 
export default trimlines;