function strong_em( tag, md ) {

  var state_slot = tag + "_state",
      other_slot = tag == "strong" ? "em_state" : "strong_state";

  function CloseTag(len) {
    this.len_after = len;
    this.name = "close_" + md;
  }

  return function ( text, orig_match ) {

    if (this[state_slot][0] == md) {
      // Most recent em is of this type
      //D:this.debug("closing", md);
      this[state_slot].shift();

      // "Consume" everything to go back to the recrusion in the else-block below
      return[ text.length, new CloseTag(text.length-md.length) ];
    }
    else {
      // Store a clone of the em/strong states
      var other = this[other_slot].slice(),
          state = this[state_slot].slice();

      this[state_slot].unshift(md);

      //D:this.debug_indent += "  ";

      // Recurse
      var res = this.processInline( text.substr( md.length ) );
      //D:this.debug_indent = this.debug_indent.substr(2);

      var last = res[res.length - 1];

      //D:this.debug("processInline from", tag + ": ", uneval( res ) );

      var check = this[state_slot].shift();
      if (last instanceof CloseTag) {
        res.pop();
        // We matched! Huzzah.
        var consumed = text.length - last.len_after;
        return [ consumed, [ tag ].concat(res) ];
      }
      else {
        // Restore the state of the other kind. We might have mistakenly closed it.
        this[other_slot] = other;
        this[state_slot] = state;

        // We can't reuse the processed result as it could have wrong parsing contexts in it.
        return [ md.length, md ];
      }
    }
  } // End returned function
}
// Meta Helper/generator method for em and strong handling
Meta Helper/generator method for em and strong handling
Meta Helper / generator method for em and strong handling
function strong_em( tag, md ) {
  var state_slot = tag + "_state",
      other_slot = tag == "strong" ? "em_state" : "strong_state";
  function CloseTag(len) {
    this.len_after = len;
    this.name = "close_" + md;
  }
  return function ( text, orig_match ) {
    if (this[state_slot][0] == md) {
      this[state_slot].shift();
      return[ text.length, new CloseTag(text.length-md.length) ];
    }
    else {
      var other = this[other_slot].slice(),
          state = this[state_slot].slice();
      this[state_slot].unshift(md);
      var res = this.processInline( text.substr( md.length ) );
      var last = res[res.length - 1];
      var check = this[state_slot].shift();
      if (last instanceof CloseTag) {
        res.pop();
        var consumed = text.length - last.len_after;
        return [ consumed, [ tag ].concat(res) ];
      }
      else {
        this[other_slot] = other;
        this[state_slot] = state;
        return [ md.length, md ];
      }
    }
  } 
}
function strong_em ( tag , md ) { var state_slot = tag + "_state" , other_slot = tag == "strong" ? "em_state" : "strong_state" ; function CloseTag ( len ) { this . len_after = len ; this . name = "close_" + md ; } return function ( text , orig_match ) { if ( this [ state_slot ] [ 0 ] == md ) { this [ state_slot ] . shift ( ) ; return [ text . length , new CloseTag ( text . length - md . length ) ] ; } else { var other = this [ other_slot ] . slice ( ) , state = this [ state_slot ] . slice ( ) ; this [ state_slot ] . unshift ( md ) ; var res = this . processInline ( text . substr ( md . length ) ) ; var last = res [ res . length - 1 ] ; var check = this [ state_slot ] . shift ( ) ; if ( last instanceof CloseTag ) { res . pop ( ) ; var consumed = text . length - last . len_after ; return [ consumed , [ tag ] . concat ( res ) ] ; } else { this [ other_slot ] = other ; this [ state_slot ] = state ; return [ md . length , md ] ; } } } }
Meta Helper/generator method for em and strong handling
Meta Helper / generator method for em and strong handling
// Most recent em is of this type //D:this.debug("closing", md); // "Consume" everything to go back to the recrusion in the else-block below // Store a clone of the em/strong states //D:this.debug_indent += "  "; // Recurse //D:this.debug_indent = this.debug_indent.substr(2); //D:this.debug("processInline from", tag + ": ", uneval( res ) ); // We matched! Huzzah. // Restore the state of the other kind. We might have mistakenly closed it. // We can't reuse the processed result as it could have wrong parsing contexts in it. // End returned function