diff options
| author | John MacFarlane <jgm@berkeley.edu> | 2014-09-10 23:06:22 -0700 | 
|---|---|---|
| committer | John MacFarlane <jgm@berkeley.edu> | 2014-09-11 11:17:41 -0700 | 
| commit | 23c24d88401a4dbb8319c8c1fc6bbb0c44fb29cb (patch) | |
| tree | d1f6d03c231a0b7e52be658fd587c9f9b9650c21 | |
| parent | 5f56a1988ff8edfc020c97e37dbf834b499157d6 (diff) | |
Added last_closer to Inline object.
This helps us avoid unneeded backtracking in pathological input
of the form:
*a
**a
*a
**a
*a
etc.
If we get to position k without finding a closing delimiter,
then backtrack to 1, we can assume we won't find a closing
delimiter when parsing forward again.
This could no doubt be polished up, e.g. by making it sensitive
to the kind of delimiter.
| -rwxr-xr-x | js/stmd.js | 25 | 
1 files changed, 19 insertions, 6 deletions
| @@ -291,14 +291,19 @@ var parseEmphasis = function() {    this.pos += numdelims;    var next_inline; +  var last_closer = null; -    var delims_to_match = numdelims; -    while (true) { +  var delims_to_match = numdelims; +  while (this.last_closer === null || this.last_closer >= this.pos) {          res = this.scanDelims(c);          numclosedelims = res.numdelims;          if (res.can_close) { +            if (last_closer < this.pos) { +                last_closer = this.pos; +            }              if (numclosedelims === 3 && delims_to_match === 3) {                  this.pos += 3; +                this.last_closer = null;                  return {t: 'Strong', c: [{t: 'Emph', c: inlines}]};              } else if (numclosedelims >= 2 && delims_to_match >= 2) {                  delims_to_match -= 2; @@ -310,18 +315,24 @@ var parseEmphasis = function() {                  inlines = [{t: 'Emph', c: inlines}];              }              if (delims_to_match === 0) { +                this.last_closer = null;                  return inlines[0];              }          } else if (next_inline = this.parseInline()) {              inlines.push(next_inline);          } else { -            // didn't find closing delimiter -            this.pos = startpos + numdelims; -            return {t: 'Str', c: this.subject.slice(startpos, startpos + numdelims)}; +            break;          }      } -    return null; +    // didn't find closing delimiter +    this.pos = startpos + numdelims; +    if (last_closer === null) { +        this.last_closer = startpos; +    } else { +        this.last_closer = last_closer; +    } +    return {t: 'Str', c: this.subject.slice(startpos, startpos + numdelims)};  };  // Attempt to parse link title (sans quotes), returning the string @@ -654,6 +665,7 @@ var parseInlines = function(s, refmap) {    this.pos = 0;    this.refmap = refmap || {};    this.memo = {}; +  this.last_closer = null;    var inlines = [];    var next_inline;    while (next_inline = this.parseInline()) { @@ -670,6 +682,7 @@ function InlineParser(){      pos: 0,      refmap: {},      memo: {}, +    last_closer: null,      match: match,      peek: peek,      spnl: spnl, | 
