static int rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque) { struct html_renderopt *options = opaque; if (!link || !link->size) return 0; BUFPUTSL(ob, "<img src=\""); escape_href(ob, link->data, link->size); BUFPUTSL(ob, "\" alt=\""); if (alt && alt->size) escape_html(ob, alt->data, alt->size); if (title && title->size) { BUFPUTSL(ob, "\" title=\""); escape_html(ob, title->data, title->size); } bufputs(ob, USE_XHTML(options) ? "\"/>" : "\">"); return 1; }
static void rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) { struct html_renderopt *options = opaque; if (ob->size) bufputc(ob, '\n'); if (options->flags & HTML_TOC) { bufprintf(ob, "<h%d id=\"", level); if (options->toc_id_prefix) { bufputs(ob, options->toc_id_prefix); } bufprintf(ob, "toc_%d\">", options->toc_data.header_count++); } else { bufprintf(ob, "<h%d>", level); } if (text) bufput(ob, text->data, text->size); bufprintf(ob, "</h%d>\n", level); }
static void snudown_link_attr(struct buf *ob, const struct buf *link, void *opaque) { struct snudown_renderopt *options = opaque; if (options->nofollow) BUFPUTSL(ob, " rel=\"nofollow\""); /* If we have an option, if it is "_blank" which means to open a new tab, then we should check to make sure the item is not on the lightnet domain before outputting the target. We don't want to open new windows for links within the lightnet.is domain. */ if (options->target != NULL && (strcmp(options->target, "_blank") != 0 || strstr((const char*) link->data, options->domain) == 0) ) { BUFPUTSL(ob, " target=\""); bufputs(ob, options->target); bufputc(ob, '\"'); } }
static void toc_header(struct buf *ob, const struct buf *text, int level, void *opaque) { struct html_renderopt *options = opaque; /* set the level offset if this is the first header * we're parsing for the document */ if (options->toc_data.current_level == 0) { BUFPUTSL(ob, "<div class=\"toc\">\n"); options->toc_data.level_offset = level - 1; } level -= options->toc_data.level_offset; if (level > options->toc_data.current_level) { while (level > options->toc_data.current_level) { BUFPUTSL(ob, "<ul>\n<li>\n"); options->toc_data.current_level++; } } else if (level < options->toc_data.current_level) { BUFPUTSL(ob, "</li>\n"); while (level < options->toc_data.current_level) { BUFPUTSL(ob, "</ul>\n</li>\n"); options->toc_data.current_level--; } BUFPUTSL(ob,"<li>\n"); } else { BUFPUTSL(ob,"</li>\n<li>\n"); } BUFPUTSL(ob, "<a href=\"#"); if (options->toc_id_prefix) { bufputs(ob, options->toc_id_prefix); } bufprintf(ob, "toc_%d\">", options->toc_data.header_count++); if (text) escape_html(ob, text->data, text->size); BUFPUTSL(ob, "</a>\n"); }
static int rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque) { struct html_renderopt *options = opaque; if (link != NULL && (options->flags & HTML_SAFELINK) != 0 && !sd_autolink_issafe(link->data, link->size)) return 0; BUFPUTSL(ob, "<img src=\""); escape_href(ob, link->data, link->size); BUFPUTSL(ob, "\" alt=\""); if (alt && alt->size) escape_html(ob, alt->data, alt->size); if (title && title->size) { BUFPUTSL(ob, "\" title=\""); escape_html(ob, title->data, title->size); } bufputs(ob, USE_XHTML(options) ? "\"/>" : "\">"); return 1; }
static void rndr_paragraph(struct buf *ob, struct buf *text, void *opaque) { struct html_renderopt *options = opaque; size_t i = 0; if (ob->size) bufputc(ob, '\n'); if (!text || !text->size) return; while (i < text->size && isspace(text->data[i])) i++; if (i == text->size) return; BUFPUTSL(ob, "<p>"); if (options->flags & HTML_HARD_WRAP) { size_t org; while (i < text->size) { org = i; while (i < text->size && text->data[i] != '\n') i++; if (i > org) bufput(ob, text->data + org, i - org); if (i >= text->size) break; BUFPUTSL(ob, "<br"); bufputs(ob, options->close_tag); i++; } } else { bufput(ob, &text->data[i], text->size - i); } BUFPUTSL(ob, "</p>\n"); }
// Appends the marker "<elementcount>|", so we can later reference the // element by position void Parser::appendElementMarker(struct buf *ob) { std::ostringstream oss; oss << elementCount << '|'; bufputs(ob, oss.str().c_str()); }
static Rboolean render_to_html(struct buf *ib, struct buf *ob, SEXP Soptions, SEXP Sextensions) { struct sd_callbacks callbacks; struct html_renderopt renderopt; unsigned int exts=0, options=0; struct sd_markdown *markdown; struct buf *htmlbuf; Rboolean toc = FALSE, smarty = FALSE; /* Marshal extensions */ if (isString(Sextensions)) { int i; for (i = 0; i < LENGTH(Sextensions); i++) { if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "NO_INTRA_EMPHASIS") == 0) exts |= MKDEXT_NO_INTRA_EMPHASIS; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "TABLES") == 0) exts |= MKDEXT_TABLES; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "FENCED_CODE") == 0) exts |= MKDEXT_FENCED_CODE; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "AUTOLINK") == 0) exts |= MKDEXT_AUTOLINK; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "STRIKETHROUGH") == 0) exts |= MKDEXT_STRIKETHROUGH; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "LAX_SPACING") == 0) exts |= MKDEXT_LAX_SPACING; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "SPACE_HEADERS") == 0) exts |= MKDEXT_SPACE_HEADERS; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "SUPERSCRIPT") == 0) exts |= MKDEXT_SUPERSCRIPT; else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)), "LATEX_MATH") == 0) exts |= MKDEXT_LATEX_MATH; } } /* Marshal HTML options */ if (isString(Soptions)) { int i; for (i = 0; i < LENGTH(Soptions); i++) { if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "SKIP_HTML") == 0) options |= HTML_SKIP_HTML; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "SKIP_STYLE") == 0) options |= HTML_SKIP_STYLE; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "SKIP_IMAGES") == 0) options |= HTML_SKIP_IMAGES; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "SKIP_LINKS") == 0) options |= HTML_SKIP_LINKS; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "SAFELINK") == 0) options |= HTML_SAFELINK; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "TOC") == 0) { options |= HTML_TOC; toc = TRUE; } else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "HARD_WRAP") == 0) options |= HTML_HARD_WRAP; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "USE_XHTML") == 0) options |= HTML_USE_XHTML; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "ESCAPE") == 0) options |= HTML_ESCAPE; else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)), "SMARTYPANTS") == 0) smarty = TRUE; } } htmlbuf = bufnew(OUTPUT_UNIT); if (!htmlbuf) { RMD_WARNING_NOMEM; return FALSE; } if (toc==TRUE) { struct buf *tocbuf = bufnew(OUTPUT_UNIT); if (!tocbuf) { RMD_WARNING_NOMEM; return FALSE; } sdhtml_toc_renderer(&callbacks, &renderopt); markdown = sd_markdown_new(exts,16,&callbacks,(void *)&renderopt); if (!markdown) { RMD_WARNING_NOMEM; return FALSE; } sd_markdown_render(tocbuf, ib->data, ib->size, markdown); sd_markdown_free(markdown); bufputs(htmlbuf,"<div id=\"toc\">\n"); bufputs(htmlbuf,"<div id=\"toc_header\">Table of Contents</div>\n"); bufput(htmlbuf,tocbuf->data,tocbuf->size); bufputs(htmlbuf,"</div>\n"); bufputs(htmlbuf,"\n"); bufrelease(tocbuf); } sdhtml_renderer(&callbacks, &renderopt, options); markdown = sd_markdown_new(exts,16,&callbacks,(void *)&renderopt); if (!markdown) { RMD_WARNING_NOMEM; return FALSE; } sd_markdown_render(htmlbuf, ib->data, ib->size, markdown); sd_markdown_free(markdown); if (smarty==TRUE) { struct buf *smartybuf = bufnew(OUTPUT_UNIT); if (!smartybuf) { RMD_WARNING_NOMEM; return FALSE; } sdhtml_smartypants(smartybuf,htmlbuf->data,htmlbuf->size); bufrelease(htmlbuf); htmlbuf = smartybuf; } bufput(ob,htmlbuf->data,htmlbuf->size); bufrelease(htmlbuf); return TRUE; }
int rinku_autolink( struct buf *ob, const uint8_t *text, size_t size, autolink_mode mode, unsigned int flags, const char *link_attr, const char **skip_tags, void (*link_text_cb)(struct buf *ob, const struct buf *link, void *payload), void *payload) { size_t i, end, last_link_found = 0; struct buf *link = bufnew(16); char active_chars[256]; void (*link_url_cb)(struct buf *, const struct buf *, void *); int link_count = 0; if (!text || size == 0) return 0; memset(active_chars, 0x0, sizeof(active_chars)); active_chars['<'] = AUTOLINK_ACTION_SKIP_TAG; if (mode & AUTOLINK_EMAILS) active_chars['@'] = AUTOLINK_ACTION_EMAIL; if (mode & AUTOLINK_URLS) { active_chars['w'] = AUTOLINK_ACTION_WWW; active_chars['W'] = AUTOLINK_ACTION_WWW; active_chars[':'] = AUTOLINK_ACTION_URL; } if (link_text_cb == NULL) link_text_cb = &autolink__print; if (link_attr != NULL) { while (isspace(*link_attr)) link_attr++; } bufgrow(ob, size); i = end = 0; while (i < size) { size_t rewind, link_end; char action = 0; while (end < size && (action = active_chars[text[end]]) == 0) end++; if (end == size) { if (link_count > 0) bufput(ob, text + i, end - i); break; } if (action == AUTOLINK_ACTION_SKIP_TAG) { end += autolink__skip_tag(ob, text + end, size - end, skip_tags); continue; } link->size = 0; link_end = g_callbacks[(int)action]( &rewind, link, (uint8_t *)text + end, end - last_link_found, size - end, flags); /* print the link */ if (link_end > 0) { bufput(ob, text + i, end - i - rewind); bufputs(ob, g_hrefs[(int)action]); print_link(ob, link->data, link->size); if (link_attr) { BUFPUTSL(ob, "\" "); bufputs(ob, link_attr); bufputc(ob, '>'); } else { BUFPUTSL(ob, "\">"); } link_text_cb(ob, link, payload); BUFPUTSL(ob, "</a>"); link_count++; i = end + link_end; last_link_found = end = i; } else { end = end + 1; } } bufrelease(link); return link_count; }
static void rndr_html_tag(struct buf *ob, const struct buf *text, void *opaque, char* tagname, char** whitelist, int tagtype) { size_t i, x, z, in_str = 0, seen_equals = 0, done = 0, done_attr = 0, reset = 0; struct buf *attr; struct buf *value; char c; bufputc(ob, '<'); if(tagtype == HTML_TAG_CLOSE) { bufputc(ob, '/'); bufputs(ob, tagname); bufputc(ob, '>'); return; } bufputs(ob, tagname); i = 1 + strlen(tagname); attr = bufnew(16); value = bufnew(16); for(; i < text->size && !done; i++) { c = text->data[i]; done = 0; reset = 0; done_attr = 0; switch(c) { case '>': done = 1; break; case '\'': case '"': if(!seen_equals) { reset = 1; } else if(!in_str) { in_str = c; } else if(in_str == c) { in_str = 0; done_attr = 1; } else { bufputc(value, c); } break; case ' ': if (in_str) { bufputc(value, ' '); } else { reset = 1; } break; case '=': if(seen_equals) { reset = 1; break; } seen_equals = 1; break; default: if(seen_equals && in_str || !seen_equals) { bufputc(seen_equals ? value : attr, c); } break; } if(done_attr) { int valid = 0; for(z = 0; whitelist[z]; z++) { if(strlen(whitelist[z]) != attr->size) { continue; } for(x = 0; x < attr->size; x++) { if(tolower(whitelist[z][x]) != tolower(attr->data[x])) { break; } } if(x == attr->size) { valid = 1; break; } } if(valid && value->size && attr->size) { bufputc(ob, ' '); escape_html(ob, attr->data, attr->size); bufputs(ob, "=\""); escape_html(ob, value->data, value->size); bufputc(ob, '"'); } reset = 1; } if(reset) { seen_equals = 0; in_str = 0; bufreset(attr); bufreset(value); } } bufrelease(attr); bufrelease(value); bufputc(ob, '>'); }
int rinku_autolink( struct buf *ob, const uint8_t *text, size_t size, autolink_mode mode, unsigned int flags, const char *link_attr, const char **skip_tags, void (*link_text_cb)(struct buf *, const uint8_t *, size_t, void *), void *payload) { size_t i, end; char active_chars[256] = {0}; int link_count = 0; if (!text || size == 0) return 0; active_chars['<'] = AUTOLINK_ACTION_SKIP_TAG; if (mode & AUTOLINK_EMAILS) active_chars['@'] = AUTOLINK_ACTION_EMAIL; if (mode & AUTOLINK_URLS) { active_chars['w'] = AUTOLINK_ACTION_WWW; active_chars['W'] = AUTOLINK_ACTION_WWW; active_chars[':'] = AUTOLINK_ACTION_URL; } if (link_attr != NULL) { while (rinku_isspace(*link_attr)) link_attr++; } bufgrow(ob, size); i = end = 0; while (i < size) { struct autolink_pos link; bool link_found; char action = 0; while (end < size && (action = active_chars[text[end]]) == 0) end++; if (end == size) { if (link_count > 0) bufput(ob, text + i, end - i); break; } if (action == AUTOLINK_ACTION_SKIP_TAG) { end += autolink__skip_tag(ob, text + end, size - end, skip_tags); continue; } link_found = g_callbacks[(int)action]( &link, text, end, size, flags); if (link_found && link.start >= i) { const uint8_t *link_str = text + link.start; const size_t link_len = link.end - link.start; bufput(ob, text + i, link.start - i); bufputs(ob, g_hrefs[(int)action]); print_link(ob, link_str, link_len); if (link_attr) { BUFPUTSL(ob, "\" "); bufputs(ob, link_attr); bufputc(ob, '>'); } else { BUFPUTSL(ob, "\">"); } if (link_text_cb) { link_text_cb(ob, link_str, link_len, payload); } else { bufput(ob, link_str, link_len); } BUFPUTSL(ob, "</a>"); link_count++; end = i = link.end; } else { end = end + 1; } } return link_count; }