commit
758951ba6d
4 changed files with 239 additions and 198 deletions
116
src/document.c
116
src/document.c
|
@ -114,9 +114,9 @@ static char_trigger markdown_char_ptrs[] = {
|
|||
&char_math
|
||||
};
|
||||
|
||||
/* render • structure containing state for a parser instance */
|
||||
struct hoedown_document {
|
||||
hoedown_renderer md;
|
||||
hoedown_renderer_data data;
|
||||
|
||||
struct link_ref *refs[REF_TABLE_SIZE];
|
||||
struct footnote_list footnotes_found;
|
||||
|
@ -475,7 +475,7 @@ parse_inline(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t si
|
|||
if (doc->md.normal_text) {
|
||||
work.data = data + i;
|
||||
work.size = end - i;
|
||||
doc->md.normal_text(ob, &work, doc->md.opaque);
|
||||
doc->md.normal_text(ob, &work, &doc->data);
|
||||
}
|
||||
else
|
||||
hoedown_buffer_put(ob, data + i, end - i);
|
||||
|
@ -627,9 +627,9 @@ parse_emph1(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t siz
|
|||
parse_inline(work, doc, data, i);
|
||||
|
||||
if (doc->ext_flags & HOEDOWN_EXT_UNDERLINE && c == '_')
|
||||
r = doc->md.underline(ob, work, doc->md.opaque);
|
||||
r = doc->md.underline(ob, work, &doc->data);
|
||||
else
|
||||
r = doc->md.emphasis(ob, work, doc->md.opaque);
|
||||
r = doc->md.emphasis(ob, work, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
return r ? i + 1 : 0;
|
||||
|
@ -657,11 +657,11 @@ parse_emph2(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t siz
|
|||
parse_inline(work, doc, data, i);
|
||||
|
||||
if (c == '~')
|
||||
r = doc->md.strikethrough(ob, work, doc->md.opaque);
|
||||
r = doc->md.strikethrough(ob, work, &doc->data);
|
||||
else if (c == '=')
|
||||
r = doc->md.highlight(ob, work, doc->md.opaque);
|
||||
r = doc->md.highlight(ob, work, &doc->data);
|
||||
else
|
||||
r = doc->md.double_emphasis(ob, work, doc->md.opaque);
|
||||
r = doc->md.double_emphasis(ob, work, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
return r ? i + 2 : 0;
|
||||
|
@ -693,7 +693,7 @@ parse_emph3(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t siz
|
|||
hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
|
||||
|
||||
parse_inline(work, doc, data, i);
|
||||
r = doc->md.triple_emphasis(ob, work, doc->md.opaque);
|
||||
r = doc->md.triple_emphasis(ob, work, &doc->data);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
return r ? i + 3 : 0;
|
||||
|
||||
|
@ -741,7 +741,7 @@ parse_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offs
|
|||
displaymode = is_empty_all(data - offset, offset) && is_empty_all(data + i, size - i);
|
||||
|
||||
/* call callback */
|
||||
if (doc->md.math(ob, &text, displaymode, doc->md.opaque))
|
||||
if (doc->md.math(ob, &text, displaymode, &doc->data))
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
@ -796,7 +796,7 @@ char_linebreak(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
while (ob->size && ob->data[ob->size - 1] == ' ')
|
||||
ob->size--;
|
||||
|
||||
return doc->md.linebreak(ob, doc->md.opaque) ? 1 : 0;
|
||||
return doc->md.linebreak(ob, &doc->data) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -832,10 +832,10 @@ char_codespan(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t o
|
|||
/* real code span */
|
||||
if (f_begin < f_end) {
|
||||
hoedown_buffer work = { data + f_begin, f_end - f_begin, 0, 0, NULL, NULL, NULL };
|
||||
if (!doc->md.codespan(ob, &work, doc->md.opaque))
|
||||
if (!doc->md.codespan(ob, &work, &doc->data))
|
||||
end = 0;
|
||||
} else {
|
||||
if (!doc->md.codespan(ob, 0, doc->md.opaque))
|
||||
if (!doc->md.codespan(ob, 0, &doc->data))
|
||||
end = 0;
|
||||
}
|
||||
|
||||
|
@ -877,11 +877,11 @@ char_quote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offs
|
|||
hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
|
||||
parse_inline(work, doc, data + f_begin, f_end - f_begin);
|
||||
|
||||
if (!doc->md.quote(ob, work, doc->md.opaque))
|
||||
if (!doc->md.quote(ob, work, &doc->data))
|
||||
end = 0;
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
} else {
|
||||
if (!doc->md.quote(ob, 0, doc->md.opaque))
|
||||
if (!doc->md.quote(ob, 0, &doc->data))
|
||||
end = 0;
|
||||
}
|
||||
|
||||
|
@ -911,7 +911,7 @@ char_escape(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t off
|
|||
if (doc->md.normal_text) {
|
||||
work.data = data + 1;
|
||||
work.size = 1;
|
||||
doc->md.normal_text(ob, &work, doc->md.opaque);
|
||||
doc->md.normal_text(ob, &work, &doc->data);
|
||||
}
|
||||
else hoedown_buffer_putc(ob, data[1]);
|
||||
} else if (size == 1) {
|
||||
|
@ -943,7 +943,7 @@ char_entity(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t off
|
|||
if (doc->md.entity) {
|
||||
work.data = data;
|
||||
work.size = end;
|
||||
doc->md.entity(ob, &work, doc->md.opaque);
|
||||
doc->md.entity(ob, &work, &doc->data);
|
||||
}
|
||||
else hoedown_buffer_put(ob, data, end);
|
||||
|
||||
|
@ -965,11 +965,11 @@ char_langle_tag(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
work.data = data + 1;
|
||||
work.size = end - 2;
|
||||
unscape_text(u_link, &work);
|
||||
ret = doc->md.autolink(ob, u_link, altype, doc->md.opaque);
|
||||
ret = doc->md.autolink(ob, u_link, altype, &doc->data);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
}
|
||||
else if (doc->md.raw_html_tag)
|
||||
ret = doc->md.raw_html_tag(ob, &work, doc->md.opaque);
|
||||
else if (doc->md.raw_html)
|
||||
ret = doc->md.raw_html(ob, &work, &doc->data);
|
||||
}
|
||||
|
||||
if (!ret) return 0;
|
||||
|
@ -995,11 +995,11 @@ char_autolink_www(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size
|
|||
ob->size -= rewind;
|
||||
if (doc->md.normal_text) {
|
||||
link_text = newbuf(doc, BUFFER_SPAN);
|
||||
doc->md.normal_text(link_text, link, doc->md.opaque);
|
||||
doc->md.link(ob, link_url, NULL, link_text, doc->md.opaque);
|
||||
doc->md.normal_text(link_text, link, &doc->data);
|
||||
doc->md.link(ob, link_text, link_url, NULL, &doc->data);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
} else {
|
||||
doc->md.link(ob, link_url, NULL, link, doc->md.opaque);
|
||||
doc->md.link(ob, link, link_url, NULL, &doc->data);
|
||||
}
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
}
|
||||
|
@ -1021,7 +1021,7 @@ char_autolink_email(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, si
|
|||
|
||||
if ((link_len = hoedown_autolink__email(&rewind, link, data, offset, size, 0)) > 0) {
|
||||
ob->size -= rewind;
|
||||
doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_EMAIL, doc->md.opaque);
|
||||
doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_EMAIL, &doc->data);
|
||||
}
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
|
@ -1041,7 +1041,7 @@ char_autolink_url(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size
|
|||
|
||||
if ((link_len = hoedown_autolink__url(&rewind, link, data, offset, size, 0)) > 0) {
|
||||
ob->size -= rewind;
|
||||
doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_NORMAL, doc->md.opaque);
|
||||
doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_NORMAL, &doc->data);
|
||||
}
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
|
@ -1096,7 +1096,7 @@ char_link(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offse
|
|||
|
||||
/* render */
|
||||
if (doc->md.footnote_ref)
|
||||
ret = doc->md.footnote_ref(ob, fr->num, doc->md.opaque);
|
||||
ret = doc->md.footnote_ref(ob, fr->num, &doc->data);
|
||||
}
|
||||
|
||||
goto cleanup;
|
||||
|
@ -1261,9 +1261,9 @@ char_link(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offse
|
|||
if (ob->size && ob->data[ob->size - 1] == '!')
|
||||
ob->size -= 1;
|
||||
|
||||
ret = doc->md.image(ob, u_link, title, content, doc->md.opaque);
|
||||
ret = doc->md.image(ob, u_link, title, content, &doc->data);
|
||||
} else {
|
||||
ret = doc->md.link(ob, u_link, title, content, doc->md.opaque);
|
||||
ret = doc->md.link(ob, content, u_link, title, &doc->data);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
|
@ -1302,7 +1302,7 @@ char_superscript(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_
|
|||
|
||||
sup = newbuf(doc, BUFFER_SPAN);
|
||||
parse_inline(sup, doc, data + sup_start, sup_len - sup_start);
|
||||
doc->md.superscript(ob, sup, doc->md.opaque);
|
||||
doc->md.superscript(ob, sup, &doc->data);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
|
||||
return (sup_start == 2) ? sup_len + 1 : sup_len;
|
||||
|
@ -1606,7 +1606,7 @@ parse_blockquote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_
|
|||
|
||||
parse_block(out, doc, work_data, work_size);
|
||||
if (doc->md.blockquote)
|
||||
doc->md.blockquote(ob, out, doc->md.opaque);
|
||||
doc->md.blockquote(ob, out, &doc->data);
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
return end;
|
||||
}
|
||||
|
@ -1649,7 +1649,7 @@ parse_paragraph(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK);
|
||||
parse_inline(tmp, doc, work.data, work.size);
|
||||
if (doc->md.paragraph)
|
||||
doc->md.paragraph(ob, tmp, doc->md.opaque);
|
||||
doc->md.paragraph(ob, tmp, &doc->data);
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
} else {
|
||||
hoedown_buffer *header_work;
|
||||
|
@ -1671,7 +1671,7 @@ parse_paragraph(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
parse_inline(tmp, doc, work.data, work.size);
|
||||
|
||||
if (doc->md.paragraph)
|
||||
doc->md.paragraph(ob, tmp, doc->md.opaque);
|
||||
doc->md.paragraph(ob, tmp, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
work.data += beg;
|
||||
|
@ -1684,7 +1684,7 @@ parse_paragraph(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
parse_inline(header_work, doc, work.data, work.size);
|
||||
|
||||
if (doc->md.header)
|
||||
doc->md.header(ob, header_work, (int)level, doc->md.opaque);
|
||||
doc->md.header(ob, header_work, (int)level, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
}
|
||||
|
@ -1725,7 +1725,7 @@ parse_fencedcode(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_
|
|||
text.size = line_start - text_start;
|
||||
|
||||
if (doc->md.blockcode)
|
||||
doc->md.blockcode(ob, text.size ? &text : NULL, lang.size ? &lang : NULL, doc->md.opaque);
|
||||
doc->md.blockcode(ob, text.size ? &text : NULL, lang.size ? &lang : NULL, &doc->data);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -1765,7 +1765,7 @@ parse_blockcode(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
hoedown_buffer_putc(work, '\n');
|
||||
|
||||
if (doc->md.blockcode)
|
||||
doc->md.blockcode(ob, work, NULL, doc->md.opaque);
|
||||
doc->md.blockcode(ob, work, NULL, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
return beg;
|
||||
|
@ -1901,7 +1901,7 @@ parse_listitem(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
|
||||
/* render of li itself */
|
||||
if (doc->md.listitem)
|
||||
doc->md.listitem(ob, inter, *flags, doc->md.opaque);
|
||||
doc->md.listitem(ob, inter, *flags, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
|
@ -1927,7 +1927,7 @@ parse_list(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size
|
|||
}
|
||||
|
||||
if (doc->md.list)
|
||||
doc->md.list(ob, work, flags, doc->md.opaque);
|
||||
doc->md.list(ob, work, flags, &doc->data);
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
return i;
|
||||
}
|
||||
|
@ -1959,7 +1959,7 @@ parse_atxheader(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
parse_inline(work, doc, data + i, end - i);
|
||||
|
||||
if (doc->md.header)
|
||||
doc->md.header(ob, work, (int)level, doc->md.opaque);
|
||||
doc->md.header(ob, work, (int)level, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
}
|
||||
|
@ -1977,7 +1977,7 @@ parse_footnote_def(hoedown_buffer *ob, hoedown_document *doc, unsigned int num,
|
|||
parse_block(work, doc, data, size);
|
||||
|
||||
if (doc->md.footnote_def)
|
||||
doc->md.footnote_def(ob, work, num, doc->md.opaque);
|
||||
doc->md.footnote_def(ob, work, num, &doc->data);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
}
|
||||
|
||||
|
@ -2002,7 +2002,7 @@ parse_footnote_list(hoedown_buffer *ob, hoedown_document *doc, struct footnote_l
|
|||
}
|
||||
|
||||
if (doc->md.footnotes)
|
||||
doc->md.footnotes(ob, work, doc->md.opaque);
|
||||
doc->md.footnotes(ob, work, &doc->data);
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
}
|
||||
|
||||
|
@ -2120,7 +2120,7 @@ parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
if (j) {
|
||||
work.size = i + j;
|
||||
if (do_render && doc->md.blockhtml)
|
||||
doc->md.blockhtml(ob, &work, doc->md.opaque);
|
||||
doc->md.blockhtml(ob, &work, &doc->data);
|
||||
return work.size;
|
||||
}
|
||||
}
|
||||
|
@ -2137,7 +2137,7 @@ parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
if (j) {
|
||||
work.size = i + j;
|
||||
if (do_render && doc->md.blockhtml)
|
||||
doc->md.blockhtml(ob, &work, doc->md.opaque);
|
||||
doc->md.blockhtml(ob, &work, &doc->data);
|
||||
return work.size;
|
||||
}
|
||||
}
|
||||
|
@ -2162,7 +2162,7 @@ parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
|
|||
/* the end of the block has been found */
|
||||
work.size = tag_end;
|
||||
if (do_render && doc->md.blockhtml)
|
||||
doc->md.blockhtml(ob, &work, doc->md.opaque);
|
||||
doc->md.blockhtml(ob, &work, &doc->data);
|
||||
|
||||
return tag_end;
|
||||
}
|
||||
|
@ -2208,7 +2208,7 @@ parse_table_row(
|
|||
cell_end--;
|
||||
|
||||
parse_inline(cell_work, doc, data + cell_start, 1 + cell_end - cell_start);
|
||||
doc->md.table_cell(row_work, cell_work, col_data[col] | header_flag, doc->md.opaque);
|
||||
doc->md.table_cell(row_work, cell_work, col_data[col] | header_flag, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
i++;
|
||||
|
@ -2216,10 +2216,10 @@ parse_table_row(
|
|||
|
||||
for (; col < columns; ++col) {
|
||||
hoedown_buffer empty_cell = { 0, 0, 0, 0, NULL, NULL, NULL };
|
||||
doc->md.table_cell(row_work, &empty_cell, col_data[col] | header_flag, doc->md.opaque);
|
||||
doc->md.table_cell(row_work, &empty_cell, col_data[col] | header_flag, &doc->data);
|
||||
}
|
||||
|
||||
doc->md.table_row(ob, row_work, doc->md.opaque);
|
||||
doc->md.table_row(ob, row_work, &doc->data);
|
||||
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
}
|
||||
|
@ -2325,12 +2325,14 @@ parse_table(
|
|||
{
|
||||
size_t i;
|
||||
|
||||
hoedown_buffer *work = 0;
|
||||
hoedown_buffer *header_work = 0;
|
||||
hoedown_buffer *body_work = 0;
|
||||
|
||||
size_t columns;
|
||||
hoedown_table_flags *col_data = NULL;
|
||||
|
||||
work = newbuf(doc, BUFFER_BLOCK);
|
||||
header_work = newbuf(doc, BUFFER_SPAN);
|
||||
body_work = newbuf(doc, BUFFER_BLOCK);
|
||||
|
||||
|
@ -2364,13 +2366,20 @@ parse_table(
|
|||
i++;
|
||||
}
|
||||
|
||||
if (doc->md.table_header)
|
||||
doc->md.table_header(work, header_work, &doc->data);
|
||||
|
||||
if (doc->md.table_body)
|
||||
doc->md.table_body(work, body_work, &doc->data);
|
||||
|
||||
if (doc->md.table)
|
||||
doc->md.table(ob, header_work, body_work, doc->md.opaque);
|
||||
doc->md.table(ob, work, &doc->data);
|
||||
}
|
||||
|
||||
free(col_data);
|
||||
popbuf(doc, BUFFER_SPAN);
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
popbuf(doc, BUFFER_BLOCK);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -2402,7 +2411,7 @@ parse_block(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t siz
|
|||
|
||||
else if (is_hrule(txt_data, end)) {
|
||||
if (doc->md.hrule)
|
||||
doc->md.hrule(ob, doc->md.opaque);
|
||||
doc->md.hrule(ob, &doc->data);
|
||||
|
||||
while (beg < size && data[beg] != '\n')
|
||||
beg++;
|
||||
|
@ -2702,6 +2711,8 @@ hoedown_document_new(
|
|||
doc = hoedown_malloc(sizeof(hoedown_document));
|
||||
memcpy(&doc->md, renderer, sizeof(hoedown_renderer));
|
||||
|
||||
doc->data.opaque = renderer->opaque;
|
||||
|
||||
hoedown_stack_init(&doc->work_bufs[BUFFER_BLOCK], 4);
|
||||
hoedown_stack_init(&doc->work_bufs[BUFFER_SPAN], 8);
|
||||
|
||||
|
@ -2815,7 +2826,7 @@ hoedown_document_render(hoedown_document *doc, hoedown_buffer *ob, const uint8_t
|
|||
|
||||
/* second pass: actual rendering */
|
||||
if (doc->md.doc_header)
|
||||
doc->md.doc_header(ob, doc->md.opaque);
|
||||
doc->md.doc_header(ob, 0, &doc->data);
|
||||
|
||||
if (text->size) {
|
||||
/* adding a final newline if not already present */
|
||||
|
@ -2830,7 +2841,7 @@ hoedown_document_render(hoedown_document *doc, hoedown_buffer *ob, const uint8_t
|
|||
parse_footnote_list(ob, doc, &doc->footnotes_used);
|
||||
|
||||
if (doc->md.doc_footer)
|
||||
doc->md.doc_footer(ob, doc->md.opaque);
|
||||
doc->md.doc_footer(ob, 0, &doc->data);
|
||||
|
||||
/* clean-up */
|
||||
hoedown_buffer_free(text);
|
||||
|
@ -2875,8 +2886,15 @@ hoedown_document_render_inline(hoedown_document *doc, hoedown_buffer *ob, const
|
|||
|
||||
/* second pass: actual rendering */
|
||||
hoedown_buffer_grow(ob, text->size + (text->size >> 1));
|
||||
|
||||
if (doc->md.doc_header)
|
||||
doc->md.doc_header(ob, 1, &doc->data);
|
||||
|
||||
parse_inline(ob, doc, text->data, text->size);
|
||||
|
||||
if (doc->md.doc_footer)
|
||||
doc->md.doc_footer(ob, 1, &doc->data);
|
||||
|
||||
/* clean-up */
|
||||
hoedown_buffer_free(text);
|
||||
|
||||
|
|
|
@ -85,57 +85,64 @@ typedef enum hoedown_autolink_type {
|
|||
* TYPES *
|
||||
*********/
|
||||
|
||||
struct hoedown_document;
|
||||
typedef struct hoedown_document hoedown_document;
|
||||
|
||||
struct hoedown_renderer_data {
|
||||
void *opaque;
|
||||
};
|
||||
typedef struct hoedown_renderer_data hoedown_renderer_data;
|
||||
|
||||
/* hoedown_renderer - functions for rendering parsed data */
|
||||
struct hoedown_renderer {
|
||||
/* state object */
|
||||
void *opaque;
|
||||
|
||||
/* block level callbacks - NULL skips the block */
|
||||
void (*blockcode)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, void *opaque);
|
||||
void (*blockquote)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
void (*blockhtml)(hoedown_buffer *ob,const hoedown_buffer *text, void *opaque);
|
||||
void (*header)(hoedown_buffer *ob, const hoedown_buffer *text, int level, void *opaque);
|
||||
void (*hrule)(hoedown_buffer *ob, void *opaque);
|
||||
void (*list)(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_list_flags flags, void *opaque);
|
||||
void (*listitem)(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_list_flags flags, void *opaque);
|
||||
void (*paragraph)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
void (*table)(hoedown_buffer *ob, const hoedown_buffer *header, const hoedown_buffer *body, void *opaque);
|
||||
void (*table_row)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
void (*table_cell)(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_table_flags flags, void *opaque);
|
||||
void (*footnotes)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
void (*footnote_def)(hoedown_buffer *ob, const hoedown_buffer *text, unsigned int num, void *opaque);
|
||||
void (*blockcode)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data);
|
||||
void (*blockquote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*header)(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data);
|
||||
void (*hrule)(hoedown_buffer *ob, const hoedown_renderer_data *data);
|
||||
void (*list)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data);
|
||||
void (*listitem)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data);
|
||||
void (*paragraph)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*table)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*table_header)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*table_body)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*table_row)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*table_cell)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data);
|
||||
void (*footnotes)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
void (*footnote_def)(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data);
|
||||
void (*blockhtml)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
|
||||
|
||||
/* span level callbacks - NULL or return 0 prints the span verbatim */
|
||||
int (*autolink)(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, void *opaque);
|
||||
int (*codespan)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*double_emphasis)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*emphasis)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*underline)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*highlight)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*quote)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*image)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, void *opaque);
|
||||
int (*linebreak)(hoedown_buffer *ob, void *opaque);
|
||||
int (*link)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *content, void *opaque);
|
||||
int (*raw_html_tag)(hoedown_buffer *ob, const hoedown_buffer *tag, void *opaque);
|
||||
int (*triple_emphasis)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*strikethrough)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*superscript)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
int (*footnote_ref)(hoedown_buffer *ob, unsigned int num, void *opaque);
|
||||
int (*math)(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, void *opaque);
|
||||
int (*autolink)(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data);
|
||||
int (*codespan)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
|
||||
int (*double_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*underline)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*highlight)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*quote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*image)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data);
|
||||
int (*linebreak)(hoedown_buffer *ob, const hoedown_renderer_data *data);
|
||||
int (*link)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data);
|
||||
int (*triple_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*strikethrough)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*superscript)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
|
||||
int (*footnote_ref)(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data);
|
||||
int (*math)(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data);
|
||||
int (*raw_html)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
|
||||
|
||||
/* low level callbacks - NULL copies input directly into the output */
|
||||
void (*entity)(hoedown_buffer *ob, const hoedown_buffer *entity, void *opaque);
|
||||
void (*normal_text)(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque);
|
||||
void (*entity)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
|
||||
void (*normal_text)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
|
||||
|
||||
/* header and footer */
|
||||
void (*doc_header)(hoedown_buffer *ob, void *opaque);
|
||||
void (*doc_footer)(hoedown_buffer *ob, void *opaque);
|
||||
/* miscellaneous callbacks */
|
||||
void (*doc_header)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);
|
||||
void (*doc_footer)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);
|
||||
};
|
||||
typedef struct hoedown_renderer hoedown_renderer;
|
||||
|
||||
struct hoedown_document;
|
||||
typedef struct hoedown_document hoedown_document;
|
||||
|
||||
|
||||
/*************
|
||||
* FUNCTIONS *
|
||||
|
|
238
src/html.c
238
src/html.c
|
@ -56,9 +56,9 @@ static inline void escape_href(hoedown_buffer *ob, const uint8_t *source, size_t
|
|||
* GENERIC RENDERER *
|
||||
********************/
|
||||
static int
|
||||
rndr_autolink(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, void *opaque)
|
||||
rndr_autolink(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
if (!link || !link->size)
|
||||
return 0;
|
||||
|
@ -70,7 +70,7 @@ rndr_autolink(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_t
|
|||
|
||||
if (state->link_attributes) {
|
||||
hoedown_buffer_putc(ob, '\"');
|
||||
state->link_attributes(ob, link, opaque);
|
||||
state->link_attributes(ob, link, data);
|
||||
hoedown_buffer_putc(ob, '>');
|
||||
} else {
|
||||
HOEDOWN_BUFPUTSL(ob, "\">");
|
||||
|
@ -93,7 +93,7 @@ rndr_autolink(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_t
|
|||
}
|
||||
|
||||
static void
|
||||
rndr_blockcode(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, void *opaque)
|
||||
rndr_blockcode(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
|
||||
|
@ -112,16 +112,16 @@ rndr_blockcode(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buf
|
|||
}
|
||||
|
||||
static void
|
||||
rndr_blockquote(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_blockquote(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
HOEDOWN_BUFPUTSL(ob, "<blockquote>\n");
|
||||
if (text) hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content) hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</blockquote>\n");
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_codespan(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_codespan(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)
|
||||
{
|
||||
HOEDOWN_BUFPUTSL(ob, "<code>");
|
||||
if (text) escape_html(ob, text->data, text->size);
|
||||
|
@ -130,91 +130,91 @@ rndr_codespan(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
|||
}
|
||||
|
||||
static int
|
||||
rndr_strikethrough(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_strikethrough(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size)
|
||||
if (!content || !content->size)
|
||||
return 0;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<del>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</del>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_double_emphasis(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_double_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size)
|
||||
if (!content || !content->size)
|
||||
return 0;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<strong>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</strong>");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_emphasis(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size) return 0;
|
||||
if (!content || !content->size) return 0;
|
||||
HOEDOWN_BUFPUTSL(ob, "<em>");
|
||||
if (text) hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content) hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</em>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_underline(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_underline(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size)
|
||||
if (!content || !content->size)
|
||||
return 0;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<u>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</u>");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_highlight(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_highlight(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size)
|
||||
if (!content || !content->size)
|
||||
return 0;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<mark>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</mark>");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_quote(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_quote(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size)
|
||||
if (!content || !content->size)
|
||||
return 0;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<q>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</q>");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_linebreak(hoedown_buffer *ob, void *opaque)
|
||||
rndr_linebreak(hoedown_buffer *ob, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
hoedown_buffer_puts(ob, USE_XHTML(state) ? "<br/>\n" : "<br>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_header(hoedown_buffer *ob, const hoedown_buffer *text, int level, void *opaque)
|
||||
rndr_header(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
if (ob->size)
|
||||
hoedown_buffer_putc(ob, '\n');
|
||||
|
@ -224,14 +224,14 @@ rndr_header(hoedown_buffer *ob, const hoedown_buffer *text, int level, void *opa
|
|||
else
|
||||
hoedown_buffer_printf(ob, "<h%d>", level);
|
||||
|
||||
if (text) hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content) hoedown_buffer_put(ob, content->data, content->size);
|
||||
hoedown_buffer_printf(ob, "</h%d>\n", level);
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_link(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *content, void *opaque)
|
||||
rndr_link(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<a href=\"");
|
||||
|
||||
|
@ -245,7 +245,7 @@ rndr_link(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *
|
|||
|
||||
if (state->link_attributes) {
|
||||
hoedown_buffer_putc(ob, '\"');
|
||||
state->link_attributes(ob, link, opaque);
|
||||
state->link_attributes(ob, link, data);
|
||||
hoedown_buffer_putc(ob, '>');
|
||||
} else {
|
||||
HOEDOWN_BUFPUTSL(ob, "\">");
|
||||
|
@ -257,73 +257,73 @@ rndr_link(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *
|
|||
}
|
||||
|
||||
static void
|
||||
rndr_list(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_list_flags flags, void *opaque)
|
||||
rndr_list(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "<ol>\n" : "<ul>\n"), 5);
|
||||
if (text) hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content) hoedown_buffer_put(ob, content->data, content->size);
|
||||
hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "</ol>\n" : "</ul>\n"), 6);
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_listitem(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_list_flags flags, void *opaque)
|
||||
rndr_listitem(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)
|
||||
{
|
||||
HOEDOWN_BUFPUTSL(ob, "<li>");
|
||||
if (text) {
|
||||
size_t size = text->size;
|
||||
while (size && text->data[size - 1] == '\n')
|
||||
if (content) {
|
||||
size_t size = content->size;
|
||||
while (size && content->data[size - 1] == '\n')
|
||||
size--;
|
||||
|
||||
hoedown_buffer_put(ob, text->data, size);
|
||||
hoedown_buffer_put(ob, content->data, size);
|
||||
}
|
||||
HOEDOWN_BUFPUTSL(ob, "</li>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_paragraph(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_paragraph(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
size_t i = 0;
|
||||
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
|
||||
if (!text || !text->size)
|
||||
if (!content || !content->size)
|
||||
return;
|
||||
|
||||
while (i < text->size && isspace(text->data[i])) i++;
|
||||
while (i < content->size && isspace(content->data[i])) i++;
|
||||
|
||||
if (i == text->size)
|
||||
if (i == content->size)
|
||||
return;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<p>");
|
||||
if (state->flags & HOEDOWN_HTML_HARD_WRAP) {
|
||||
size_t org;
|
||||
while (i < text->size) {
|
||||
while (i < content->size) {
|
||||
org = i;
|
||||
while (i < text->size && text->data[i] != '\n')
|
||||
while (i < content->size && content->data[i] != '\n')
|
||||
i++;
|
||||
|
||||
if (i > org)
|
||||
hoedown_buffer_put(ob, text->data + org, i - org);
|
||||
hoedown_buffer_put(ob, content->data + org, i - org);
|
||||
|
||||
/*
|
||||
* do not insert a line break if this newline
|
||||
* is the last character on the paragraph
|
||||
*/
|
||||
if (i >= text->size - 1)
|
||||
if (i >= content->size - 1)
|
||||
break;
|
||||
|
||||
rndr_linebreak(ob, opaque);
|
||||
rndr_linebreak(ob, data);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
hoedown_buffer_put(ob, &text->data[i], text->size - i);
|
||||
hoedown_buffer_put(ob, content->data + i, content->size - i);
|
||||
}
|
||||
HOEDOWN_BUFPUTSL(ob, "</p>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_raw_block(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_raw_block(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)
|
||||
{
|
||||
size_t org, sz;
|
||||
if (!text) return;
|
||||
|
@ -340,27 +340,27 @@ rndr_raw_block(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
|||
}
|
||||
|
||||
static int
|
||||
rndr_triple_emphasis(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_triple_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size) return 0;
|
||||
if (!content || !content->size) return 0;
|
||||
HOEDOWN_BUFPUTSL(ob, "<strong><em>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</em></strong>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_hrule(hoedown_buffer *ob, void *opaque)
|
||||
rndr_hrule(hoedown_buffer *ob, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
hoedown_buffer_puts(ob, USE_XHTML(state) ? "<hr/>\n" : "<hr>\n");
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_image(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, void *opaque)
|
||||
rndr_image(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
if (!link || !link->size) return 0;
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "<img src=\"");
|
||||
|
@ -379,9 +379,9 @@ rndr_image(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer
|
|||
}
|
||||
|
||||
static int
|
||||
rndr_raw_html(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_raw_html(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
/* ESCAPE overrides SKIP_HTML. It doesn't look to see if
|
||||
* there are any valid tags, just escapes all of them. */
|
||||
|
@ -398,29 +398,42 @@ rndr_raw_html(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
|||
}
|
||||
|
||||
static void
|
||||
rndr_table(hoedown_buffer *ob, const hoedown_buffer *header, const hoedown_buffer *body, void *opaque)
|
||||
rndr_table(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
HOEDOWN_BUFPUTSL(ob, "<table><thead>\n");
|
||||
if (header)
|
||||
hoedown_buffer_put(ob, header->data, header->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</thead><tbody>\n");
|
||||
if (body)
|
||||
hoedown_buffer_put(ob, body->data, body->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</tbody></table>\n");
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
HOEDOWN_BUFPUTSL(ob, "<table>\n");
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</table>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_tablerow(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_table_header(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
HOEDOWN_BUFPUTSL(ob, "<thead>\n");
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</thead>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_table_body(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
HOEDOWN_BUFPUTSL(ob, "<tbody>\n");
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</tbody>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_tablerow(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
HOEDOWN_BUFPUTSL(ob, "<tr>\n");
|
||||
if (text)
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content) hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</tr>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_table_flags flags, void *opaque)
|
||||
rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (flags & HOEDOWN_TABLE_HEADER) {
|
||||
HOEDOWN_BUFPUTSL(ob, "<th");
|
||||
|
@ -445,8 +458,8 @@ rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_table_fla
|
|||
HOEDOWN_BUFPUTSL(ob, ">");
|
||||
}
|
||||
|
||||
if (text)
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content)
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
|
||||
if (flags & HOEDOWN_TABLE_HEADER) {
|
||||
HOEDOWN_BUFPUTSL(ob, "</th>\n");
|
||||
|
@ -456,51 +469,50 @@ rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *text, hoedown_table_fla
|
|||
}
|
||||
|
||||
static int
|
||||
rndr_superscript(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_superscript(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (!text || !text->size) return 0;
|
||||
if (!content || !content->size) return 0;
|
||||
HOEDOWN_BUFPUTSL(ob, "<sup>");
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</sup>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_normal_text(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_normal_text(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (text)
|
||||
escape_html(ob, text->data, text->size);
|
||||
if (content)
|
||||
escape_html(ob, content->data, content->size);
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_footnotes(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque)
|
||||
rndr_footnotes(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
if (ob->size) hoedown_buffer_putc(ob, '\n');
|
||||
HOEDOWN_BUFPUTSL(ob, "<div class=\"footnotes\">\n");
|
||||
hoedown_buffer_puts(ob, USE_XHTML(state) ? "<hr/>\n" : "<hr>\n");
|
||||
HOEDOWN_BUFPUTSL(ob, "<ol>\n");
|
||||
|
||||
if (text)
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
if (content) hoedown_buffer_put(ob, content->data, content->size);
|
||||
|
||||
HOEDOWN_BUFPUTSL(ob, "\n</ol>\n</div>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
rndr_footnote_def(hoedown_buffer *ob, const hoedown_buffer *text, unsigned int num, void *opaque)
|
||||
rndr_footnote_def(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data)
|
||||
{
|
||||
size_t i = 0;
|
||||
int pfound = 0;
|
||||
|
||||
/* insert anchor at the end of first paragraph block */
|
||||
if (text) {
|
||||
while ((i+3) < text->size) {
|
||||
if (text->data[i++] != '<') continue;
|
||||
if (text->data[i++] != '/') continue;
|
||||
if (text->data[i++] != 'p' && text->data[i] != 'P') continue;
|
||||
if (text->data[i] != '>') continue;
|
||||
if (content) {
|
||||
while ((i+3) < content->size) {
|
||||
if (content->data[i++] != '<') continue;
|
||||
if (content->data[i++] != '/') continue;
|
||||
if (content->data[i++] != 'p' && content->data[i] != 'P') continue;
|
||||
if (content->data[i] != '>') continue;
|
||||
i -= 3;
|
||||
pfound = 1;
|
||||
break;
|
||||
|
@ -509,24 +521,24 @@ rndr_footnote_def(hoedown_buffer *ob, const hoedown_buffer *text, unsigned int n
|
|||
|
||||
hoedown_buffer_printf(ob, "\n<li id=\"fn%d\">\n", num);
|
||||
if (pfound) {
|
||||
hoedown_buffer_put(ob, text->data, i);
|
||||
hoedown_buffer_put(ob, content->data, i);
|
||||
hoedown_buffer_printf(ob, " <a href=\"#fnref%d\" rev=\"footnote\">↩</a>", num);
|
||||
hoedown_buffer_put(ob, text->data + i, text->size - i);
|
||||
} else if (text) {
|
||||
hoedown_buffer_put(ob, text->data, text->size);
|
||||
hoedown_buffer_put(ob, content->data + i, content->size - i);
|
||||
} else if (content) {
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
}
|
||||
HOEDOWN_BUFPUTSL(ob, "</li>\n");
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_footnote_ref(hoedown_buffer *ob, unsigned int num, void *opaque)
|
||||
rndr_footnote_ref(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_buffer_printf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\" rel=\"footnote\">%d</a></sup>", num, num, num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rndr_math(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, void *opaque)
|
||||
rndr_math(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\[" : "\\("), 2);
|
||||
escape_html(ob, text->data, text->size);
|
||||
|
@ -535,9 +547,9 @@ rndr_math(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, void
|
|||
}
|
||||
|
||||
static void
|
||||
toc_header(hoedown_buffer *ob, const hoedown_buffer *text, int level, void *opaque)
|
||||
toc_header(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
if (level <= state->toc_data.nesting_level) {
|
||||
/* set the level offset if this is the first header
|
||||
|
@ -564,23 +576,23 @@ toc_header(hoedown_buffer *ob, const hoedown_buffer *text, int level, void *opaq
|
|||
}
|
||||
|
||||
hoedown_buffer_printf(ob, "<a href=\"#toc_%d\">", state->toc_data.header_count++);
|
||||
if (text) escape_html(ob, text->data, text->size);
|
||||
if (content) escape_html(ob, content->data, content->size);
|
||||
HOEDOWN_BUFPUTSL(ob, "</a>\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
toc_link(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *content, void *opaque)
|
||||
toc_link(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data)
|
||||
{
|
||||
if (content && content->size)
|
||||
hoedown_buffer_put(ob, content->data, content->size);
|
||||
if (content && content->size) hoedown_buffer_put(ob, content->data, content->size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
toc_finalize(hoedown_buffer *ob, void *opaque)
|
||||
toc_finalize(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data)
|
||||
{
|
||||
hoedown_html_renderer_state *state = opaque;
|
||||
if (inline_render) return;
|
||||
hoedown_html_renderer_state *state = data->opaque;
|
||||
|
||||
while (state->toc_data.current_level > 0) {
|
||||
HOEDOWN_BUFPUTSL(ob, "</li>\n</ul>\n");
|
||||
|
@ -594,7 +606,6 @@ hoedown_html_toc_renderer_new(int nesting_level)
|
|||
static const hoedown_renderer cb_default = {
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
toc_header,
|
||||
|
@ -607,6 +618,9 @@ hoedown_html_toc_renderer_new(int nesting_level)
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
rndr_codespan,
|
||||
|
@ -618,12 +632,12 @@ hoedown_html_toc_renderer_new(int nesting_level)
|
|||
NULL,
|
||||
NULL,
|
||||
toc_link,
|
||||
NULL,
|
||||
rndr_triple_emphasis,
|
||||
rndr_strikethrough,
|
||||
rndr_superscript,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -657,17 +671,19 @@ hoedown_html_renderer_new(hoedown_html_flags render_flags, int nesting_level)
|
|||
|
||||
rndr_blockcode,
|
||||
rndr_blockquote,
|
||||
rndr_raw_block,
|
||||
rndr_header,
|
||||
rndr_hrule,
|
||||
rndr_list,
|
||||
rndr_listitem,
|
||||
rndr_paragraph,
|
||||
rndr_table,
|
||||
rndr_table_header,
|
||||
rndr_table_body,
|
||||
rndr_tablerow,
|
||||
rndr_tablecell,
|
||||
rndr_footnotes,
|
||||
rndr_footnote_def,
|
||||
rndr_raw_block,
|
||||
|
||||
rndr_autolink,
|
||||
rndr_codespan,
|
||||
|
@ -679,12 +695,12 @@ hoedown_html_renderer_new(hoedown_html_flags render_flags, int nesting_level)
|
|||
rndr_image,
|
||||
rndr_linebreak,
|
||||
rndr_link,
|
||||
rndr_raw_html,
|
||||
rndr_triple_emphasis,
|
||||
rndr_strikethrough,
|
||||
rndr_superscript,
|
||||
rndr_footnote_ref,
|
||||
rndr_math,
|
||||
rndr_raw_html,
|
||||
|
||||
NULL,
|
||||
rndr_normal_text,
|
||||
|
|
|
@ -46,7 +46,7 @@ struct hoedown_html_renderer_state {
|
|||
hoedown_html_flags flags;
|
||||
|
||||
/* extra callbacks */
|
||||
void (*link_attributes)(hoedown_buffer *ob, const hoedown_buffer *url, void *self);
|
||||
void (*link_attributes)(hoedown_buffer *ob, const hoedown_buffer *url, const hoedown_renderer_data *data);
|
||||
};
|
||||
typedef struct hoedown_html_renderer_state hoedown_html_renderer_state;
|
||||
|
||||
|
|
Loading…
Reference in a new issue