/* parse_block • parsing of one block, returning next char to parse */ static void parse_block(struct buf *ob, struct render *rndr, char *data, size_t size) { size_t beg, end, i; char *txt_data; beg = 0; if (rndr->work.size > rndr->max_nesting) return; while (beg < size) { txt_data = data + beg; end = size - beg; if (data[beg] == '#') beg += parse_atxheader(ob, rndr, txt_data, end); else if (data[beg] == '<' && rndr->make.blockhtml && (i = parse_htmlblock(ob, rndr, txt_data, end, 1)) != 0) beg += i; else if ((i = is_empty(txt_data, end)) != 0) beg += i; else if (is_hrule(txt_data, end)) { if (rndr->make.hrule) rndr->make.hrule(ob, rndr->make.opaque); while (beg < size && data[beg] != '\n') beg++; beg++; } else if ((rndr->ext_flags & MKDEXT_FENCED_CODE) != 0 && (i = parse_fencedcode(ob, rndr, txt_data, end)) != 0) beg += i; else if ((rndr->ext_flags & MKDEXT_TABLES) != 0 && (i = parse_table(ob, rndr, txt_data, end)) != 0) beg += i; else if (prefix_quote(txt_data, end)) beg += parse_blockquote(ob, rndr, txt_data, end); else if (prefix_code(txt_data, end)) beg += parse_blockcode(ob, rndr, txt_data, end); else if (prefix_uli(txt_data, end)) beg += parse_list(ob, rndr, txt_data, end, 0); else if (prefix_oli(txt_data, end)) beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED); else beg += parse_paragraph(ob, rndr, txt_data, end); } }
/* parse_block • parsing of one block, returning next char to parse */ static void parse_block(struct buf *ob, struct render *rndr, char *data, size_t size) { size_t beg, end, i; char *txt_data; int has_table = (rndr->make.table && rndr->make.table_row && rndr->make.table_cell); if (rndr->work.size > rndr->make.max_work_stack) { if (size) bufput(ob, data, size); return; } beg = 0; while (beg < size) { txt_data = data + beg; end = size - beg; if (data[beg] == '#') beg += parse_atxheader(ob, rndr, txt_data, end); else if (data[beg] == '<' && rndr->make.blockhtml && (i = parse_htmlblock(ob, rndr, txt_data, end)) != 0) beg += i; else if ((i = is_empty(txt_data, end)) != 0) beg += i; else if (is_hrule(txt_data, end)) { if (rndr->make.hrule) rndr->make.hrule(ob, rndr->make.opaque); while (beg < size && data[beg] != '\n') beg += 1; beg += 1; } else if (prefix_quote(txt_data, end)) beg += parse_blockquote(ob, rndr, txt_data, end); else if (prefix_code(txt_data, end)) beg += parse_blockcode(ob, rndr, txt_data, end); else if (prefix_uli(txt_data, end)) beg += parse_list(ob, rndr, txt_data, end, 0); else if (prefix_oli(txt_data, end)) beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED); else if (has_table && is_tableline(txt_data, end)) beg += parse_table(ob, rndr, txt_data, end); else beg += parse_paragraph(ob, rndr, txt_data, end); } }
/* parse_blockquote • hanldes parsing of a regular paragraph */ static size_t parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size) { size_t i = 0, end = 0; int level = 0; struct buf work = { data, 0, 0, 0, 0 }; /* volatile working buffer */ while (i < size) { for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */; if (is_empty(data + i, size - i) || (level = is_headerline(data + i, size - i)) != 0) break; if (rndr->ext_flags & MKDEXT_LAX_HTML_BLOCKS) { if (data[i] == '<' && rndr->make.blockhtml && parse_htmlblock(ob, rndr, data + i, size - i, 0)) { end = i; break; } } if (data[i] == '#' || is_hrule(data + i, size - i)) { end = i; break; } i = end; } work.size = i; while (work.size && data[work.size - 1] == '\n') work.size--; if (!level) { struct buf *tmp = rndr_newbuf(rndr); parse_inline(tmp, rndr, work.data, work.size); if (rndr->make.paragraph) rndr->make.paragraph(ob, tmp, rndr->make.opaque); rndr_popbuf(rndr); } else { struct buf *header_work; if (work.size) { size_t beg; i = work.size; work.size -= 1; while (work.size && data[work.size] != '\n') work.size -= 1; beg = work.size + 1; while (work.size && data[work.size - 1] == '\n') work.size -= 1; if (work.size > 0) { struct buf *tmp = rndr_newbuf(rndr); parse_inline(tmp, rndr, work.data, work.size); if (rndr->make.paragraph) rndr->make.paragraph(ob, tmp, rndr->make.opaque); rndr_popbuf(rndr); work.data += beg; work.size = i - beg; } else work.size = i; } header_work = rndr_newbuf(rndr); parse_inline(header_work, rndr, work.data, work.size); if (rndr->make.header) rndr->make.header(ob, header_work, (int)level, rndr->make.opaque); rndr_popbuf(rndr); } return end; }