size_t ups_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size) { size_t link_end, rewind = 0; if (size < 4 || data[1] != '/' || data[2] != '/') return 0; while (rewind < offset && isalpha(data[-rewind - 1])) rewind++; if (!is_safe_link(data - rewind, size + rewind)) return 0; link_end = 0; while (link_end < size && !isspace(data[link_end])) link_end++; link_end = autolink_delim(data, link_end, offset, size); if (link_end == 0) return 0; bufput(link, data - rewind, link_end + rewind); *rewind_p = rewind; return link_end; }
/******************** * GENERIC RENDERER * ********************/ static int rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque) { struct html_renderopt *options = opaque; if (!link || !link->size) return 0; if ((options->flags & HTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size) && type != MKDA_EMAIL) return 0; BUFPUTSL(ob, "<a href=\""); if (type == MKDA_EMAIL) BUFPUTSL(ob, "mailto:"); bufput(ob, link->data, link->size); BUFPUTSL(ob, "\">"); /* * Pretty printing: if we get an email address as * an actual URI, e.g. `mailto:[email protected]`, we don't * want to print the `mailto:` prefix */ if (bufprefix(link, "mailto:") == 0) { attr_escape(ob, link->data + 7, link->size - 7); } else { attr_escape(ob, link->data, link->size); } BUFPUTSL(ob, "</a>"); return 1; }
static int rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque) { struct html_renderopt *options = opaque; if ((options->flags & HTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size)) return 0; BUFPUTSL(ob, "<a href=\""); if (link && link->size) bufput(ob, link->data, link->size); if (title && title->size) { BUFPUTSL(ob, "\" title=\""); attr_escape(ob, title->data, title->size); } BUFPUTSL(ob, "\">"); if (content && content->size) bufput(ob, content->data, content->size); BUFPUTSL(ob, "</a>"); return 1; }
static size_t char_autolink(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size) { struct buf work = { data, 0, 0, 0, 0 }; if (offset > 0 && !isspace(data[-1])) return 0; if (!is_safe_link(data, size)) return 0; while (work.size < size && !isspace(data[work.size])) work.size++; if (rndr->make.autolink) { struct buf *u_link = rndr_newbuf(rndr); unscape_text(u_link, &work); rndr->make.autolink(ob, u_link, MKDA_NORMAL, rndr->make.opaque); rndr_popbuf(rndr); } return work.size; }