JSFiddle - React, Tailwind, and code Playground

by brigand

HTML

<pre id="out"></pre>

JavaScript

function* lines(s) {
  let last = 0;
  for (const line of s.split('\n')) {
    if (last !== 0) {
      last += 1;
    }

    const start = last;
    last += line.length;
    yield {
      line,
      start,
      end: last
    };
  }
}

function getRanges(s) {
  let current = null;
  const ranges = [];
  for (const {
      line,
      start,
      end
    } of lines(s)) {
    if (!current && line.startsWith('>')) {
      current = [start];
    } else if (current && /^> ?$/.test(line)) {
      ranges.push([current[0], end])
      current = null;
    } else if (current && !/^> ./.test(line)) {
      ranges.push([current[0], start - 1])
      current = null;
    }
  }
  
  if (current) {
	  ranges.push([current[0], s.length]);
  }
  
  return ranges;
}

function getQuotes(s) {
  return getRanges(s).map(([i, j]) => s.slice(i, j + 1))
}


const s = '> a\n> b\n> \ncde\n> fg';
out.textContent = JSON.stringify({
  ranges: getRanges(s),
  quotes: getQuotes(s),
}, null, 2)