Handle empty list items.
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 120 121 122 123 124 125 126
diff --git a/md4c/md4c.c b/md4c/md4c.c
index 0665c20..3f6567c 100644
--- a/md4c/md4c.c
+++ b/md4c/md4c.c
@@ -146,7 +146,7 @@ struct MD_CTX_tag {
unsigned n_containers;
unsigned alloc_containers;
- int last_line_is_blank;
+ int last_line_has_list_loosening_effect;
/* Minimal indentation to call the block "indented code block". */
unsigned code_indent_offset;
@@ -4684,7 +4684,7 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
}
/* Check for list item bullet mark. */
- if(off+1 < ctx->size && ISANYOF(off, _T("-+*")) && ISBLANK(off+1)) {
+ if(off+1 < ctx->size && ISANYOF(off, _T("-+*")) && (ISBLANK(off+1) || ISNEWLINE(off+1))) {
p_container->ch = CH(off);
p_container->is_loose = FALSE;
p_container->mark_indent = indent;
@@ -4702,7 +4702,7 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
p_container->start = p_container->start * 10 + CH(off) - _T('0');
off++;
}
- if(off+1 < ctx->size && (CH(off) == _T('.') || CH(off) == _T(')')) && ISBLANK(off+1)) {
+ if(off+1 < ctx->size && (CH(off) == _T('.') || CH(off) == _T(')')) && (ISBLANK(off+1) || ISNEWLINE(off+1))) {
p_container->ch = CH(off);
p_container->is_loose = FALSE;
p_container->mark_indent = indent;
@@ -4745,7 +4745,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
int n_brothers = 0;
int n_children = 0;
MD_CONTAINER container;
- int prev_line_is_blank = ctx->last_line_is_blank;
+ int prev_line_has_list_loosening_effect = ctx->last_line_has_list_loosening_effect;
OFF off = beg;
int ret = 0;
@@ -4848,14 +4848,14 @@ redo:
line->indent -= ctx->code_indent_offset;
else
line->indent = 0;
- ctx->last_line_is_blank = FALSE;
+ ctx->last_line_has_list_loosening_effect = FALSE;
} else {
line->type = MD_LINE_BLANK;
- ctx->last_line_is_blank = TRUE;
+ ctx->last_line_has_list_loosening_effect = (n_brothers + n_children == 0);
}
goto done;
} else {
- ctx->last_line_is_blank = FALSE;
+ ctx->last_line_has_list_loosening_effect = FALSE;
}
/* Check for indented code.
@@ -4906,32 +4906,39 @@ redo:
line->indent = md_line_indentation(ctx, total_indent, off, &off);
total_indent += line->indent;
- line->beg = off;
- /* Some of the following whitespace actually still belongs to the mark. */
- if(line->indent <= ctx->code_indent_offset) {
- container.contents_indent += line->indent;
- line->indent = 0;
+ if((off >= ctx->size || ISNEWLINE(off)) && pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers) {
+ /* Noop. List mark followed by a blank line cannot interrupt a paragraph. */
} else {
- container.contents_indent += 1;
- line->indent--;
- }
+ line->beg = off;
- if(n_brothers + n_children == 0) {
- pivot_line = &md_dummy_blank_line;
+ /* Some of the following whitespace actually still belongs to the mark. */
+ if(off >= ctx->size || ISNEWLINE(off)) {
+ container.contents_indent++;
+ } else if(line->indent <= ctx->code_indent_offset) {
+ container.contents_indent += line->indent;
+ line->indent = 0;
+ } else {
+ container.contents_indent += 1;
+ line->indent--;
+ }
+
+ if(n_brothers + n_children == 0) {
+ pivot_line = &md_dummy_blank_line;
- if(n_parents < ctx->n_containers && md_is_container_compatible(&ctx->containers[n_parents], &container)) {
- n_brothers++;
- goto redo;
+ if(n_parents < ctx->n_containers && md_is_container_compatible(&ctx->containers[n_parents], &container)) {
+ n_brothers++;
+ goto redo;
+ }
}
- }
- if(n_children == 0)
- MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers));
+ if(n_children == 0)
+ MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers));
- n_children++;
- MD_CHECK(md_push_container(ctx, &container));
- goto redo;
+ n_children++;
+ MD_CHECK(md_push_container(ctx, &container));
+ goto redo;
+ }
}
/* Check for ATX header. */
@@ -5032,7 +5039,7 @@ done:
*p_end = off;
/* If we belong to a list after seeing a blank line, the enclosing is loose. */
- if(prev_line_is_blank && line->type != MD_LINE_BLANK && n_parents + n_brothers > 0) {
+ if(prev_line_has_list_loosening_effect && line->type != MD_LINE_BLANK && n_parents + n_brothers > 0) {
MD_CONTAINER* c = &ctx->containers[n_parents + n_brothers - 1];
if(c->ch != _T('>')) {
MD_BLOCK* block = (MD_BLOCK*) (((char*)ctx->block_bytes) + c->block_byte_off);