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

95.24% Statements 40/42
47.37% Branches 9/19
71.43% Functions 5/7
95% Lines 38/40

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  10x 10x 10x 10x   10x 10x 10x   10x 213x           10x 33x 33x 15x   18x 18x 18x     10x           40x   40x         80x 60x     20x   20x   13x 5x 12x 12x 12x 5x                     15x         88x 88x 3x 3x   85x                 10x     10x         10x  
/* 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;
 
const varRegex = new RegExp("\\$[VLT]?[0-9]+\\$", "g");
const varCharRegex = new RegExp("#[VLT]?[0-9]+#", "g");
const commandRegex = new RegExp("\\!S[0-5]\\!", "g");
 
const lineLength = (line: string) => {
  return line
    .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;