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 )