ker/com/x-latex/x-latex.com.js
function parseGroup(tokenizer) {
  // Group this functon will return.
  var mrow = {tag: 'mrow', children: []};
  // Last child of mrow.
  var lastItem;
  // Current token.
  var tkn;
  // Current tag.
  var tag;
  // Macro. This is a function with this prototype: (tokenizer, mrow).
  var macro;

  for(;;) {
    tkn = tokenizer.next();
    // End of stream.
    if (!tkn) break;
    // End of block.
    if (tkn.typ == '}') break;
    // Deal with msup.
    if (tkn.typ == '^') {
      if (mrow.children.length == 0) {
        mrow.children.push({tag: 'mrow', children: []});
      }
      lastItem = mrow.children[mrow.children.length - 1];
      if (lastItem.msup) {
        tokenizer.fatal("Double superscript.", tkn.idx);
      }
      lastItem.msup = parseItemOrGroup(tokenizer);
    }
    else if (tkn.typ == '_') {
      if (mrow.children.length == 0) {
        mrow.children.push({tag: 'mrow', children: []});
      }
      lastItem = mrow.children[mrow.children.length - 1];
      if (lastItem.msub) {
        tokenizer.fatal("Double subscript.", tkn.idx);
      }
      lastItem.msub = parseItemOrGroup(tokenizer);
    }
    // Prime, double, triple or quadruple prime.
    else if (tkn.typ == 'prime') {
      lastItem = mrow.children[mrow.children.length - 1];
      if (lastItem.msup) {
        tokenizer.fatal("Double superscript because of a prime.", tkn.idx);
      }
      lastItem.msup = {tag: 'mo', children: tkn.txt};
    }
    // Beginning of a new group.
    else if (tkn.typ == '{') {
      mrow.children.push( parseGroup(tokenizer) );
    }
    // Add this leaf in the tree.
    else {
      tag = tokenToTag(tkn);
      if (typeof tag === 'function') {
        // This is a macro.
        macro = tag;
        tag = macro(tokenizer, mrow, tkn.idx);
        if (tag) {
          mrow.children.push(tag);
        }
      } else {
        mrow.children.push(tag);
      }
    }
  }
  return mrow;
}
function parseGroup(tokenizer) {
  // Group this functon will return.
  var mrow = {tag: 'mrow', children: []};
  // Last child of mrow.
  var lastItem;
  // Current token.
  var tkn;
  // Current tag.
  var tag;
  // Macro. This is a function with this prototype: (tokenizer, mrow).
  var macro;

  for(;;) {
    tkn = tokenizer.next();
    // End of stream.
    if (!tkn) break;
    // End of block.
    if (tkn.typ == '}') break;
    // Deal with msup.
    if (tkn.typ == '^') {
      if (mrow.children.length == 0) {
        mrow.children.push({tag: 'mrow', children: []});
      }
      lastItem = mrow.children[mrow.children.length - 1];
      if (lastItem.msup) {
        tokenizer.fatal("Double superscript.", tkn.idx);
      }
      lastItem.msup = parseItemOrGroup(tokenizer);
    }
    else if (tkn.typ == '_') {
      if (mrow.children.length == 0) {
        mrow.children.push({tag: 'mrow', children: []});
      }
      lastItem = mrow.children[mrow.children.length - 1];
      if (lastItem.msub) {
        tokenizer.fatal("Double subscript.", tkn.idx);
      }
      lastItem.msub = parseItemOrGroup(tokenizer);
    }
    // Prime, double, triple or quadruple prime.
    else if (tkn.typ == 'prime') {
      lastItem = mrow.children[mrow.children.length - 1];
      if (lastItem.msup) {
        tokenizer.fatal("Double superscript because of a prime.", tkn.idx);
      }
      lastItem.msup = {tag: 'mo', children: tkn.txt};
    }
    // Beginning of a new group.
    else if (tkn.typ == '{') {
      mrow.children.push( parseGroup(tokenizer) );
    }
    // Add this leaf in the tree.
    else {
      tag = tokenToTag(tkn);
      if (typeof tag === 'function') {
        // This is a macro.
        macro = tag;
        tag = macro(tokenizer, mrow, tkn.idx);
        if (tag) {
          mrow.children.push(tag);
        }
      } else {
        mrow.children.push(tag);
      }
    }
  }
  return mrow;
}
function parseGroup ( tokenizer ) { // Group this functon will return. var mrow = { tag : 'mrow' , children : [ ] } ; // Last child of mrow. var lastItem ; // Current token. var tkn ; // Current tag. var tag ; // Macro. This is a function with this prototype: (tokenizer, mrow). var macro ; for ( ; ; ) { tkn = tokenizer . next ( ) ; // End of stream. if ( ! tkn ) break ; // End of block. if ( tkn . typ == '}' ) break ; // Deal with msup. if ( tkn . typ == '^' ) { if ( mrow . children . length == 0 ) { mrow . children . push ( { tag : 'mrow' , children : [ ] } ) ; } lastItem = mrow . children [ mrow . children . length - 1 ] ; if ( lastItem . msup ) { tokenizer . fatal ( "Double superscript." , tkn . idx ) ; } lastItem . msup = parseItemOrGroup ( tokenizer ) ; } else if ( tkn . typ == '_' ) { if ( mrow . children . length == 0 ) { mrow . children . push ( { tag : 'mrow' , children : [ ] } ) ; } lastItem = mrow . children [ mrow . children . length - 1 ] ; if ( lastItem . msub ) { tokenizer . fatal ( "Double subscript." , tkn . idx ) ; } lastItem . msub = parseItemOrGroup ( tokenizer ) ; } // Prime, double, triple or quadruple prime. else if ( tkn . typ == 'prime' ) { lastItem = mrow . children [ mrow . children . length - 1 ] ; if ( lastItem . msup ) { tokenizer . fatal ( "Double superscript because of a prime." , tkn . idx ) ; } lastItem . msup = { tag : 'mo' , children : tkn . txt } ; } // Beginning of a new group. else if ( tkn . typ == '{' ) { mrow . children . push ( parseGroup ( tokenizer ) ) ; } // Add this leaf in the tree. else { tag = tokenToTag ( tkn ) ; if ( typeof tag === 'function' ) { // This is a macro. macro = tag ; tag = macro ( tokenizer , mrow , tkn . idx ) ; if ( tag ) { mrow . children . push ( tag ) ; } } else { mrow . children . push ( tag ) ; } } } return mrow ; }
Read tokens from a Tokenizer and return a group.

The end of a group is when ye  reach to last token or if we encounter
the char '}'.
Read tokens from a Tokenizer and return a group .