All files / js metaformat.tsx

100% Statements 58/58
91.18% Branches 31/34
100% Functions 9/9
100% Lines 56/56

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  21x 21x       14x   7x 7x 7x 4x       7x       7x 7x       9x 9x 9x 9x     11x 7x 7x 7x       9x 24x 24x   24x 2x 2x 22x 14x 4x 4x 3x     11x   8x 8x 21x 7x 7x 7x 3x   4x 4x           9x 9x       7x   7x 21x 7x 1x   7x 3x 3x 3x 3x 1x   3x 7x     4x       7x    
function lineIsDashes(rawLine: string): boolean {
  const line = rawLine.trim();
  return line.length >= 3 && line === new Array(line.length + 1).join("-");
}
 
function processBuf(buf: string[]): string[] {
  const lines = buf.map((line) => (lineIsDashes(line) ? line.substr(1) : line));
 
  Eif (lines.length > 0) {
    const lastLine = lines[lines.length - 1];
    if (lastLine.substr(lastLine.length - 1) === "\n") {
      lines[lines.length - 1] = lastLine.substr(0, lastLine.length - 1);
    }
  }
 
  return lines;
}
 
function trimTabsAndSpaces(str: string): string {
  const match = str.match(/^[\t ]*(.*?)[\t ]*$/m);
  return match ? match[1] : "";
}
 
export function tokenize(lines: string[]): [string, string[]][] {
  let key: string | null = null;
  let buf: string[] = [];
  let wantNewline = false;
  const rv: [string, string[]][] = [];
 
  function flushItem() {
    if (key !== null) {
      rv.push([key, processBuf(buf)]);
      key = null;
      buf = [];
    }
  }
 
  for (let i = 0; i < lines.length; i++) {
    const match = lines[i].match(/^(.*?)(\r?\n)*$/m);
    const line = match ? `${match[1]}\n` : "\n";
 
    if (line.trimRight() === "---") {
      wantNewline = false;
      flushItem();
    } else if (key !== null) {
      if (wantNewline) {
        wantNewline = false;
        if (line.match(/^\s*$/)) {
          continue;
        }
      }
      buf.push(line);
    } else {
      const bits = line.split(":");
      if (bits.length >= 2) {
        const [rawKey, ...rest] = bits;
        key = rawKey.trim();
        const firstBit = trimTabsAndSpaces(rest.join(":"));
        if (!firstBit.match(/^\s*$/)) {
          buf = [firstBit];
        } else {
          buf = [];
          wantNewline = true;
        }
      }
    }
  }
 
  flushItem();
  return rv;
}
 
export function serialize(blocks: [string, string][]): string[] {
  const rv: string[] = [];
 
  blocks.forEach((item, idx) => {
    const [key, value] = item;
    if (idx > 0) {
      rv.push("---\n");
    }
    if (value.match(/([\r\n]|(^[\t ])|([\t ]$))/m)) {
      rv.push(key + ":\n");
      rv.push("\n");
      const lines = value.split(/\n/);
      if (lines[lines.length - 1] === "") {
        lines.pop();
      }
      lines.forEach((line) => {
        rv.push(lineIsDashes(line) ? `-${line}\n` : `${line}\n`);
      });
    } else {
      rv.push(key + ": " + value + "\n");
    }
  });
 
  return rv;
}