diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/inlines.c | 101 | 
1 files changed, 54 insertions, 47 deletions
| diff --git a/src/inlines.c b/src/inlines.c index c8bdebc..92e79c7 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -159,7 +159,7 @@ static void subject_from_buf(cmark_mem *mem, subject *e, cmark_strbuf *buffer,    e->refmap = refmap;    e->last_delim = NULL;    e->last_bracket = NULL; -  for (i=0; i <= MAXBACKTICKS; i++) { +  for (i = 0; i <= MAXBACKTICKS; i++) {      e->backticks[i] = 0;    }    e->scanned_for_backticks = false; @@ -515,17 +515,9 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {    delimiter *opener;    delimiter *old_closer;    bool opener_found; -  bool odd_match; -  delimiter *openers_bottom[3][128]; -  int i; - -  // initialize openers_bottom: -  for (i=0; i < 3; i++) { -    openers_bottom[i]['*'] = stack_bottom; -    openers_bottom[i]['_'] = stack_bottom; -    openers_bottom[i]['\''] = stack_bottom; -    openers_bottom[i]['"'] = stack_bottom; -  } +  int openers_bottom_index; +  delimiter *openers_bottom[6] = {stack_bottom, stack_bottom, stack_bottom, +                                  stack_bottom, stack_bottom, stack_bottom};    // move back to first relevant delim.    while (closer != NULL && closer->previous != stack_bottom) { @@ -535,22 +527,36 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {    // now move forward, looking for closers, and handling each    while (closer != NULL) {      if (closer->can_close) { +      switch (closer->delim_char) { +      case '"': +        openers_bottom_index = 0; +        break; +      case '\'': +        openers_bottom_index = 1; +        break; +      case '_': +        openers_bottom_index = 2; +        break; +      case '*': +        openers_bottom_index = 3 + (closer->length % 3); +        break; +      default: +        assert(false); +      } +        // Now look backwards for first matching opener:        opener = closer->previous;        opener_found = false; -      odd_match = false; -      while (opener != NULL && opener != stack_bottom && -             opener != openers_bottom[closer->length % 3][closer->delim_char]) { -	if (opener->can_open && opener->delim_char == closer->delim_char) { +      while (opener != NULL && opener != openers_bottom[openers_bottom_index]) { +        if (opener->can_open && opener->delim_char == closer->delim_char) {            // interior closer of size 2 can't match opener of size 1            // or of size 1 can't match 2 -          odd_match = (closer->can_open || opener->can_close) && -                      ((opener->length + closer->length) % 3 == 0); -          if (!odd_match) { +          if (!(closer->can_open || opener->can_close) || +              ((opener->length + closer->length) % 3) != 0) {              opener_found = true;              break;            } -	} +        }          opener = opener->previous;        }        old_closer = closer; @@ -579,8 +585,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {        }        if (!opener_found) {          // set lower bound for future searches for openers -        openers_bottom[old_closer->length % 3][old_closer->delim_char] = -		old_closer->previous; +        openers_bottom[openers_bottom_index] = old_closer->previous;          if (!old_closer->can_open) {            // we can remove a closer that can't be an            // opener, once we've seen there's no @@ -593,7 +598,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {      }    }    // free all delimiters in list until stack_bottom: -  while (subj->last_delim != stack_bottom) { +  while (subj->last_delim != NULL && subj->last_delim != stack_bottom) {      remove_delimiter(subj, subj->last_delim);    }  } @@ -845,11 +850,13 @@ static bufsize_t manual_scan_link_url(cmark_chunk *input, bufsize_t offset) {        if (input->data[i] == '\\')          i += 2;        else if (input->data[i] == '(') { -        ++nb_p; ++i; +        ++nb_p; +        ++i;        } else if (input->data[i] == ')') {          if (nb_p == 0)            break; -        --nb_p; ++i; +        --nb_p; +        ++i;        } else if (cmark_isspace(input->data[i]))          break;        else @@ -1033,31 +1040,31 @@ static cmark_node *handle_newline(subject *subj) {  static bufsize_t subject_find_special_char(subject *subj, int options) {    // "\r\n\\`&_*[]<!"    static const int8_t SPECIAL_CHARS[256] = { -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, -    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, +      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};    // " ' . -    static const char SMART_PUNCT_CHARS[] = { -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    };    bufsize_t n = subj->pos + 1; | 
