Skip to content

Commit

Permalink
Fix HTML renderer to handle neted images correctly.
Browse files Browse the repository at this point in the history
Fixes #210.
  • Loading branch information
mity committed Jan 10, 2024
1 parent 47a2ad3 commit ca169a9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 29 deletions.
52 changes: 23 additions & 29 deletions src/md4c-html.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,6 @@ render_open_img_span(MD_HTML* r, const MD_SPAN_IMG_DETAIL* det)
render_attribute(r, &det->src, render_url_escaped);

RENDER_VERBATIM(r, "\" alt=\"");

r->image_nesting_level++;
}

static void
Expand All @@ -357,8 +355,6 @@ render_close_img_span(MD_HTML* r, const MD_SPAN_IMG_DETAIL* det)
}

RENDER_VERBATIM(r, (r->flags & MD_HTML_FLAG_XHTML) ? "\" />" : "\">");

r->image_nesting_level--;
}

static void
Expand Down Expand Up @@ -435,25 +431,26 @@ static int
enter_span_callback(MD_SPANTYPE type, void* detail, void* userdata)
{
MD_HTML* r = (MD_HTML*) userdata;

if(r->image_nesting_level > 0) {
/* We are inside a Markdown image label. Markdown allows to use any
* emphasis and other rich contents in that context similarly as in
* any link label.
*
* However, unlike in the case of links (where that contents becomes
* contents of the <a>...</a> tag), in the case of images the contents
* is supposed to fall into the attribute alt: <img alt="...">.
*
* In that context we naturally cannot output nested HTML tags. So lets
* suppress them and only output the plain text (i.e. what falls into
* text() callback).
*
* This make-it-a-plain-text approach is the recommended practice by
* CommonMark specification (for HTML output).
*/
int inside_img = (r->image_nesting_level > 0);

/* We are inside a Markdown image label. Markdown allows to use any emphasis
* and other rich contents in that context similarly as in any link label.
*
* However, unlike in the case of links (where that contents becomescontents
* of the <a>...</a> tag), in the case of images the contents is supposed to
* fall into the attribute alt: <img alt="...">.
*
* In that context we naturally cannot output nested HTML tags. So lets
* suppress them and only output the plain text (i.e. what falls into text()
* callback).
*
* CommonMark specification declares this a recommended practice for HTML
* output.
*/
if(type == MD_SPAN_IMG)
r->image_nesting_level++;
if(inside_img)
return 0;
}

switch(type) {
case MD_SPAN_EM: RENDER_VERBATIM(r, "<em>"); break;
Expand All @@ -476,20 +473,17 @@ leave_span_callback(MD_SPANTYPE type, void* detail, void* userdata)
{
MD_HTML* r = (MD_HTML*) userdata;

if(r->image_nesting_level > 0) {
/* Ditto as in enter_span_callback(), except we have to allow the
* end of the <img> tag. */
if(r->image_nesting_level == 1 && type == MD_SPAN_IMG)
render_close_img_span(r, (MD_SPAN_IMG_DETAIL*) detail);
if(type == MD_SPAN_IMG)
r->image_nesting_level--;
if(r->image_nesting_level > 0)
return 0;
}

switch(type) {
case MD_SPAN_EM: RENDER_VERBATIM(r, "</em>"); break;
case MD_SPAN_STRONG: RENDER_VERBATIM(r, "</strong>"); break;
case MD_SPAN_U: RENDER_VERBATIM(r, "</u>"); break;
case MD_SPAN_A: RENDER_VERBATIM(r, "</a>"); break;
case MD_SPAN_IMG: /*noop, handled above*/ break;
case MD_SPAN_IMG: render_close_img_span(r, (MD_SPAN_IMG_DETAIL*) detail); break;
case MD_SPAN_CODE: RENDER_VERBATIM(r, "</code>"); break;
case MD_SPAN_DEL: RENDER_VERBATIM(r, "</del>"); break;
case MD_SPAN_LATEXMATH: /*fall through*/
Expand Down
9 changes: 9 additions & 0 deletions test/coverage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,15 @@ _bar_
````````````````````````````````


### [Issue 210](https://github.com/mity/md4c/issues/210)

```````````````````````````````` example
![outer ![inner](img_inner "inner title")](img_outer "outer title")
.
<p><img src="img_outer" alt="outer inner" title="outer title"></p>
````````````````````````````````


## Code coverage

### `md_is_unicode_whitespace__()`
Expand Down

0 comments on commit ca169a9

Please sign in to comment.