Implement block quotes.
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 127 128 129 130 131 132 133
diff --git a/README.md b/README.md
index 16b98d4..7b9bc1d 100644
--- a/README.md
+++ b/README.md
@@ -92,7 +92,7 @@ more or less forms our to do list.
- [x] 4.9 Blank lines
- **Container Blocks:**
- - [ ] 5.1 Block quotes
+ - [x] 5.1 Block quotes
- [ ] 5.2 List items
- [ ] 5.3 Lists
diff --git a/md4c/md4c.c b/md4c/md4c.c
index 5be5103..2a3969b 100644
--- a/md4c/md4c.c
+++ b/md4c/md4c.c
@@ -4442,6 +4442,10 @@ md_line_contains_char(MD_CTX* ctx, OFF beg, CHAR ch, OFF* p_pos)
static int
md_is_container_compatible(const MD_CONTAINER* pivot, const MD_CONTAINER* container)
{
+ /* Block quote has no "items" like lists. */
+ if(container->ch == _T('>'))
+ return FALSE;
+
if(container->ch != pivot->ch)
return FALSE;
if(container->mark_indent > pivot->contents_indent)
@@ -4490,6 +4494,10 @@ md_enter_child_containers(MD_CTX* ctx, int n_children)
MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, MD_BLOCK_CONTAINER_OPENER));
break;
+ case _T('>'):
+ MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, MD_BLOCK_CONTAINER_OPENER));
+ break;
+
default:
MD_UNREACHABLE();
break;
@@ -4514,6 +4522,10 @@ md_leave_child_containers(MD_CTX* ctx, int n_keep)
MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_UL, MD_BLOCK_CONTAINER_CLOSER));
break;
+ case _T('>'):
+ MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, MD_BLOCK_CONTAINER_CLOSER));
+ break;
+
default:
MD_UNREACHABLE();
break;
@@ -4531,6 +4543,20 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
{
OFF off = beg;
+ /* Check for block quote mark. */
+ if(off < ctx->size && CH(off) == _T('>')) {
+ off++;
+ if(off < ctx->size && CH(off) == _T(' '))
+ off++;
+ p_container->ch = _T('>');
+ p_container->is_loose = FALSE;
+ p_container->mark_indent = indent;
+ /*p_container->contents_indent = indent+1; Not meaningful*/
+ *p_end = off;
+ return TRUE;
+ }
+
+ /* Check for list item bullet mark. */
if(off+1 < ctx->size && ISANYOF(off, _T("-+*")) && CH(off+1) == _T(' ')) {
p_container->ch = CH(off);
p_container->is_loose = FALSE;
@@ -4580,12 +4606,27 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
line->indent = md_line_indentation(ctx, off, &off);
line->beg = off;
- /* Given the indentation, determine how many of the current containers
- * are our parents. */
- while(n_parents < ctx->n_containers &&
- line->indent >= ctx->containers[n_parents].contents_indent)
- {
- line->indent -= ctx->containers[n_parents].contents_indent;
+ /* Given the indentation and block quote marks '>', determine how many of
+ * the current containers are our parents. */
+ while(n_parents < ctx->n_containers) {
+ MD_CONTAINER* c = &ctx->containers[n_parents];
+
+ if(c->ch == _T('>') && line->indent < ctx->code_indent_offset &&
+ off < ctx->size && CH(off) == _T('>'))
+ {
+ /* Block quote mark. */
+ off++;
+ if(off < ctx->size && CH(off) == _T(' '))
+ off++;
+ line->indent = md_line_indentation(ctx, off, &off);
+ line->beg = off;
+ } else if(c->ch != _T('>') && line->indent >= c->contents_indent) {
+ /* List. */
+ line->indent -= c->contents_indent;
+ } else {
+ break;
+ }
+
n_parents++;
}
@@ -4674,7 +4715,8 @@ redo:
/* Check whether we are Setext underline. */
if(line->indent < ctx->code_indent_offset && pivot_line->type == MD_LINE_TEXT
- && (CH(off) == _T('=') || CH(off) == _T('-')))
+ && (CH(off) == _T('=') || CH(off) == _T('-'))
+ && (n_parents == ctx->n_containers))
{
unsigned level;
@@ -4820,11 +4862,13 @@ done:
*p_end = off;
- /* If we belong to a list after seeing a blank line, the list is loose. */
+ /* 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) {
- MD_BLOCK* block = (MD_BLOCK*) (((char*)ctx->block_bytes) +
- ctx->containers[n_parents + n_brothers - 1].block_byte_off);
- block->flags |= MD_BLOCK_LOOSE_LIST;
+ 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);
+ block->flags |= MD_BLOCK_LOOSE_LIST;
+ }
}
/* Leave any containers we are not part of anymore. */