Fixes of ATX header parsing.
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
diff --git a/md4c/md4c.c b/md4c/md4c.c
index e761127..4949510 100644
--- a/md4c/md4c.c
+++ b/md4c/md4c.c
@@ -295,7 +295,7 @@ md_is_atxheader_line(MD_CTX* ctx, OFF beg, OFF* p_beg, OFF* p_end)
return -1;
ctx->header_level = n;
- if(!(ctx->r.flags & MD_FLAG_PERMISSIVEATXHEADERS) && off < ctx->size && CH(off) != _T(' '))
+ if(!(ctx->r.flags & MD_FLAG_PERMISSIVEATXHEADERS) && off < ctx->size && CH(off) != _T(' ') && !ISNEWLINE(off))
return -1;
while(off < ctx->size && CH(off) == _T(' '))
@@ -357,14 +357,15 @@ done:
/* But for ATX header, we should not include the optional tailing mark. */
if(line->type == MD_LINE_ATXHEADER) {
OFF tmp = line->end;
- while(tmp > line->beg && CH(tmp-1) == _T(' '))
+ while(tmp > line->beg && CH(tmp-1) == _T(' '))
tmp--;
- while(tmp > line->beg && CH(tmp-1) == _T('#'))
+ while(tmp > line->beg && CH(tmp-1) == _T('#'))
tmp--;
- while(tmp > line->beg && CH(tmp-1) == _T(' '))
- tmp--;
- if(CH(tmp) == _T(' ') || (ctx->r.flags & MD_FLAG_PERMISSIVEATXHEADERS))
+ if(tmp == line->beg || CH(tmp-1) == _T(' ') || (ctx->r.flags & MD_FLAG_PERMISSIVEATXHEADERS)) {
+ while(tmp > line->beg && CH(tmp-1) == _T(' '))
+ tmp--;
line->end = tmp;
+ }
}
/* Eat also the new line. */
@@ -455,31 +456,43 @@ md_process_doc(MD_CTX *ctx)
md_analyze_line(ctx, off, &off, pivot_line, &lines[n_lines]);
line = &lines[n_lines];
- /* The same block continues as long lines are of the same type. */
- if(line->type == pivot_line->type) {
- /* But not so thematic break and ATX headers. */
- if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER)
- goto force_block_end;
+ /* Some line types form block on their own. */
+ if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER) {
+ /* Flush accumulated lines. */
+ ret = md_process_block(ctx, lines, n_lines);
+ if(ret != 0)
+ goto abort;
- /* Do not grow the 'lines' because of blank lines. Semantically
- * one blank line is equivalent to many. */
- if(line->type != MD_LINE_BLANK)
- n_lines++;
+ /* Flush ourself. */
+ ret = md_process_block(ctx, line, 1);
+ if(ret != 0)
+ goto abort;
+ pivot_line = &dummy_line;
+ n_lines = 0;
continue;
}
-force_block_end:
- /* Otherwise the old block is complete and we have to process it. */
- ret = md_process_block(ctx, lines, n_lines);
- if(ret != 0)
- goto abort;
+ /* New block also starts if line type changes. */
+ if(line->type != pivot_line->type) {
+ ret = md_process_block(ctx, lines, n_lines);
+ if(ret != 0)
+ goto abort;
+
+ /* Keep the current line as the new pivot. */
+ if(line != &lines[0])
+ memcpy(&lines[0], line, sizeof(MD_LINE));
+ pivot_line = &lines[0];
+ n_lines = 1;
+ continue;
+ }
+
+ /* Not much to do with multiple blank lines. */
+ if(line->type == MD_LINE_BLANK)
+ continue;
- /* Keep the current line as the new pivot. */
- if(line != &lines[0])
- memcpy(&lines[0], line, sizeof(MD_LINE));
- pivot_line = &lines[0];
- n_lines = 1;
+ /* Otherwise we just accumulate the line into ongoing block. */
+ n_lines++;
}
/* Process also the last block. */