Handles adding/removing a format string to a line
@param   {String} string         the entire string
@param   {Number[]}  selectionRange the starting and ending positions of the selection
@param   {String} symbol         the format string to use
@returns {Object} the new string, the updated indices
function blockHandler(string, selectionRange, symbol) {
  const start = selectionRange[0];
  const end = selectionRange[1];
  const boundaryRegex = /[0-9~*`_-]|\b|\n|$/gm;
  let value;
  let lineStart = startOfLine(string, start);
  let lineEnd = endOfLine(string, end);

  // If there is a block handler symbol at the start of the line...
  if (indexOfMatch(string, /^[#>]/m, lineStart) === lineStart) {
    // Find the first boundary from the start of the formatting symbol
    // May include white space
    const existingSymbolBoundary = string.substring(lineStart).search(boundaryRegex);
    const existingSymbol = string.substring(lineStart, existingSymbolBoundary);

    // Create new string without the existingSymbol
    value = string.substring(0, lineStart) + string.substring(existingSymbolBoundary, string.length);

    // And also subtract the length of the symbol from the lineEnd index
    lineEnd -= existingSymbol.length;

    // If it's some other block handler...
    if (symbol.trim().length && existingSymbol.trim() !== symbol.trim()) {
      // Create a new string with the symbol inserted
      value = string.substring(0, lineStart) + symbol + string.substring(existingSymbolBoundary, string.length);
      // And adjust lineStart and lineEnd indices
      lineStart += symbol.length;
      lineEnd += symbol.length;
    }

    return { value, range: [lineStart, lineEnd] };
  }

  // If not, pretty simple
  value = string.substring(0, lineStart) + symbol + string.substring(lineStart, string.length);
  return { value, range: [start + symbol.length, end + symbol.length] };
}