示例#1
0
static int
toc_link(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque)
{
	if (content && content->size)
		bufput(ob, content->data, content->size);
	return 1;
}
示例#2
0
void
houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)
{
	size_t i = 0, org, esc = 0;

	bufgrow(ob, ESCAPE_GROW_FACTOR(size));

	while (i < size) {
		org = i;
		while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
			i++;

		if (i > org)
			bufput(ob, src + org, i - org);

		/* escaping */
		if (i >= size)
			break;

		/* The forward slash is only escaped in secure mode */
		if (src[i] == '/' && !secure) {
			bufputc(ob, '/');
		} else {
			bufputs(ob, HTML_ESCAPES[esc]);
		}

		i++;
	}
}
示例#3
0
static int
rndr_raw_html(struct buf *ob, const struct buf *text, void *opaque)
{
	struct html_renderopt *options = opaque;

	/* HTML_ESCAPE overrides SKIP_HTML, SKIP_STYLE, SKIP_LINKS and SKIP_IMAGES
	* It doens't see if there are any valid tags, just escape all of them. */
	if((options->flags & HTML_ESCAPE) != 0) {
		escape_html(ob, text->data, text->size);
		return 1;
	}

	if ((options->flags & HTML_SKIP_HTML) != 0)
		return 1;

	if ((options->flags & HTML_SKIP_STYLE) != 0 &&
		sdhtml_is_tag(text->data, text->size, "style"))
		return 1;

	if ((options->flags & HTML_SKIP_LINKS) != 0 &&
		sdhtml_is_tag(text->data, text->size, "a"))
		return 1;

	if ((options->flags & HTML_SKIP_IMAGES) != 0 &&
		sdhtml_is_tag(text->data, text->size, "img"))
		return 1;

	bufput(ob, text->data, text->size);
	return 1;
}
示例#4
0
static void
rndr_tablecell(struct buf *ob, const struct buf *text, int flags, void *opaque)
{
	if (flags & MKD_TABLE_HEADER) {
		BUFPUTSL(ob, "<th");
	} else {
		BUFPUTSL(ob, "<td");
	}

	switch (flags & MKD_TABLE_ALIGNMASK) {
	case MKD_TABLE_ALIGN_CENTER:
		BUFPUTSL(ob, " style=\"text-align: center\">");
		break;

	case MKD_TABLE_ALIGN_L:
		BUFPUTSL(ob, " style=\"text-align: left\">");
		break;

	case MKD_TABLE_ALIGN_R:
		BUFPUTSL(ob, " style=\"text-align: right\">");
		break;

	default:
		BUFPUTSL(ob, ">");
	}

	if (text)
		bufput(ob, text->data, text->size);

	if (flags & MKD_TABLE_HEADER) {
		BUFPUTSL(ob, "</th>\n");
	} else {
		BUFPUTSL(ob, "</td>\n");
	}
}
示例#5
0
static int
rndr_link(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, 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, "<a href=\"");

	if (link && link->size)
		escape_href(ob, link->data, link->size);

	if (title && title->size) {
		BUFPUTSL(ob, "\" title=\"");
		escape_html(ob, title->data, title->size);
	}

	if (options->link_attributes) {
		bufputc(ob, '\"');
		options->link_attributes(ob, link, opaque);
		bufputc(ob, '>');
	} else {
		BUFPUTSL(ob, "\">");
	}

	if (content && content->size) bufput(ob, content->data, content->size);
	BUFPUTSL(ob, "</a>");
	return 1;
}
示例#6
0
/* build_ref_id • collapse whitespace from input text to make it a ref id */
static int
build_ref_id(struct buf *id, const char *data, size_t size) {
	size_t beg, i;

	/* skip leading whitespace */
	while (size > 0
	&& (data[0] == ' ' || data[0] == '\t' || data[0] == '\n')) {
		data += 1;
		size -= 1; }

	/* skip trailing whitespace */
	while (size > 0
	&& (data[size - 1] == ' ' || data[size - 1] == '\t'
	 || data[size - 1] == '\n'))
		size -= 1;
	if (size == 0) return -1;

	/* making the ref id */
	i = 0;
	id->size = 0;
	while (i < size) {
		/* copy non-whitespace into the output buffer */
		beg = i;
		while (i < size
		&& !(data[i] == ' ' || data[i] == '\t' || data[i] == '\n'))
			i += 1;
		bufput(id, data + beg, i - beg);

		/* add a single space and skip all consecutive whitespace */
		if (i < size) bufputc(id, ' ');
		while (i < size
		&& (data[i] == ' ' || data[i] == '\t' || data[i] == '\n'))
			i += 1; }
	return 0; }
示例#7
0
/* parse_blockquote • hanldes parsing of a block-level code fragment */
static size_t
parse_blockcode(struct buf *ob, struct render *rndr,
			char *data, size_t size) {
	size_t beg, end, pre;
	struct buf *work = new_work_buffer(rndr);

	beg = 0;
	while (beg < size) {
		for (end = beg + 1; end < size && data[end - 1] != '\n';
							end += 1);
		pre = prefix_code(data + beg, end - beg);
		if (pre) beg += pre; /* skipping prefix */
		else if (!is_empty(data + beg, end - beg))
			/* non-empty non-prefixed line breaks the pre */
			break;
		if (beg < end) {
			/* verbatim copy to the working buffer,
				escaping entities */
			if (is_empty(data + beg, end - beg))
				bufputc(work, '\n');
			else bufput(work, data + beg, end - beg); }
		beg = end; }

	while (work->size && work->data[work->size - 1] == '\n')
		work->size -= 1;
	bufputc(work, '\n');
	if (rndr->make.blockcode)
		rndr->make.blockcode(ob, work, rndr->make.opaque);
	release_work_buffer(rndr, work);
	return beg; }
示例#8
0
文件: autolink.c 项目: bkad/misaka
size_t
sd_autolink__www(
  size_t *rewind_p,
  struct buf *link,
  uint8_t *data,
  size_t offset,
  size_t size,
  unsigned int flags)
{
	size_t link_end;

	if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
		return 0;

	if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
		return 0;

	link_end = check_domain(data, size, flags);

	if (link_end == 0)
		return 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, link_end);
	*rewind_p = 0;

	return (int)link_end;
}
示例#9
0
static int
latex_image(struct buf *ob, struct buf *link, struct buf *title,
			struct buf *alt, void *opaque) {
	if (!link || !link->size) return 0;
	BUFPUTSL(ob, "\\includegraphics{");
	bufput(ob, link->data, link->size);
	BUFPUTSL(ob, "}");
	return 1; }
示例#10
0
static int
rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	if (!text || !text->size) return 0;
	BUFPUTSL(ob, "<strong><em>");
	bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</em></strong>");
	return 1;
}
示例#11
0
static int
rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	if (!text || !text->size) return 0;
	BUFPUTSL(ob, "<em>");
	if (text) bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</em>");
	return 1;
}
示例#12
0
static void
rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque) {
	BUFPUTSL(ob, "<li>");
	if (text) {
		while (text->size && text->data[text->size - 1] == '\n')
			text->size -= 1;
		bufput(ob, text->data, text->size); }
	BUFPUTSL(ob, "</li>\n"); }
示例#13
0
static void
rndr_blockquote(struct buf *ob, const struct buf *text, void *opaque)
{
	if (ob->size) bufputc(ob, '\n');
	BUFPUTSL(ob, "<blockquote>\n");
	if (text) bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</blockquote>\n");
}
示例#14
0
static void
rndr_tablerow(struct buf *ob, const struct buf *text, void *opaque)
{
	BUFPUTSL(ob, "<tr>\n");
	if (text)
		bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</tr>\n");
}
示例#15
0
size_t
sd_autolink__subreddit(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
{
	size_t link_end;

	if (size < 3)
		return 0;

	/* make sure this / is part of /r/ */
	if (strncasecmp((char*)data, "/r/", 3) != 0)
		return 0;
	link_end = strlen("/r/");

	do {
		size_t start = link_end;
		int max_length = 24;

		/* special case: /r/reddit.com (only subreddit containing '.'). */
		if ( size >= link_end+10 && strncasecmp((char*)data+link_end, "reddit.com", 10) == 0 ) {
			link_end += 10;
			/* Make sure there are no trailing characters (don't do
			 * any autolinking for /r/reddit.commission) */
			max_length = 10;
		}

		/* If not a special case, verify it begins with (t:)?[A-Za-z0-9] */
		else {
			/* support autolinking to timereddits, /r/t:when (1 April 2012) */
			if ( size > link_end+2 && strncasecmp((char*)data+link_end, "t:", 2) == 0 )
				link_end += 2;  /* Jump over the 't:' */

			/* the first character of a subreddit name must be a letter or digit */
			if (!isalnum(data[link_end]))
				return 0;
			link_end += 1;
		}

		/* consume valid characters ([A-Za-z0-9_]) until we run out */
		while (link_end < size && (isalnum(data[link_end]) ||
							data[link_end] == '_'))
			link_end++;

		/* valid subreddit names are between 3 and 21 characters, with
		 * some subreddits having 2-character names. Don't bother with
		 * autolinking for anything outside this length range.
		 * (chksrname function in reddit/.../validator.py) */
		if ( link_end-start < 2 || link_end-start > max_length )
			return 0;

		/* If we are linking to a multireddit, continue */
	} while ( link_end < size && data[link_end] == '+' && link_end++ );

	/* make the link */
	bufput(link, data, link_end);
	*rewind_p = 0;

	return link_end;
}
示例#16
0
static int
rndr_triple_emphasis(struct buf *ob, const struct buf *text, void *opaque)
{
	if (!text || !text->size) return 0;
	BUFPUTSL(ob, "<b><i>");
	bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</i></b>");
	return 1;
}
示例#17
0
static int
rndr_superscript(struct buf *ob, const struct buf *text, void *opaque)
{
	if (!text || !text->size) return 0;
	BUFPUTSL(ob, "<sup>");
	bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</sup>");
	return 1;
}
示例#18
0
static void
rndr_tablerow(struct buf *ob, struct buf *text, void *opaque)
{
	if (ob->size) bufputc(ob, '\n');
	BUFPUTSL(ob, "<tr>\n");
	if (text)
		bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "\n</tr>");
}
示例#19
0
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;
}
示例#20
0
文件: rinku.c 项目: Arkham/rinku
/**
 * Ruby code
 */
static void
autolink_callback(struct buf *link_text, const struct buf *link, void *block)
{
	VALUE rb_link, rb_link_text;
	rb_link = rb_str_new(link->data, link->size);
	rb_link_text = rb_funcall((VALUE)block, rb_intern("call"), 1, rb_link);
	Check_Type(rb_link_text, T_STRING);
	bufput(link_text, RSTRING_PTR(rb_link_text), RSTRING_LEN(rb_link_text));
}
示例#21
0
static void
latex_entity(struct buf *ob, struct buf *entity, void *opaque) {
	const char *rendered = entity2latex(entity);
	if (rendered)
		bufputs(ob, rendered);
	else {
		BUFPUTSL(ob, "\\texttt{");
		bufput(ob, entity->data, entity->size);
		BUFPUTSL(ob, "}"); } }
示例#22
0
void
houdini_escape_js(struct buf *ob, const uint8_t *src, size_t size)
{
	size_t  i = 0, org, ch;

	bufgrow(ob, ESCAPE_GROW_FACTOR(size));

	while (i < size) {
		org = i;
		while (i < size && JS_ESCAPE[src[i]] == 0)
			i++;

		if (i > org)
			bufput(ob, src + org, i - org);

		/* escaping */
		if (i >= size)
			break;

		ch = src[i];
		
		switch (ch) {
		case '/':
			/*
			 * Escape only if preceded by a lt
			 */
			if (i && src[i - 1] == '<')
				bufputc(ob, '\\');

			bufputc(ob, ch);
			break;

		case '\r':
			/*
			 * Escape as \n, and skip the next \n if it's there
			 */
			if (i + 1 < size && src[i + 1] == '\n') i++;

		case '\n':
			/*
			 * Escape actually as '\','n', not as '\', '\n'
			 */
			ch = 'n';

		default:
			/*
			 * Normal escaping
			 */
			bufputc(ob, '\\');
			bufputc(ob, ch);
			break;
		}

		i++;
	}
}
示例#23
0
static void
rndr_paragraph(struct buf *ob, const 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);

			/*
			 * do not insert a line break if this newline
			 * is the last character on the paragraph
			 */
			if (i >= text->size - 1)
				break;

			rndr_linebreak(ob, opaque);
			i++;
		}
	} else {
		bufput(ob, &text->data[i], text->size - i);
	}
	BUFPUTSL(ob, "</p>\n");
}
示例#24
0
static void
rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
{
	struct xhtml_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 & XHTML_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/>\n");
			i++;
		}
	} else {
		bufput(ob, &text->data[i], text->size - i);
	}
	BUFPUTSL(ob, "</p>\n");

	/* Close any open quotes at the end of the paragraph */
	options->quotes.in_squote = 0;
	options->quotes.in_dquote = 0;
}
示例#25
0
static int
rndr_strikethrough(struct buf *ob, const struct buf *text, void *opaque)
{
	if (!text || !text->size)
		return 0;

	BUFPUTSL(ob, "<del>");
	bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</del>");
	return 1;
}
示例#26
0
static int
rndr_displayedmath(struct buf *ob, const struct buf *text, void *opaque)
{
	if (!text || !text->size)
		return 0;

	BUFPUTSL(ob, "\\[");
	if (text) bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "\\]");
	return 1;
}
示例#27
0
static int
rndr_inlinemath(struct buf *ob, const struct buf *text, void *opaque)
{
	if (!text || !text->size)
		return 0;

	BUFPUTSL(ob, "\\(");
	if (text) bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "\\)");
	return 1;
}
示例#28
0
size_t
sd_autolink__email(
	size_t *rewind_p,
	struct buf *link,
	uint8_t *data,
	size_t max_rewind,
	size_t size,
	unsigned int flags)
{
	size_t link_end, rewind;
	int nb = 0, np = 0;

	for (rewind = 0; rewind < max_rewind; ++rewind) {
		uint8_t c = data[-rewind - 1];

		if (isalnum(c))
			continue;

		if (strchr(".+-_", c) != NULL)
			continue;

		break;
	}

	if (rewind == 0)
		return 0;

	for (link_end = 0; link_end < size; ++link_end) {
		uint8_t c = data[link_end];

		if (isalnum(c))
			continue;

		if (c == '@')
			nb++;
		else if (c == '.' && link_end < size - 1)
			np++;
		else if (c != '-' && c != '_')
			break;
	}

	if (link_end < 2 || nb != 1 || np == 0)
		return 0;

	link_end = autolink_delim(data, link_end, max_rewind, size);

	if (link_end == 0)
		return 0;

	bufput(link, data - rewind, link_end + rewind);
	*rewind_p = rewind;

	return link_end;
}
示例#29
0
/* get_link_ref • extract referenced link and title from id */
static int
get_link_ref(struct render *rndr, struct buf *link, struct buf *title,
				char * data, size_t size) {
	struct link_ref *lr;

	/* find the link from its id (stored temporarily in link) */
	link->size = 0;
	if (build_ref_id(link, data, size) < 0)
		return -1;
	lr = arr_sorted_find(&rndr->refs, link, cmp_link_ref);
	if (!lr) return -1;

	/* fill the output buffers */
	link->size = 0;
	if (lr->link)
		bufput(link, lr->link->data, lr->link->size);
	title->size = 0;
	if (lr->title)
		bufput(title, lr->title->data, lr->title->size);
	return 0; }
示例#30
0
static int
rndr_quote(struct buf *ob, const struct buf *text, void *opaque)
{
	if (!text || !text->size)
		return 0;

	BUFPUTSL(ob, "<q>");
	bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</q>");

	return 1;
}