示例#1
0
文件: markdown.c 项目: nono/upskirt
/* 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);
	}
}
示例#2
0
/* 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); } }
示例#3
0
/*	assuming initial prefix is already removed */
static size_t
parse_listitem(struct buf *ob, struct render *rndr,
			char *data, size_t size, int *flags) {
	struct buf *work = 0, *inter = 0;
	size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
	int in_empty = 0, has_inside_empty = 0;

	/* keeping book of the first indentation prefix */
	if (size > 1 && data[0] == ' ') { orgpre = 1;
	if (size > 2 && data[1] == ' ') { orgpre = 2;
	if (size > 3 && data[2] == ' ') { orgpre = 3; } } }
	beg = prefix_uli(data, size);
	if (!beg) beg = prefix_oli(data, size);
	if (!beg) return 0;
	/* skipping to the beginning of the following line */
	end = beg;
	while (end < size && data[end - 1] != '\n') end += 1;

	/* getting working buffers */
	work = new_work_buffer(rndr);
	inter = new_work_buffer(rndr);

	/* putting the first line into the working buffer */
	bufput(work, data + beg, end - beg);
	beg = end;

	/* process the following lines */
	while (beg < size) {
		end += 1;
		while (end < size && data[end - 1] != '\n') end += 1;

		/* process an empty line */
		if (is_empty(data + beg, end - beg)) {
			in_empty = 1;
			beg = end;
			continue; }

		/* calculating the indentation */
		i = 0;
		if (end - beg > 1 && data[beg] == ' ') { i = 1;
		if (end - beg > 2 && data[beg + 1] == ' ') { i = 2;
		if (end - beg > 3 && data[beg + 2] == ' ') { i = 3;
		if (end - beg > 3 && data[beg + 3] == ' ') { i = 4; } } } }
		pre = i;
		if (data[beg] == '\t') { i = 1; pre = 8; }

		/* checking for a new item */
		if ((prefix_uli(data + beg + i, end - beg - i)
			&& !is_hrule(data + beg + i, end - beg - i))
		||  prefix_oli(data + beg + i, end - beg - i)) {
			if (in_empty) has_inside_empty = 1;
			if (pre == orgpre) /* the following item must have */
				break;             /* the same indentation */
			if (!sublist) sublist = work->size; }

		/* joining only indented stuff after empty lines */
		else if (in_empty && i < 4 && data[beg] != '\t') {
				*flags |= MKD_LI_END;
				break; }
		else if (in_empty) {
			bufputc(work, '\n');
			has_inside_empty = 1; }
		in_empty = 0;

		/* adding the line without prefix into the working buffer */
		bufput(work, data + beg + i, end - beg - i);
		beg = end; }

	/* render of li contents */
	if (has_inside_empty) *flags |= MKD_LI_BLOCK;
	if (*flags & MKD_LI_BLOCK) {
		/* intermediate render of block li */
		if (sublist && sublist < work->size) {
			parse_block(inter, rndr, work->data, sublist);
			parse_block(inter, rndr, work->data + sublist,
						work->size - sublist); }
		else
			parse_block(inter, rndr, work->data, work->size); }
	else {
		/* intermediate render of inline li */
		if (sublist && sublist < work->size) {
			parse_inline(inter, rndr, work->data, sublist);
			parse_block(inter, rndr, work->data + sublist,
						work->size - sublist); }
		else
			parse_inline(inter, rndr, work->data, work->size); }

	/* render of li itself */
	if (rndr->make.listitem)
		rndr->make.listitem(ob, inter, *flags, rndr->make.opaque);
	release_work_buffer(rndr, inter);
	release_work_buffer(rndr, work);
	return beg; }