cmark

My personal build of CMark ✏️

Commit
4d4a3f72892ee50207e50e447a03f61e5c267867
Parent
65af8da7a80a9fb062cacf1ef7e21b0c91cfde53
Author
John MacFarlane <fiddlosopher@gmail.com>
Date

Allow images to contain images.

Diffstat

4 files changed, 37 insertions, 32 deletions

Status File Name N° Changes Insertions Deletions
Modified js/lib/html-renderer.js 4 3 1
Modified js/lib/inlines.js 26 14 12
Modified spec.txt 6 3 3
Modified src/inlines.c 33 17 16
diff --git a/js/lib/html-renderer.js b/js/lib/html-renderer.js
@@ -43,7 +43,9 @@ var renderInline = function(inline) {
         return inTags('a', attrs, this.renderInlines(inline.label));
     case 'Image':
         attrs = [['src', this.escape(inline.destination, true)],
-                 ['alt', this.renderInlines(inline.label).replace(/\<[^>]*\>/g,'')]];
+                 ['alt', this.renderInlines(inline.label).
+                    replace(/\<[^>]*alt="([^"]*)"[^>]*\>/g, '$1').
+                    replace(/\<[^>]*\>/g,'')]];
         if (inline.title) {
             attrs.push(['title', this.escape(inline.title, true)]);
         }
diff --git a/js/lib/inlines.js b/js/lib/inlines.js
@@ -595,21 +595,23 @@ var parseCloseBracket = function(inlines) {
         }
 
         // processEmphasis will remove this and later delimiters.
-        // Now we also remove earlier ones of the same kind (so,
-        // no links in links, no images in images).
-        opener = this.delimiters;
-        closer_above = null;
-        while (opener !== null) {
-            if (opener.cc === (is_image ? C_BANG : C_OPEN_BRACKET)) {
-                if (closer_above) {
-                    closer_above.previous = opener.previous;
-                } else {
-                    this.delimiters = opener.previous;
-                }
+        // Now, for a link, we also remove earlier link openers.
+        // (no links in links)
+        if (!is_image) {
+          opener = this.delimiters;
+          closer_above = null;
+          while (opener !== null) {
+            if (opener.cc === C_OPEN_BRACKET) {
+              if (closer_above) {
+                closer_above.previous = opener.previous;
+              } else {
+                this.delimiters = opener.previous;
+              }
             } else {
-                closer_above = opener;
+              closer_above = opener;
             }
             opener = opener.previous;
+          }
         }
 
         inlines.push({t: is_image ? 'Image' : 'Link',
diff --git a/spec.txt b/spec.txt
@@ -5889,8 +5889,8 @@ difference. Instead of [link text](#link-text), we have an [image
 description](@image-description).  The rules for this are the
 same as for [link text](#link-text), except that (a) an
 image description starts with `![` rather than `[`, and
-(b) an image description may contain links, but not images
-(even deeply nested).  An image description has inline elements
+(b) an image description may contain links.
+An image description has inline elements
 as its contents.  When an image is rendered to HTML,
 this is standardly used as the image's `alt` attribute.
 
@@ -5911,7 +5911,7 @@ this is standardly used as the image's `alt` attribute.
 .
 ![foo ![bar](/url)](/url2)
 .
-<p>![foo <img src="/url" alt="bar" />](/url2)</p>
+<p><img src="/url2" alt="foo bar" /></p>
 .
 
 .
diff --git a/src/inlines.c b/src/inlines.c
@@ -782,25 +782,26 @@ match:
 	*last = inl;
 
 	// process_emphasis will remove this delimiter and all later ones.
-	// Now we also remove earlier ones of the same kind
-	// (so, no links in links, and no images in images):
-	// (This code can be removed if we decide to allow links
-	// inside links and images inside images):
-	opener = subj->delimiters;
-	closer_above = NULL;
-	while (opener != NULL) {
-		tempstack = opener->previous;
-		if (opener->delim_char == (is_image ? '!' : '[')) {
-			free(opener);
-			if (closer_above) {
-				closer_above->previous = tempstack;
+	// Now, if we have a link, we also want to remove earlier link
+        // delimiters. (This code can be removed if we decide to allow links
+	// inside links.)
+	if (!is_image) {
+		opener = subj->delimiters;
+		closer_above = NULL;
+		while (opener != NULL) {
+			tempstack = opener->previous;
+			if (opener->delim_char == '[') {
+				free(opener);
+				if (closer_above) {
+					closer_above->previous = tempstack;
+				} else {
+					subj->delimiters = tempstack;
+				}
 			} else {
-				subj->delimiters = tempstack;
+				closer_above = opener;
 			}
-		} else {
-			closer_above = opener;
+			opener = tempstack;
 		}
-		opener = tempstack;
 	}
 
 	return NULL;