Esempio n. 1
0
static void
rndr_raw_block(struct buf *ob, const struct buf *text, void *opaque)
{
	size_t org, size;
	struct html_renderopt *options = opaque;

	if (!text)
		return;

	size = text->size;
	while (size > 0 && text->data[size - 1] == '\n')
		size--;

	for (org = 0; org < size && text->data[org] == '\n'; ++org)

	if (org >= size)
		return;

	/* Remove style tags if the `:no_styles` option is enabled */
	if ((options->flags & HTML_SKIP_STYLE) != 0 &&
		sdhtml_is_tag(text->data, size, "style"))
		return;

	if (ob->size)
		bufputc(ob, '\n');

	bufput(ob, text->data + org, size - org);
	bufputc(ob, '\n');
}
Esempio n. 2
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;
}
Esempio n. 3
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; }
Esempio n. 4
0
File: html.c Progetto: mdietz/misaka
static void
rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque)
{
	if (ob->size) bufputc(ob, '\n');

	if (lang && lang->size) {
		size_t i, cls;
		BUFPUTSL(ob, "<pre><code class=\"");

		for (i = 0, cls = 0; i < lang->size; ++i, ++cls) {
			while (i < lang->size && isspace(lang->data[i]))
				i++;

			if (i < lang->size) {
				size_t org = i;
				while (i < lang->size && !isspace(lang->data[i]))
					i++;

				if (lang->data[org] == '.')
					org++;

				if (cls) bufputc(ob, ' ');
				escape_html(ob, lang->data + org, i - org);
			}
		}

		BUFPUTSL(ob, "\">");
	} else
		BUFPUTSL(ob, "<pre><code>");

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

	BUFPUTSL(ob, "</code></pre>\n");
}
Esempio n. 5
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++;
	}
}
Esempio n. 6
0
static void
rndr_raw_block(struct buf *ob, struct buf *text, void *opaque) {
	size_t org, sz;
	if (!text) return;
	sz = text->size;
	while (sz > 0 && text->data[sz - 1] == '\n') sz -= 1;
	org = 0;
	while (org < sz && text->data[org] == '\n') org += 1;
	if (org >= sz) return;
	if (ob->size) bufputc(ob, '\n');
	bufput(ob, text->data + org, sz - org);
	bufputc(ob, '\n'); }
Esempio n. 7
0
static void
rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque) {
	if (ob->size) bufputc(ob, '\n');
	bufput(ob, flags & MKD_LIST_ORDERED ? "<ol>\n" : "<ul>\n", 5);
	if (text) bufput(ob, text->data, text->size);
	bufput(ob, flags & MKD_LIST_ORDERED ? "</ol>\n" : "</ul>\n", 6);
}
Esempio n. 8
0
static void
rndr_header(struct buf *ob, struct buf *text, int level, void *opaque) {
	if (ob->size) bufputc(ob, '\n');
	bufprintf(ob, "<h%d>", level);
	if (text) bufput(ob, text->data, text->size);
	bufprintf(ob, "</h%d>\n", level);
}
Esempio n. 9
0
static void
rndr_blockcode(struct buf *ob, struct buf *text, void *opaque) {
	if (ob->size) bufputc(ob, '\n');
	BUFPUTSL(ob, "<pre><code>");
	if (text) lus_attr_escape(ob, text->data, text->size);
	BUFPUTSL(ob, "</code></pre>\n");
}
Esempio n. 10
0
static void
rndr_hrule(struct buf *ob, void *opaque)
{
	struct html_renderopt *options = opaque;
	if (ob->size) bufputc(ob, '\n');
	bufputs(ob, USE_XHTML(options) ? "<hr/>\n" : "<hr>\n");
}
Esempio n. 11
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; }
Esempio n. 12
0
static size_t
smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
	if (word_boundary(previous_char) && size >= 3) {
		if (text[0] == '1' && text[1] == '/' && text[2] == '2') {
			if (size == 3 || word_boundary(text[3])) {
				BUFPUTSL(ob, "&frac12;");
				return 2;
			}
		}

		if (text[0] == '1' && text[1] == '/' && text[2] == '4') {
			if (size == 3 || word_boundary(text[3]) ||
				(size >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h')) {
				BUFPUTSL(ob, "&frac14;");
				return 2;
			}
		}

		if (text[0] == '3' && text[1] == '/' && text[2] == '4') {
			if (size == 3 || word_boundary(text[3]) ||
				(size >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's')) {
				BUFPUTSL(ob, "&frac34;");
				return 2;
			}
		}
	}

	bufputc(ob, text[0]);
	return 0;
}
Esempio n. 13
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 if (HTML_ESCAPE_TABLE[src[i]] == 7) {
			/* skip control characters */
		} else {
			bufputs(ob, HTML_ESCAPES[esc]);
		}

		i++;
	}
}
Esempio n. 14
0
/*
 * GitHub style code block:
 *
 *		<pre lang="LANG"><code>
 *		...
 *		</pre></code>
 *
 * Unlike other parsers, we store the language identifier in the <pre>,
 * and don't let the user generate custom classes.
 *
 * The language identifier in the <pre> block gets postprocessed and all
 * the code inside gets syntax highlighted with Pygments. This is much safer
 * than letting the user specify a CSS class for highlighting.
 *
 * Note that we only generate HTML for the first specifier.
 * E.g.
 *		~~~~ {.python .numbered}	=>	<pre lang="python"><code>
 */
static void
rndr_blockcode_github(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)
{
	if (ob->size) bufputc(ob, '\n');

	if (lang && lang->size) {
		size_t i = 0;
		BUFPUTSL(ob, "<pre lang=\"");

		while (i < lang->size && !isspace(lang->data[i]))
			i++;

		if (lang->data[0] == '.')
			sdhtml_escape(ob, lang->data + 1, i - 1);
		else
			sdhtml_escape(ob, lang->data, i);

		BUFPUTSL(ob, "\"><code>");
	} else
		BUFPUTSL(ob, "<pre><code>");

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

	BUFPUTSL(ob, "</code></pre>\n");
}
Esempio n. 15
0
File: xhtml.c Progetto: nono/upskirt
/*
 * GitHub style code block:
 *
 *		<pre lang="LANG"><code>
 *		...
 *		</pre></code>
 *
 * Unlike other parsers, we store the language identifier in the <pre>,
 * and don't let the user generate custom classes.
 *
 * The language identifier in the <pre> block gets postprocessed and all
 * the code inside gets syntax highlighted with Pygments. This is much safer
 * than letting the user specify a CSS class for highlighting.
 *
 * Note that we only generate HTML for the first specifier.
 * E.g.
 *		~~~~ {.python .numbered}	=>	<pre lang="python"><code>
 */
static void
rndr_blockcode_github(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)
{
	if (ob->size) bufputc(ob, '\n');

	if (lang && lang->size) {
		size_t i = 0;
		BUFPUTSL(ob, "<pre lang=\"");

		for (; i < lang->size; ++i)
			if (isspace(lang->data[i]))
				break;

		if (lang->data[0] == '.')
			bufput(ob, lang->data + 1, i - 1);
		else
			bufput(ob, lang->data, i);

		BUFPUTSL(ob, "\"><code>");
	} else
		BUFPUTSL(ob, "<pre><code>");

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

	BUFPUTSL(ob, "</code></pre>\n");
}
Esempio n. 16
0
static void
rndr_tablecell(struct buf *ob, struct buf *text, int align, void *opaque)
{
	if (ob->size) bufputc(ob, '\n');
	switch (align) {
	case MKD_TABLE_ALIGN_L:
		BUFPUTSL(ob, "<td align=\"left\">");
		break;

	case MKD_TABLE_ALIGN_R:
		BUFPUTSL(ob, "<td align=\"right\">");
		break;

	case MKD_TABLE_ALIGN_CENTER:
		BUFPUTSL(ob, "<td align=\"center\">");
		break;

	default:
		BUFPUTSL(ob, "<td>");
		break;
	}

	if (text)
		bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</td>");
}
Esempio n. 17
0
static size_t
smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
	if (size >= 3) {
		uint8_t t1 = tolower(text[1]);
		uint8_t t2 = tolower(text[2]);

		if (t1 == 'c' && t2 == ')') {
			BUFPUTSL(ob, "&copy;");
			return 2;
		}

		if (t1 == 'r' && t2 == ')') {
			BUFPUTSL(ob, "&reg;");
			return 2;
		}

		if (size >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')') {
			BUFPUTSL(ob, "&trade;");
			return 3;
		}
	}

	bufputc(ob, text[0]);
	return 0;
}
Esempio n. 18
0
static void rndr_blockcode_github(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque) {
    if (ob->size)
        bufputc(ob, '\n');

    if (!text || !text->size) {
        BUFPUTSL(ob, "<pre><code></code></pre>");
        return;
    }

    if (lang && lang->size) {
        size_t i = 0, lang_size;
        const char *lang_name = NULL;

        while (i < lang->size && !isspace(lang->data[i]))
            i++;

        if (lang->data[0] == '.') {
            lang_name = (char const *) (lang->data + 1);
            lang_size = i - 1;
        } else {
            lang_name = (char const *) lang->data;
            lang_size = i;
        }

        BUFPUTSL(ob, "<pre lang=\"");
        houdini_escape_html0(ob, (uint8_t const *) lang_name, lang_size, 0);
        BUFPUTSL(ob, "\"><code>");

    } else {
        BUFPUTSL(ob, "<pre><code>");
    }

    houdini_escape_html0(ob, text->data, text->size, 0);
    BUFPUTSL(ob, "</code></pre>\n");
}
Esempio n. 19
0
static void
rndr_header_anchor(struct buf *out, const struct buf *anchor)
{
	static const char *STRIPPED = " -&+$,/:;=?@\"#{}|^~[]`\\*()%.!'";

	const uint8_t *a = anchor->data;
	const size_t size = anchor->size;
	size_t i = 0;
	int stripped = 0, inserted = 0;

	for (; i < size; ++i) {
		// skip html tags
		if (a[i] == '<') {
			while (i < size && a[i] != '>')
				i++;
		// skip html entities
		} else if (a[i] == '&') {
			while (i < size && a[i] != ';')
				i++;
		}
		// replace non-ascii or invalid characters with dashes
		else if (!isascii(a[i]) || strchr(STRIPPED, a[i])) {
			if (inserted && !stripped)
				bufputc(out, '-');
			// and do it only once
			stripped = 1;
		}
		else {
			bufputc(out, tolower(a[i]));
			stripped = 0;
			inserted++;
		}
	}

	// replace the last dash if there was anything added
	if (stripped && inserted)
		out->size--;

	// if anchor found empty, use djb2 hash for it
	if (!inserted && anchor->size) {
	        unsigned long hash = 5381;
		for (i = 0; i < size; ++i) {
			hash = ((hash << 5) + hash) + a[i]; /* h * 33 + c */
		}
		bufprintf(out, "part-%lx", hash);
	}
}
Esempio n. 20
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");
}
Esempio n. 21
0
static void
rndr_hrule(struct buf *ob, void *opaque)
{
	struct html_renderopt *options = opaque;	
	if (ob->size) bufputc(ob, '\n');
	BUFPUTSL(ob, "<hr");
	bufputs(ob, options->close_tag);
}
Esempio n. 22
0
void
houdini_unescape_js(struct buf *ob, const uint8_t *src, size_t size)
{
	size_t  i = 0, org, ch;

	bufgrow(ob, UNESCAPE_GROW_FACTOR(size));

	while (i < size) {
		org = i;
		while (i < size && src[i] != '\\')
			i++;

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

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

		if (++i == size) {
			bufputc(ob, '\\');
			break;
		}

		ch = src[i];

		switch (ch) {
		case 'n':
			ch = '\n';
			/* pass through */

		case '\\':
		case '\'':
		case '\"':
		case '/':
			bufputc(ob, ch);
			i++;
			break;

		default:
			bufputc(ob, '\\');
			break;
		}
	}
}
Esempio n. 23
0
static void
rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque)
{
	struct html_renderopt *options = opaque;

	if (ob->size) bufputc(ob, '\n');

	if (lang && lang->size) {
		size_t i, cls;
		if (options->flags & HTML_PRETTIFY) {
			BUFPUTSL(ob, "<pre><code class=\"prettyprint lang-");
			cls++;
		} else {
			BUFPUTSL(ob, "<pre><code class=\"");
		}

		for (i = 0, cls = 0; i < lang->size; ++i, ++cls) {
			while (i < lang->size && isspace(lang->data[i]))
				i++;

			if (i < lang->size) {
				size_t org = i;
				while (i < lang->size && !isspace(lang->data[i]))
					i++;

				if (lang->data[org] == '.')
					org++;

				if (cls) bufputc(ob, ' ');
				escape_html(ob, lang->data + org, i - org);
			}
		}

		BUFPUTSL(ob, "\">");
	} else if (options->flags & HTML_PRETTIFY) {
		BUFPUTSL(ob, "<pre><code class=\"prettyprint\">");
	} else {
		BUFPUTSL(ob, "<pre><code>");
	}

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

	BUFPUTSL(ob, "</code></pre>\n");
}
Esempio n. 24
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>");
}
Esempio n. 25
0
static void
nat_header(struct buf *ob, struct buf *text, int level, void *opaque) {
	size_t i = 0;
	if (ob->size) bufputc(ob, '\n');
	while (i < text->size && (text->data[i] == '-' || text->data[i] == '_'
			 ||  text->data[i] == '.' || text->data[i] == ':'
			 || (text->data[i] >= 'a' && text->data[i] <= 'z')
			 || (text->data[i] >= 'A' && text->data[i] <= 'Z')
			 || (text->data[i] >= '0' && text->data[i] <= '0')))
		i += 1;
	bufprintf(ob, "<h%d", level);
	if (i < text->size && text->data[i] == '#') {
		bufprintf(ob, " id=\"%.*s\">", (int)i, text->data);
		i += 1; }
	else {
		bufputc(ob, '>');
		i = 0; }
	bufput(ob, text->data + i, text->size - i);
	bufprintf(ob, "</h%d>\n", level); }
Esempio n. 26
0
static void
rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque) {
	if (ob->size) bufputc(ob, '\n');
	BUFPUTSL(ob, "<li>\n");
	if (text) {
		while (text->size && text->data[text->size - 1] == '\n')
			text->size -= 1;
		bufput(ob, text->data, text->size); }
	BUFPUTSL(ob, "</li>\n");
}
Esempio n. 27
0
File: html.c Progetto: mdietz/misaka
/********************
 * GENERIC RENDERER *
 ********************/
static int
rndr_autolink(struct buf *ob, const 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 &&
		!sd_autolink_issafe(link->data, link->size) &&
		type != MKDA_EMAIL)
		return 0;

	BUFPUTSL(ob, "<a href=\"");
	if (type == MKDA_EMAIL)
		BUFPUTSL(ob, "mailto:");
	escape_href(ob, link->data, link->size);

	if (options->link_attributes) {
		bufputc(ob, '\"');
		options->link_attributes(ob, link, opaque);
		bufputc(ob, '>');
	} else if (options->flags & HTML_NEW_TAB_LINKS) {
    BUFPUTSL(ob, "\" target=\"_blank\">");
  } else {
		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) {
		escape_html(ob, link->data + 7, link->size - 7);
	} else {
		escape_html(ob, link->data, link->size);
	}

	BUFPUTSL(ob, "</a>");

	return 1;
}
Esempio n. 28
0
/* parse_fencedcode • hanldes parsing of a block-level code fragment */
static size_t
parse_fencedcode(struct buf *ob, struct render *rndr, char *data, size_t size)
{
	size_t beg, end;
	struct buf *work = 0;
	struct buf lang = { 0, 0, 0, 0, 0 };

	beg = is_codefence(data, size, &lang);
	if (beg == 0) return 0;

	work = rndr_newbuf(rndr);

	while (beg < size) {
		size_t fence_end;

		fence_end = is_codefence(data + beg, size - beg, NULL);
		if (fence_end != 0) {
			beg += fence_end;
			break;
		}

		for (end = beg + 1; end < size && data[end - 1] != '\n'; end += 1);

		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;
	}

	if (work->size && work->data[work->size - 1] != '\n')
		bufputc(work, '\n');

	if (rndr->make.blockcode)
		rndr->make.blockcode(ob, work, lang.size ? &lang : NULL, rndr->make.opaque);

	rndr_popbuf(rndr);
	return beg;
}
Esempio n. 29
0
/* char_escape • '\\' backslash escape */
static size_t
char_escape(struct buf *ob, struct render *rndr,
				char *data, size_t offset, size_t size) {
	struct buf work = { 0, 0, 0, 0, 0 };
	if (size > 1) {
		if (rndr->make.normal_text) {
			work.data = data + 1;
			work.size = 1;
			rndr->make.normal_text(ob, &work, rndr->make.opaque); }
		else bufputc(ob, data[1]); }
	return 2; }
Esempio n. 30
0
static inline void
put_scaped_char(struct buf *ob, char c)
{
	switch (c) {
		case '<': BUFPUTSL(ob, "&lt;"); break;
		case '>': BUFPUTSL(ob, "&gt;"); break;
		case '&': BUFPUTSL(ob, "&amp;"); break;
		case '"': BUFPUTSL(ob, "&quot;"); break;
		default: bufputc(ob, c); break;
	}
}