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; } |