Text-Markdown-Hoedown

 view release on metacpan or  search on metacpan

hoedown/src/document.c  view on Meta::CPAN


	hoedown_stack_init(&doc->work_bufs[BUFFER_BLOCK], 4);
	hoedown_stack_init(&doc->work_bufs[BUFFER_SPAN], 8);

	memset(doc->active_char, 0x0, 256);

	if (extensions & HOEDOWN_EXT_UNDERLINE && doc->md.underline) {
		doc->active_char['_'] = MD_CHAR_EMPHASIS;
	}

	if (doc->md.emphasis || doc->md.double_emphasis || doc->md.triple_emphasis) {
		doc->active_char['*'] = MD_CHAR_EMPHASIS;
		doc->active_char['_'] = MD_CHAR_EMPHASIS;
		if (extensions & HOEDOWN_EXT_STRIKETHROUGH)
			doc->active_char['~'] = MD_CHAR_EMPHASIS;
		if (extensions & HOEDOWN_EXT_HIGHLIGHT)
			doc->active_char['='] = MD_CHAR_EMPHASIS;
	}

	if (doc->md.codespan)
		doc->active_char['`'] = MD_CHAR_CODESPAN;

	if (doc->md.linebreak)
		doc->active_char['\n'] = MD_CHAR_LINEBREAK;

	if (doc->md.image || doc->md.link || doc->md.footnotes || doc->md.footnote_ref) {
		doc->active_char['['] = MD_CHAR_LINK;
		doc->active_char['!'] = MD_CHAR_IMAGE;
	}

	doc->active_char['<'] = MD_CHAR_LANGLE;
	doc->active_char['\\'] = MD_CHAR_ESCAPE;
	doc->active_char['&'] = MD_CHAR_ENTITY;

	if (extensions & HOEDOWN_EXT_AUTOLINK) {
		doc->active_char[':'] = MD_CHAR_AUTOLINK_URL;
		doc->active_char['@'] = MD_CHAR_AUTOLINK_EMAIL;
		doc->active_char['w'] = MD_CHAR_AUTOLINK_WWW;
	}

	if (extensions & HOEDOWN_EXT_SUPERSCRIPT)
		doc->active_char['^'] = MD_CHAR_SUPERSCRIPT;

	if (extensions & HOEDOWN_EXT_QUOTE)
		doc->active_char['"'] = MD_CHAR_QUOTE;

	if (extensions & HOEDOWN_EXT_MATH)
		doc->active_char['$'] = MD_CHAR_MATH;

	/* Extension data */
	doc->ext_flags = extensions;
	doc->max_nesting = max_nesting;
	doc->in_link_body = 0;

	return doc;
}

void
hoedown_document_render(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size)
{
	static const uint8_t UTF8_BOM[] = {0xEF, 0xBB, 0xBF};

	hoedown_buffer *text;
	size_t beg, end;

	int footnotes_enabled;

	text = hoedown_buffer_new(64);

	/* Preallocate enough space for our buffer to avoid expanding while copying */
	hoedown_buffer_grow(text, size);

	/* reset the references table */
	memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *));

	footnotes_enabled = doc->ext_flags & HOEDOWN_EXT_FOOTNOTES;

	/* reset the footnotes lists */
	if (footnotes_enabled) {
		memset(&doc->footnotes_found, 0x0, sizeof(doc->footnotes_found));
		memset(&doc->footnotes_used, 0x0, sizeof(doc->footnotes_used));
	}

	/* first pass: looking for references, copying everything else */
	beg = 0;

	/* Skip a possible UTF-8 BOM, even though the Unicode standard
	 * discourages having these in UTF-8 documents */
	if (size >= 3 && memcmp(data, UTF8_BOM, 3) == 0)
		beg += 3;

	while (beg < size) /* iterating over lines */
		if (footnotes_enabled && is_footnote(data, beg, size, &end, &doc->footnotes_found))
			beg = end;
		else if (is_ref(data, beg, size, &end, doc->refs))
			beg = end;
		else { /* skipping to the next line */
			end = beg;
			while (end < size && data[end] != '\n' && data[end] != '\r')
				end++;

			/* adding the line body if present */
			if (end > beg)
				expand_tabs(text, data + beg, end - beg);

			while (end < size && (data[end] == '\n' || data[end] == '\r')) {
				/* add one \n per newline */
				if (data[end] == '\n' || (end + 1 < size && data[end + 1] != '\n'))
					hoedown_buffer_putc(text, '\n');
				end++;
			}

			beg = end;
		}

	/* pre-grow the output buffer to minimize allocations */
	hoedown_buffer_grow(ob, text->size + (text->size >> 1));

	/* second pass: actual rendering */
	if (doc->md.doc_header)
		doc->md.doc_header(ob, 0, &doc->data);

	if (text->size) {
		/* adding a final newline if not already present */
		if (text->data[text->size - 1] != '\n' &&  text->data[text->size - 1] != '\r')
			hoedown_buffer_putc(text, '\n');

		parse_block(ob, doc, text->data, text->size);
	}

	/* footnotes */
	if (footnotes_enabled)
		parse_footnote_list(ob, doc, &doc->footnotes_used);

	if (doc->md.doc_footer)
		doc->md.doc_footer(ob, 0, &doc->data);

	/* clean-up */
	hoedown_buffer_free(text);
	free_link_refs(doc->refs);
	if (footnotes_enabled) {
		free_footnote_list(&doc->footnotes_found, 1);
		free_footnote_list(&doc->footnotes_used, 0);
	}

	assert(doc->work_bufs[BUFFER_SPAN].size == 0);
	assert(doc->work_bufs[BUFFER_BLOCK].size == 0);
}



( run in 0.662 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )