cmark

My personal build of CMark ✏️

Commit
c069cb55bcadfd0f45890d846ff412b3c892eb87
Parent
9a8610c9715e714e40ad7a93be89985fe5371907
Author
John MacFarlane <jgm@berkeley.edu>
Date

Better parsing of shortcut references.

We reuse the parser for reference labels, instead of just assuming that a slice of the link text will be a valid reference label. (It might contain interior brackets, for example.)

Diffstat

1 file changed, 15 insertions, 10 deletions

Status File Name N° Changes Insertions Deletions
Modified src/inlines.c 25 15 10
diff --git a/src/inlines.c b/src/inlines.c
@@ -751,11 +751,11 @@ noMatch:
 
 // Return a link, an image, or a literal close bracket.
 static cmark_node *handle_close_bracket(subject *subj) {
-  bufsize_t initial_pos;
+  bufsize_t initial_pos, save_pos;
   bufsize_t starturl, endurl, starttitle, endtitle, endall;
   bufsize_t n;
   bufsize_t sps;
-  cmark_reference *ref;
+  cmark_reference *ref = NULL;
   bool is_image = false;
   cmark_chunk url_chunk, title_chunk;
   cmark_chunk url, title;
@@ -830,11 +830,6 @@ static cmark_node *handle_close_bracket(subject *subj) {
   // skip spaces
   raw_label = cmark_chunk_literal("");
   found_label = link_label(subj, &raw_label);
-  if (!found_label || raw_label.len == 0) {
-    cmark_chunk_free(subj->mem, &raw_label);
-    raw_label = cmark_chunk_dup(&subj->input, opener->position,
-                                initial_pos - opener->position - 1);
-  }
 
   if (!found_label) {
     // If we have a shortcut reference link, back up
@@ -842,12 +837,22 @@ static cmark_node *handle_close_bracket(subject *subj) {
     subj->pos = initial_pos;
   }
 
-  ref = cmark_reference_lookup(subj->refmap, &raw_label);
-  cmark_chunk_free(subj->mem, &raw_label);
+  if (!found_label || raw_label.len == 0) {
+    save_pos = subj->pos;
+    subj->pos = opener->position - 1;
+    cmark_chunk_free(subj->mem, &raw_label);
+    found_label = link_label(subj, &raw_label);
+    subj->pos = save_pos;
+  }
+
+  if (found_label) {
+    ref = cmark_reference_lookup(subj->refmap, &raw_label);
+  }
 
-  if (ref != NULL) { // found
+  if (ref) {
     url = chunk_clone(subj->mem, &ref->url);
     title = chunk_clone(subj->mem, &ref->title);
+    cmark_chunk_free(subj->mem, &raw_label);
     goto match;
   } else {
     goto noMatch;