From e1db44b114620c5a23708d851d64fb53dd84bde9 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Wed, 10 Jun 2015 12:58:27 -0700 Subject: process_inlines: remove closers from delim stack when possible. When they have no matching openers and cannot be openers themselves, we can safely remove them. This helps with a performance case: "a_ " * 20000. See jgm/commonmark.js#43. --- src/inlines.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/inlines.c') diff --git a/src/inlines.c b/src/inlines.c index 7e8f806..a1f0356 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -439,6 +439,8 @@ static void process_emphasis(subject *subj, delimiter *start_delim) { delimiter *closer = subj->last_delim; delimiter *opener; + delimiter *old_closer; + bool opener_not_found; // move back to first relevant delim. while (closer != NULL && closer->previous != start_delim) { @@ -459,6 +461,9 @@ static void process_emphasis(subject *subj, delimiter *start_delim) } opener = opener->previous; } + opener_not_found = opener == NULL || + opener == start_delim; + old_closer = closer; if (closer->delim_char == '*' || closer->delim_char == '_') { if (opener != NULL && opener != start_delim) { closer = S_insert_emph(subj, opener, closer); @@ -486,6 +491,12 @@ static void process_emphasis(subject *subj, delimiter *start_delim) } closer = closer->next; } + if (opener_not_found && !old_closer->can_open) { + // we can remove a closer that can't be an + // opener, once we've seen there's no + // matching opener: + remove_delimiter(subj, old_closer); + } } else { closer = closer->next; } -- cgit v1.2.3