Fix handling EOLs inside a code span.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
diff --git a/md4c/md4c.c b/md4c/md4c.c
index e4ffd7b..7d08756 100644
--- a/md4c/md4c.c
+++ b/md4c/md4c.c
@@ -2772,15 +2772,19 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg,
OFF closer_end;
SZ mark_len;
OFF line_end;
- int has_space_after_opener;
- int has_space_before_closer;
+ int has_space_after_opener = FALSE;
+ int has_eol_after_opener = FALSE;
+ int has_space_before_closer = FALSE;
+ int has_eol_before_closer = FALSE;
int has_only_space = TRUE;
+ int line_index = 0;
line_end = lines[0].end;
opener_end = opener_beg;
while(opener_end < line_end && CH(opener_end) == _T('`'))
opener_end++;
- has_space_after_opener = (opener_end >= line_end || CH(opener_end) == _T(' '));
+ has_space_after_opener = (opener_end < line_end && CH(opener_end) == _T(' '));
+ has_eol_after_opener = (opener_end == line_end);
/* The caller needs to know end of the opening mark even if we fail. */
*p_opener_end = opener_end;
@@ -2811,7 +2815,8 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg,
if(closer_end - closer_beg == mark_len) {
/* Success. */
- has_space_before_closer = (closer_beg == lines[0].beg || CH(closer_beg-1) == _T(' '));
+ has_space_before_closer = (closer_beg > lines[line_index].beg && CH(closer_beg-1) == _T(' '));
+ has_eol_before_closer = (closer_beg == lines[line_index].beg);
break;
}
@@ -2829,16 +2834,15 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg,
}
if(closer_end >= line_end) {
- lines++;
- n_lines--;
- if(n_lines == 0) {
+ line_index++;
+ if(line_index >= n_lines) {
/* Reached end of the paragraph and still nothing. */
*p_reached_paragraph_end = TRUE;
return FALSE;
}
/* Try on the next line. */
- line_end = lines[0].end;
- closer_beg = lines[0].beg;
+ line_end = lines[line_index].end;
+ closer_beg = lines[line_index].beg;
} else {
closer_beg = closer_end;
}
@@ -2847,16 +2851,24 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg,
/* If there is a space or a new line both after and before the opener
* (and if the code span is not made of spaces only), consume one initial
* and one trailing space as part of the marks. */
- if(has_space_after_opener && has_space_before_closer && !has_only_space) {
- if(CH(opener_end) == _T('\r') && CH(opener_end+1) == _T('\n'))
- opener_end += 2;
- else
- opener_end += 1;
-
- if(CH(closer_beg-2) == _T('\r') && CH(closer_beg-1) == _T('\n'))
- closer_beg -= 2;
+ if(!has_only_space &&
+ (has_space_after_opener || has_eol_after_opener) &&
+ (has_space_before_closer || has_eol_before_closer))
+ {
+ if(has_space_after_opener)
+ opener_end++;
else
- closer_beg -= 1;
+ opener_end = lines[1].beg;
+
+ if(has_space_before_closer)
+ closer_beg--;
+ else {
+ closer_beg = lines[line_index-1].end;
+ /* We need to eat the preceding "\r\n" but not any line trailing
+ * spaces. */
+ while(closer_beg < ctx->size && ISBLANK(closer_beg))
+ closer_beg++;
+ }
}
*p_opener_beg = opener_beg;
@@ -4170,14 +4182,24 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
break;
if(text_type == MD_TEXT_CODE) {
- /* Inside code spans, new lines are transformed into single
- * spaces. */
+ OFF tmp;
+
MD_ASSERT(prev_mark != NULL);
MD_ASSERT(prev_mark->ch == '`' && (prev_mark->flags & MD_MARK_OPENER));
MD_ASSERT(mark->ch == '`' && (mark->flags & MD_MARK_CLOSER));
+ /* Inside a code span, trailing line whitespace has to be
+ * outputted. */
+ tmp = off;
+ while(off < ctx->size && ISBLANK(off))
+ off++;
+ if(off > tmp)
+ MD_TEXT(MD_TEXT_CODE, STR(tmp), off-tmp);
+
+ /* and new lines are transformed into single spaces. */
if(prev_mark->end < off && off < mark->beg)
MD_TEXT(MD_TEXT_CODE, _T(" "), 1);
+
} else if(text_type == MD_TEXT_HTML) {
/* Inside raw HTML, we output the new line verbatim, including
* any trailing spaces. */