static void rndr_tablerow(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) { HOEDOWN_BUFPUTSL(ob, "<tr>\n"); if (content) hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</tr>\n"); }
static int 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 = data->opaque; HOEDOWN_BUFPUTSL(ob, "<a href=\""); if (link && link->size) escape_href(ob, link->data, link->size); if (title && title->size) { HOEDOWN_BUFPUTSL(ob, "\" title=\""); escape_html(ob, title->data, title->size); } if (state->link_attributes) { hoedown_buffer_putc(ob, '\"'); state->link_attributes(ob, link, data); hoedown_buffer_putc(ob, '>'); } else { HOEDOWN_BUFPUTSL(ob, "\">"); } if (content && content->size) hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</a>"); return 1; }
static int rndr_link(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *content, void *opaque) { hoedown_html_renderer_state *state = opaque; if (link != NULL && (state->flags & HOEDOWN_HTML_SAFELINK) != 0 && !hoedown_autolink_is_safe(link->data, link->size)) return 0; HOEDOWN_BUFPUTSL(ob, "<a href=\""); if (link && link->size) escape_href(ob, link->data, link->size); if (title && title->size) { HOEDOWN_BUFPUTSL(ob, "\" title=\""); escape_html(ob, title->data, title->size); } if (state->link_attributes) { hoedown_buffer_putc(ob, '\"'); state->link_attributes(ob, link, opaque); hoedown_buffer_putc(ob, '>'); } else { HOEDOWN_BUFPUTSL(ob, "\">"); } if (content && content->size) hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</a>"); return 1; }
// rndr_blockcode from HEAD. The "language-" prefix in class in needed to make // the HTML compatible with Prism. void hoedown_patch_render_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'); if (lang) { hoedown_html_renderer_state_extra *extra = ((hoedown_html_renderer_state *)data->opaque)->opaque; hoedown_buffer *mapped = NULL; if (extra->language_addition) mapped = extra->language_addition(lang, extra->owner); HOEDOWN_BUFPUTSL(ob, "<pre><code class=\"language-"); if (mapped) { hoedown_escape_html(ob, mapped->data, mapped->size, 0); hoedown_buffer_free(mapped); } else { hoedown_escape_html(ob, lang->data, lang->size, 0); } HOEDOWN_BUFPUTSL(ob, "\">"); } else { HOEDOWN_BUFPUTSL(ob, "<pre><code>"); } if (text) hoedown_escape_html(ob, text->data, text->size, 0); HOEDOWN_BUFPUTSL(ob, "</code></pre>\n"); }
static void 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 (content) hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</blockquote>\n"); }
static void rndr_blockquote(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { if (ob->size) hoedown_buffer_putc(ob, '\n'); HOEDOWN_BUFPUTSL(ob, "<blockquote>\n"); if (text) hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</blockquote>\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 int rndr_codespan(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { HOEDOWN_BUFPUTSL(ob, "<code>"); if (text) escape_html(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</code>"); return 1; }
static void rndr_tablerow(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { HOEDOWN_BUFPUTSL(ob, "<tr>\n"); if (text) hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</tr>\n"); }
static int rndr_triple_emphasis(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { if (!text || !text->size) return 0; HOEDOWN_BUFPUTSL(ob, "<strong><em>"); hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</em></strong>"); return 1; }
static int rndr_superscript(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) { if (!content || !content->size) return 0; HOEDOWN_BUFPUTSL(ob, "<sup>"); hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</sup>"); return 1; }
static int rndr_triple_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) { if (!content || !content->size) return 0; HOEDOWN_BUFPUTSL(ob, "<strong><em>"); hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</em></strong>"); return 1; }
static int rndr_superscript(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { if (!text || !text->size) return 0; HOEDOWN_BUFPUTSL(ob, "<sup>"); hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</sup>"); return 1; }
static int 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); //Penner:Don't escape html if (text) hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</code>"); return 1; }
static int rndr_strikethrough(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) { if (!content || !content->size) return 0; HOEDOWN_BUFPUTSL(ob, "<del>"); hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</del>"); return 1; }
static int rndr_strikethrough(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { if (!text || !text->size) return 0; HOEDOWN_BUFPUTSL(ob, "<del>"); hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</del>"); return 1; }
static int rndr_underline(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { if (!text || !text->size) return 0; HOEDOWN_BUFPUTSL(ob, "<u>"); hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</u>"); return 1; }
static int rndr_highlight(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) { if (!content || !content->size) return 0; HOEDOWN_BUFPUTSL(ob, "<mark>"); hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "</mark>"); return 1; }
static void rndr_table(hoedown_buffer *ob, const hoedown_buffer *header, const hoedown_buffer *body, void *opaque) { 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"); }
static int rndr_highlight(hoedown_buffer *ob, const hoedown_buffer *text, void *opaque) { if (!text || !text->size) return 0; HOEDOWN_BUFPUTSL(ob, "<mark>"); hoedown_buffer_put(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</mark>"); return 1; }
static void rndr_listitem(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data) { HOEDOWN_BUFPUTSL(ob, "<li>"); if (content) { size_t size = content->size; while (size && content->data[size - 1] == '\n') size--; hoedown_buffer_put(ob, content->data, size); } HOEDOWN_BUFPUTSL(ob, "</li>\n"); }
static void rndr_listitem(hoedown_buffer *ob, const hoedown_buffer *text, unsigned int flags, void *opaque) { HOEDOWN_BUFPUTSL(ob, "<li>"); if (text) { size_t size = text->size; while (size && text->data[size - 1] == '\n') size--; hoedown_buffer_put(ob, text->data, size); } HOEDOWN_BUFPUTSL(ob, "</li>\n"); }
static void rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *text, unsigned int flags, void *opaque) { if (flags & HOEDOWN_TABLE_HEADER) { HOEDOWN_BUFPUTSL(ob, "<th"); } else { HOEDOWN_BUFPUTSL(ob, "<td"); } switch (flags & HOEDOWN_TABLE_ALIGNMASK) { case HOEDOWN_TABLE_ALIGN_CENTER: HOEDOWN_BUFPUTSL(ob, " style=\"text-align: center\">"); break; case HOEDOWN_TABLE_ALIGN_LEFT: HOEDOWN_BUFPUTSL(ob, " style=\"text-align: left\">"); break; case HOEDOWN_TABLE_ALIGN_RIGHT: HOEDOWN_BUFPUTSL(ob, " style=\"text-align: right\">"); break; default: HOEDOWN_BUFPUTSL(ob, ">"); } if (text) hoedown_buffer_put(ob, text->data, text->size); if (flags & HOEDOWN_TABLE_HEADER) { HOEDOWN_BUFPUTSL(ob, "</th>\n"); } else { HOEDOWN_BUFPUTSL(ob, "</td>\n"); } }
static void 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"); } else { HOEDOWN_BUFPUTSL(ob, "<td"); } switch (flags & HOEDOWN_TABLE_ALIGNMASK) { case HOEDOWN_TABLE_ALIGN_CENTER: HOEDOWN_BUFPUTSL(ob, " style=\"text-align: center\">"); break; case HOEDOWN_TABLE_ALIGN_LEFT: HOEDOWN_BUFPUTSL(ob, " style=\"text-align: left\">"); break; case HOEDOWN_TABLE_ALIGN_RIGHT: HOEDOWN_BUFPUTSL(ob, " style=\"text-align: right\">"); break; default: HOEDOWN_BUFPUTSL(ob, ">"); } if (content) hoedown_buffer_put(ob, content->data, content->size); if (flags & HOEDOWN_TABLE_HEADER) { HOEDOWN_BUFPUTSL(ob, "</th>\n"); } else { HOEDOWN_BUFPUTSL(ob, "</td>\n"); } }
static void rndr_footnotes(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data) { 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 (content) hoedown_buffer_put(ob, content->data, content->size); HOEDOWN_BUFPUTSL(ob, "\n</ol>\n</div>\n"); }
// rndr_blockcode from HEAD. The "language-" prefix in class in needed to make // the HTML compatible with Prism. void hoedown_patch_render_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'); hoedown_html_renderer_state *state = data->opaque; hoedown_buffer *front = NULL; hoedown_buffer *back = NULL; if (lang && USE_BLOCKCODE_INFORMATION(state)) { front = hoedown_buffer_new(lang->size); back = hoedown_buffer_new(lang->size); hoedown_buffer *current = front; for (size_t i = 0; i < lang->size; i++) { uint8_t c = lang->data[i]; if (current == front && c == ':') current = back; else hoedown_buffer_putc(current, c); } lang = front; } HOEDOWN_BUFPUTSL(ob, "<pre"); if (state->flags & HOEDOWN_HTML_BLOCKCODE_LINE_NUMBERS) HOEDOWN_BUFPUTSL(ob, " class=\"line-numbers\""); if (back && back->size) { HOEDOWN_BUFPUTSL(ob, " data-information=\""); hoedown_buffer_put(ob, back->data, back->size); HOEDOWN_BUFPUTSL(ob, "\""); } HOEDOWN_BUFPUTSL(ob, "><code class=\"language-"); if (lang && lang->size) hoedown_escape_html(ob, lang->data, lang->size, 0); else HOEDOWN_BUFPUTSL(ob, "none"); HOEDOWN_BUFPUTSL(ob, "\">"); if (text) { // Remove last newline to prevent prism from adding a blank line at the // end of code blocks. size_t size = text->size; if (size > 0 && text->data[size - 1] == '\n') size--; hoedown_escape_html(ob, text->data, size, 0); } HOEDOWN_BUFPUTSL(ob, "</code></pre>\n"); hoedown_buffer_free(front); hoedown_buffer_free(back); }
// Supports task list syntax if HOEDOWN_HTML_USE_TASK_LIST is on. // Implementation based on hoextdown. void hoedown_patch_render_listitem( hoedown_buffer *ob, const hoedown_buffer *text, hoedown_list_flags flags, const hoedown_renderer_data *data) { if (text) { hoedown_html_renderer_state *state = data->opaque; size_t offset = 0; if (flags & HOEDOWN_LI_BLOCK) offset = 3; // Do task list checkbox ([x] or [ ]). if (USE_TASK_LIST(state) && text->size >= 3) { if (strncmp((char *)(text->data + offset), "[ ]", 3) == 0) { HOEDOWN_BUFPUTSL(ob, "<li class=\"task-list-item\">"); hoedown_buffer_put(ob, text->data, offset); if (USE_XHTML(state)) HOEDOWN_BUFPUTSL(ob, "<input type=\"checkbox\" />"); else HOEDOWN_BUFPUTSL(ob, "<input type=\"checkbox\">"); offset += 3; } else if (strncmp((char *)(text->data + offset), "[x]", 3) == 0) { HOEDOWN_BUFPUTSL(ob, "<li class=\"task-list-item\">"); hoedown_buffer_put(ob, text->data, offset); if (USE_XHTML(state)) HOEDOWN_BUFPUTSL(ob, "<input type=\"checkbox\" checked />"); else HOEDOWN_BUFPUTSL(ob, "<input type=\"checkbox\" checked>"); offset += 3; } else { HOEDOWN_BUFPUTSL(ob, "<li>"); offset = 0; } } else { HOEDOWN_BUFPUTSL(ob, "<li>"); offset = 0; } size_t size = text->size; while (size && text->data[size - offset - 1] == '\n') size--; hoedown_buffer_put(ob, text->data + offset, size - offset); } HOEDOWN_BUFPUTSL(ob, "</li>\n"); }
static void rndr_footnote_def(hoedown_buffer *ob, const hoedown_buffer *text, unsigned int num, void *opaque) { 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; i -= 3; pfound = 1; break; } } hoedown_buffer_printf(ob, "\n<li id=\"fn%d\">\n", num); if (pfound) { hoedown_buffer_put(ob, text->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_BUFPUTSL(ob, "</li>\n"); }
static void rndr_blockcode(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, void *opaque) { if (ob->size) hoedown_buffer_putc(ob, '\n'); if (lang) { HOEDOWN_BUFPUTSL(ob, "<pre><code class=\"language-"); escape_html(ob, lang->data, lang->size); HOEDOWN_BUFPUTSL(ob, "\">"); } else { HOEDOWN_BUFPUTSL(ob, "<pre><code>"); } if (text) escape_html(ob, text->data, text->size); HOEDOWN_BUFPUTSL(ob, "</code></pre>\n"); }
static void toc_finalize(hoedown_buffer *ob, void *opaque) { hoedown_html_renderer_state *state = opaque; while (state->toc_data.current_level > 0) { HOEDOWN_BUFPUTSL(ob, "</li>\n</ul>\n"); state->toc_data.current_level--; } }