summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2014-09-10 23:06:22 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2014-09-11 11:17:41 -0700
commit23c24d88401a4dbb8319c8c1fc6bbb0c44fb29cb (patch)
treed1f6d03c231a0b7e52be658fd587c9f9b9650c21 /js
parent5f56a1988ff8edfc020c97e37dbf834b499157d6 (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.
Diffstat (limited to 'js')
-rwxr-xr-xjs/stmd.js25
1 files changed, 19 insertions, 6 deletions
diff --git a/js/stmd.js b/js/stmd.js
index 0cfb6b3..fdbc188 100755
--- a/js/stmd.js
+++ b/js/stmd.js
@@ -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,