docs: function parseTemplate(template, tags) {
          if (!template) return [];
  
          var sections = []; // Stack to hold section tokens
          var tokens = []; // Buffer to hold the tokens
          var spaces = []; // Indices of whitespace tokens on the current line
          var hasTag = false; // Is there a {{tag}} on the current line?
          var nonSpace = false; // Is there a non-space char on the current line?
  
          // Strips all whitespace tokens array for the current line
          // if there was a {{#tag}} on it and otherwise only space.
          function stripSpace() {
              if (hasTag && !nonSpace) {
                  while (spaces.length) {
                      delete tokens[spaces.pop()];
                  }
              } else {
                  spaces = [];
              }
  
              hasTag = false;
              nonSpace = false;
          }
  
          var openingTagRe, closingTagRe, closingCurlyRe;
  
          function compileTags(tagsToCompile) {
              if (typeof tagsToCompile === 'string') tagsToCompile = tagsToCompile.split(spaceRe, 2);
  
              if (!isArray(tagsToCompile) || tagsToCompile.length !== 2) throw new Error('Invalid tags: ' + tagsToCompile);
  
              openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
              closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
              closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
          }
  
          compileTags(tags || mustache.tags);
  
          var scanner = new Scanner(template);
  
          var start, type, value, chr, token, openSection;
          while (!scanner.eos()) {
              start = scanner.pos;
  
              // Match any text between tags.
              value = scanner.scanUntil(openingTagRe);
  
              if (value) {
                  for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
                      chr = value.charAt(i);
  
                      if (isWhitespace(chr)) {
                          spaces.push(tokens.length);
                      } else {
                          nonSpace = true;
                      }
  
                      tokens.push(['text', chr, start, start + 1]);
                      start += 1;
  
                      // Check for whitespace on the current line.
                      if (chr === '\n') stripSpace();
                  }
              }
  
              // Match the opening tag.
              if (!scanner.scan(openingTagRe)) break;
  
              hasTag = true;
  
              // Get the tag type.
              type = scanner.scan(tagRe) || 'name';
              scanner.scan(whiteRe);
  
              // Get the tag value.
              if (type === '=') {
                  value = scanner.scanUntil(equalsRe);
                  scanner.scan(equalsRe);
                  scanner.scanUntil(closingTagRe);
              } else if (type === '{') {
                  value = scanner.scanUntil(closingCurlyRe);
                  scanner.scan(curlyRe);
                  scanner.scanUntil(closingTagRe);
                  type = '&';
              } else {
                  value = scanner.scanUntil(closingTagRe);
              }
  
              // Match the closing tag.
              if (!scanner.scan(closingTagRe)) throw new Error('Unclosed tag at ' + scanner.pos);
  
              token = [type, value, start, scanner.pos];
              tokens.push(token);
  
              if (type === '#' || type === '^') {
                  sections.push(token);
              } else if (type === '/') {
                  // Check section nesting.
                  openSection = sections.pop();
  
                  if (!openSection) throw new Error('Unopened section "' + value + '" at ' + start);
  
                  if (openSection[1] !== value) throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
              } else if (type === 'name' || type === '{' || type === '&') {
                  nonSpace = true;
              } else if (type === '=') {
                  // Set the tags for the next time around.
                  compileTags(value);
              }
          }
  
          // Make sure there are no open sections when we're done.
          openSection = sections.pop();
  
          if (openSection) throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
  
          return nestTokens(squashTokens(tokens));
      }