diff --git a/cbits/autolink.c b/cbits/autolink.c
--- a/cbits/autolink.c
+++ b/cbits/autolink.c
@@ -24,9 +24,9 @@
 int
 sd_autolink_issafe(const uint8_t *link, size_t link_len)
 {
-	static const size_t valid_uris_count = 4;
+	static const size_t valid_uris_count = 5;
 	static const char *valid_uris[] = {
-		"http://", "https://", "ftp://", "mailto://"
+		"/", "http://", "https://", "ftp://", "mailto:"
 	};
 
 	size_t i;
@@ -140,10 +140,9 @@
 		else if (!isalnum(data[i]) && data[i] != '-') break;
 	}
 
-	if (!isalnum(data[i - 1]) || np == 0)
-		return 0;
-
-	return i;
+	/* a valid domain needs to have at least a dot.
+	 * that's as far as we get */
+	return np ? i : 0;
 }
 
 size_t
diff --git a/cbits/buffer.c b/cbits/buffer.c
--- a/cbits/buffer.c
+++ b/cbits/buffer.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 /* MSVC compat */
 #if defined(_MSC_VER)
@@ -34,6 +35,7 @@
 bufprefix(const struct buf *buf, const char *prefix)
 {
 	size_t i;
+	assert(buf && buf->unit);
 
 	for (i = 0; i < buf->size; ++i) {
 		if (prefix[i] == 0)
@@ -52,7 +54,10 @@
 {
 	size_t neoasz;
 	void *neodata;
-	if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE)
+
+	assert(buf && buf->unit);
+
+	if (neosz > BUFFER_MAX_ALLOC_SIZE)
 		return BUF_ENOMEM;
 
 	if (buf->asize >= neosz)
@@ -91,8 +96,7 @@
 const char *
 bufcstr(struct buf *buf)
 {
-	if (!buf || !buf->unit)
-		return NULL;
+	assert(buf && buf->unit);
 
 	if (buf->size < buf->asize && buf->data[buf->size] == 0)
 		return (char *)buf->data;
@@ -110,20 +114,45 @@
 bufprintf(struct buf *buf, const char *fmt, ...)
 {
 	va_list ap;
-	if (!buf || !buf->unit)
-		return;
+	int n;
 
+	assert(buf && buf->unit);
+
+	if (buf->size >= buf->asize && bufgrow(buf, buf->size + 1) < 0)
+		return;
+	
 	va_start(ap, fmt);
-	vbufprintf(buf, fmt, ap);
+	n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
 	va_end(ap);
+
+	if (n < 0) {
+#ifdef _MSC_VER
+		n = _vscprintf(fmt, ap);
+#else
+		return;
+#endif
+	}
+
+	if ((size_t)n >= buf->asize - buf->size) {
+		if (bufgrow(buf, buf->size + n + 1) < 0)
+			return;
+
+		va_start(ap, fmt);
+		n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
+		va_end(ap);
+	}
+
+	if (n < 0)
+		return;
+
+	buf->size += n;
 }
 
 /* bufput: appends raw data to a buffer */
 void
 bufput(struct buf *buf, const void *data, size_t len)
 {
-	if (!buf)
-		return;
+	assert(buf && buf->unit);
 
 	if (buf->size + len > buf->asize && bufgrow(buf, buf->size + len) < 0)
 		return;
@@ -144,8 +173,7 @@
 void
 bufputc(struct buf *buf, int c)
 {
-	if (!buf)
-		return;
+	assert(buf && buf->unit);
 
 	if (buf->size + 1 > buf->asize && bufgrow(buf, buf->size + 1) < 0)
 		return;
@@ -182,8 +210,7 @@
 void
 bufslurp(struct buf *buf, size_t len)
 {
-	if (!buf || !buf->unit || len <= 0)
-		return;
+	assert(buf && buf->unit);
 
 	if (len >= buf->size) {
 		buf->size = 0;
@@ -192,37 +219,5 @@
 
 	buf->size -= len;
 	memmove(buf->data, buf->data + len, buf->size);
-}
-
-/* vbufprintf: stdarg variant of formatted printing into a buffer */
-void
-vbufprintf(struct buf *buf, const char *fmt, va_list ap)
-{
-	int n;
-
-	if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0)
-		return;
-
-	n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
-
-	if (n < 0) {
-#ifdef _MSC_VER
-		n = _vscprintf(fmt, ap);
-#else
-		return;
-#endif
-	}
-
-	if ((size_t)n >= buf->asize - buf->size) {
-		if (bufgrow(buf, buf->size + n + 1) < 0)
-			return;
-
-		n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
-	}
-
-	if (n < 0)
-		return;
-
-	buf->size += n;
 }
 
diff --git a/cbits/buffer.h b/cbits/buffer.h
--- a/cbits/buffer.h
+++ b/cbits/buffer.h
@@ -15,8 +15,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifndef __GEN_BUFFER_H__
-#define __GEN_BUFFER_H__
+#ifndef BUFFER_H__
+#define BUFFER_H__
 
 #include <stddef.h>
 #include <stdarg.h>
@@ -84,8 +84,5 @@
 
 /* bufprintf: formatted printing to a buffer */
 void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
-
-/* vbufprintf: stdarg variant of formatted printing into a buffer */
-void vbufprintf(struct buf *, const char * , va_list);
 
 #endif
diff --git a/cbits/houdini.h b/cbits/houdini.h
--- a/cbits/houdini.h
+++ b/cbits/houdini.h
@@ -1,5 +1,5 @@
-#ifndef __HOUDINI_H__
-#define __HOUDINI_H__
+#ifndef HOUDINI_H__
+#define HOUDINI_H__
 
 #include "buffer.h"
 
@@ -17,6 +17,7 @@
 extern void houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size);
 extern void houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure);
 extern void houdini_unescape_html(struct buf *ob, const uint8_t *src, size_t size);
+extern void houdini_escape_xml(struct buf *ob, const uint8_t *src, size_t size);
 extern void houdini_escape_uri(struct buf *ob, const uint8_t *src, size_t size);
 extern void houdini_escape_url(struct buf *ob, const uint8_t *src, size_t size);
 extern void houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size);
diff --git a/cbits/houdini_html_e.c b/cbits/houdini_html_e.c
--- a/cbits/houdini_html_e.c
+++ b/cbits/houdini_html_e.c
@@ -49,7 +49,7 @@
 void
 houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)
 {
-	size_t  i = 0, org, esc;
+	size_t i = 0, org, esc = 0;
 
 	bufgrow(ob, ESCAPE_GROW_FACTOR(size));
 
diff --git a/cbits/html.c b/cbits/html.c
--- a/cbits/html.c
+++ b/cbits/html.c
@@ -60,6 +60,16 @@
 	return HTML_TAG_NONE;
 }
 
+static inline void escape_html(struct buf *ob, const uint8_t *source, size_t length)
+{
+	houdini_escape_html0(ob, source, length, 0);
+}
+
+static inline void escape_href(struct buf *ob, const uint8_t *source, size_t length)
+{
+	houdini_escape_href(ob, source, length);
+}
+
 /********************
  * GENERIC RENDERER *
  ********************/
@@ -79,7 +89,7 @@
 	BUFPUTSL(ob, "<a href=\"");
 	if (type == MKDA_EMAIL)
 		BUFPUTSL(ob, "mailto:");
-	houdini_escape_href(ob, link->data, link->size);
+	escape_href(ob, link->data, link->size);
 
 	if (options->link_attributes) {
 		bufputc(ob, '\"');
@@ -95,9 +105,9 @@
 	 * want to print the `mailto:` prefix
 	 */
 	if (bufprefix(link, "mailto:") == 0) {
-		houdini_escape_html(ob, link->data + 7, link->size - 7);
+		escape_html(ob, link->data + 7, link->size - 7);
 	} else {
-		houdini_escape_html(ob, link->data, link->size);
+		escape_html(ob, link->data, link->size);
 	}
 
 	BUFPUTSL(ob, "</a>");
@@ -127,7 +137,7 @@
 					org++;
 
 				if (cls) bufputc(ob, ' ');
-				houdini_escape_html(ob, lang->data + org, i - org);
+				escape_html(ob, lang->data + org, i - org);
 			}
 		}
 
@@ -136,7 +146,7 @@
 		BUFPUTSL(ob, "<pre><code>");
 
 	if (text)
-		houdini_escape_html(ob, text->data, text->size);
+		escape_html(ob, text->data, text->size);
 
 	BUFPUTSL(ob, "</code></pre>\n");
 }
@@ -154,7 +164,7 @@
 rndr_codespan(struct buf *ob, const struct buf *text, void *opaque)
 {
 	BUFPUTSL(ob, "<code>");
-	if (text) houdini_escape_html(ob, text->data, text->size);
+	if (text) escape_html(ob, text->data, text->size);
 	BUFPUTSL(ob, "</code>");
 	return 1;
 }
@@ -230,11 +240,11 @@
 	BUFPUTSL(ob, "<a href=\"");
 
 	if (link && link->size)
-		houdini_escape_href(ob, link->data, link->size);
+		escape_href(ob, link->data, link->size);
 
 	if (title && title->size) {
 		BUFPUTSL(ob, "\" title=\"");
-		houdini_escape_html(ob, title->data, title->size);
+		escape_html(ob, title->data, title->size);
 	}
 
 	if (options->link_attributes) {
@@ -322,9 +332,9 @@
 	size_t org, sz;
 	if (!text) return;
 	sz = text->size;
-	while (sz > 0 && text->data[sz - 1] == '\n') sz -= 1;
+	while (sz > 0 && text->data[sz - 1] == '\n') sz--;
 	org = 0;
-	while (org < sz && text->data[org] == '\n') org += 1;
+	while (org < sz && text->data[org] == '\n') org++;
 	if (org >= sz) return;
 	if (ob->size) bufputc(ob, '\n');
 	bufput(ob, text->data + org, sz - org);
@@ -356,15 +366,15 @@
 	if (!link || !link->size) return 0;
 
 	BUFPUTSL(ob, "<img src=\"");
-	houdini_escape_href(ob, link->data, link->size);
+	escape_href(ob, link->data, link->size);
 	BUFPUTSL(ob, "\" alt=\"");
 
 	if (alt && alt->size)
-		houdini_escape_html(ob, alt->data, alt->size);
+		escape_html(ob, alt->data, alt->size);
 
 	if (title && title->size) {
 		BUFPUTSL(ob, "\" title=\"");
-		houdini_escape_html(ob, title->data, title->size); }
+		escape_html(ob, title->data, title->size); }
 
 	bufputs(ob, USE_XHTML(options) ? "\"/>" : "\">");
 	return 1;
@@ -375,6 +385,13 @@
 {
 	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;
 
@@ -466,7 +483,7 @@
 rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque)
 {
 	if (text)
-		houdini_escape_html(ob, text->data, text->size);
+		escape_html(ob, text->data, text->size);
 }
 
 static void
@@ -598,6 +615,6 @@
 		callbacks->autolink = NULL;
 	}
 
-	if (render_flags & HTML_SKIP_HTML)
+	if (render_flags & HTML_SKIP_HTML || render_flags & HTML_ESCAPE)
 		callbacks->blockhtml = NULL;
 }
diff --git a/cbits/html.h b/cbits/html.h
--- a/cbits/html.h
+++ b/cbits/html.h
@@ -43,6 +43,7 @@
 	HTML_TOC = (1 << 6),
 	HTML_HARD_WRAP = (1 << 7),
 	HTML_USE_XHTML = (1 << 8),
+	HTML_ESCAPE = (1 << 9),
 } html_render_mode;
 
 typedef enum {
diff --git a/cbits/html_blocks.h b/cbits/html_blocks.h
--- a/cbits/html_blocks.h
+++ b/cbits/html_blocks.h
@@ -147,7 +147,7 @@
 {
   enum
     {
-      TOTAL_KEYWORDS = 23,
+      TOTAL_KEYWORDS = 24,
       MIN_WORD_LENGTH = 1,
       MAX_WORD_LENGTH = 10,
       MIN_HASH_VALUE = 1,
@@ -179,7 +179,8 @@
       "script",
       "h5",
       "noscript",
-      "", "",
+      "",
+      "style",
       "iframe",
       "h4",
       "ins",
diff --git a/cbits/html_smartypants.c b/cbits/html_smartypants.c
--- a/cbits/html_smartypants.c
+++ b/cbits/html_smartypants.c
@@ -264,8 +264,10 @@
 static size_t
 smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
 {
-	static const char *skip_tags[] = {"pre", "code", "kbd", "script"};
-	static const size_t skip_tags_count = 4;
+	static const char *skip_tags[] = {
+	  "pre", "code", "var", "samp", "kbd", "math", "script", "style"
+	};
+	static const size_t skip_tags_count = 8;
 
 	size_t tag, i = 0;
 
diff --git a/cbits/markdown.c b/cbits/markdown.c
--- a/cbits/markdown.c
+++ b/cbits/markdown.c
@@ -111,6 +111,7 @@
 	struct stack work_bufs[2];
 	unsigned int ext_flags;
 	size_t max_nesting;
+	int in_link_body;
 };
 
 /***************************
@@ -372,7 +373,6 @@
 		if (end >= size) break;
 		i = end;
 
-		/* calling the trigger */
 		end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
 		if (!end) /* no action from the callback */
 			end = i + 1;
@@ -425,7 +425,6 @@
 			}
 
 			if (i >= size) return tmp_i;
-			i++;
 		}
 		/* skipping a link */
 		else if (data[i] == '[') {
@@ -682,7 +681,7 @@
 static size_t
 char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
 {
-	static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>";
+	static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>^~";
 	struct buf work = { 0, 0, 0, 0 };
 
 	if (size > 1) {
@@ -695,6 +694,8 @@
 			rndr->cb.normal_text(ob, &work, rndr->opaque);
 		}
 		else bufputc(ob, data[1]);
+	} else if (size == 1) {
+		bufputc(ob, data[0]);
 	}
 
 	return 2;
@@ -761,7 +762,7 @@
 	struct buf *link, *link_url, *link_text;
 	size_t link_len, rewind;
 
-	if (!rndr->cb.link)
+	if (!rndr->cb.link || rndr->in_link_body)
 		return 0;
 
 	link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -793,7 +794,7 @@
 	struct buf *link;
 	size_t link_len, rewind;
 
-	if (!rndr->cb.autolink)
+	if (!rndr->cb.autolink || rndr->in_link_body)
 		return 0;
 
 	link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -813,7 +814,7 @@
 	struct buf *link;
 	size_t link_len, rewind;
 
-	if (!rndr->cb.autolink)
+	if (!rndr->cb.autolink || rndr->in_link_body)
 		return 0;
 
 	link = rndr_newbuf(rndr, BUFFER_SPAN);
@@ -839,6 +840,7 @@
 	struct buf *u_link = 0;
 	size_t org_work_size = rndr->work_bufs[BUFFER_SPAN].size;
 	int text_has_nl = 0, ret = 0;
+	int in_title = 0, qtype = 0;
 
 	/* checking whether the correct renderer exists */
 	if ((is_img && !rndr->cb.image) || (!is_img && !rndr->cb.link))
@@ -886,7 +888,8 @@
 		/* looking for link end: ' " ) */
 		while (i < size) {
 			if (data[i] == '\\') i += 2;
-			else if (data[i] == ')' || data[i] == '\'' || data[i] == '"') break;
+			else if (data[i] == ')') break;
+			else if (i >= 1 && _isspace(data[i-1]) && (data[i] == '\'' || data[i] == '"')) break;
 			else i++;
 		}
 
@@ -895,12 +898,15 @@
 
 		/* looking for title end if present */
 		if (data[i] == '\'' || data[i] == '"') {
+			qtype = data[i];
+			in_title = 1;
 			i++;
 			title_b = i;
 
 			while (i < size) {
 				if (data[i] == '\\') i += 2;
-				else if (data[i] == ')') break;
+				else if (data[i] == qtype) {in_title = 0; i++;}
+				else if ((data[i] == ')') && !in_title) break;
 				else i++;
 			}
 
@@ -1026,8 +1032,15 @@
 	/* building content: img alt is escaped, link content is parsed */
 	if (txt_e > 1) {
 		content = rndr_newbuf(rndr, BUFFER_SPAN);
-		if (is_img) bufput(content, data + 1, txt_e - 1);
-		else parse_inline(content, rndr, data + 1, txt_e - 1);
+		if (is_img) {
+			bufput(content, data + 1, txt_e - 1);
+		} else {
+			/* disable autolinking when parsing inline the
+			 * content of a link */
+			rndr->in_link_body = 1;
+			parse_inline(content, rndr, data + 1, txt_e - 1);
+			rndr->in_link_body = 0;
+		}
 	}
 
 	if (link) {
@@ -1565,6 +1578,7 @@
 	struct buf *work = 0, *inter = 0;
 	size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
 	int in_empty = 0, has_inside_empty = 0;
+	size_t has_next_uli, has_next_oli;
 
 	/* keeping track of the first indentation prefix */
 	while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
@@ -1611,10 +1625,19 @@
 
 		pre = i;
 
+		has_next_uli = prefix_uli(data + beg + i, end - beg - i);
+		has_next_oli = prefix_oli(data + beg + i, end - beg - i);
+
+		/* checking for ul/ol switch */
+		if (in_empty && (
+			((*flags & MKD_LIST_ORDERED) && has_next_uli) ||
+			(!(*flags & MKD_LIST_ORDERED) && has_next_oli))){
+			*flags |= MKD_LI_END;
+			break; /* the following item must have same list type */
+		}
+
 		/* checking for a new item */
-		if ((prefix_uli(data + beg + i, end - beg - i) &&
-			!is_hrule(data + beg + i, end - beg - i)) ||
-			prefix_oli(data + beg + i, end - beg - i)) {
+		if ((has_next_uli && !is_hrule(data + beg + i, end - beg - i)) || has_next_oli) {
 			if (in_empty)
 				has_inside_empty = 1;
 
@@ -1783,7 +1806,7 @@
 		i++;
 
 	if (i < size)
-		curtag = find_block_tag((char *)data + 1, i - 1);
+		curtag = find_block_tag((char *)data + 1, (int)i - 1);
 
 	/* handling of special cases */
 	if (!curtag) {
@@ -2332,6 +2355,7 @@
 	md->ext_flags = extensions;
 	md->opaque = opaque;
 	md->max_nesting = max_nesting;
+	md->in_link_body = 0;
 
 	return md;
 }
@@ -2339,7 +2363,8 @@
 void
 sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, struct sd_markdown *md)
 {
-	static const float MARKDOWN_GROW_FACTOR = 1.4f;
+#define MARKDOWN_GROW(x) ((x) + ((x) >> 1))
+	static const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
 
 	struct buf *text;
 	size_t beg, end;
@@ -2356,6 +2381,12 @@
 
 	/* first pass: looking for references, copying everything else */
 	beg = 0;
+
+	/* Skip a possible UTF-8 BOM, even though the Unicode standard
+	 * discourages having these in UTF-8 documents */
+	if (doc_size >= 3 && memcmp(document, UTF8_BOM, 3) == 0)
+		beg += 3;
+
 	while (beg < doc_size) /* iterating over lines */
 		if (is_ref(document, beg, doc_size, &end, md->refs))
 			beg = end;
@@ -2379,7 +2410,7 @@
 		}
 
 	/* pre-grow the output buffer to minimize allocations */
-	bufgrow(ob, text->size * MARKDOWN_GROW_FACTOR);
+	bufgrow(ob, MARKDOWN_GROW(text->size));
 
 	/* second pass: actual rendering */
 	if (md->cb.doc_header)
diff --git a/cbits/stack.h b/cbits/stack.h
--- a/cbits/stack.h
+++ b/cbits/stack.h
@@ -1,5 +1,5 @@
-#ifndef __CR_STACK_H__
-#define __CR_STACK_H__
+#ifndef STACK_H__
+#define STACK_H__
 
 #include <stdlib.h>
 
diff --git a/src/Text/Sundown/Flag.hs b/src/Text/Sundown/Flag.hs
--- a/src/Text/Sundown/Flag.hs
+++ b/src/Text/Sundown/Flag.hs
@@ -3,16 +3,12 @@
        , toCUInt
        ) where
 
-
 import Foreign.C.Types
 import Data.Bits
 
 class Flag a where
-  flagIndexes :: a -> [(Int, Bool)]
+  flagIndexes :: a -> [(CUInt, Bool)]
 
 toCUInt :: Flag a => a -> CUInt
-toCUInt flag = foldl (\uint (ix, b) -> shiftL (fromIntegral . fromEnum $ b) ix .|. uint)
+toCUInt flag = foldl (\uint (f, b) -> (if b then f else 0) .|. uint)
                      0 (flagIndexes flag)
-
-
-
diff --git a/src/Text/Sundown/Markdown/Foreign.hsc b/src/Text/Sundown/Markdown/Foreign.hsc
--- a/src/Text/Sundown/Markdown/Foreign.hsc
+++ b/src/Text/Sundown/Markdown/Foreign.hsc
@@ -35,14 +35,14 @@
                              }
 
 instance Flag Extensions where
-  flagIndexes exts = [ (0, extNoIntraEmphasis exts)
-                     , (1, extTables exts)
-                     , (2, extFencedCode exts)
-                     , (3, extAutolink exts)
-                     , (4, extStrikethrough exts)
-                     , (5, extLaxHtmlBlocks exts)
-                     , (6, extSpaceHeaders exts)
-                     , (7, extSuperscript exts)
+  flagIndexes exts = [ (#{const MKDEXT_NO_INTRA_EMPHASIS}, extNoIntraEmphasis exts)
+                     , (#{const MKDEXT_TABLES}, extTables exts)
+                     , (#{const MKDEXT_FENCED_CODE}, extFencedCode exts)
+                     , (#{const MKDEXT_AUTOLINK}, extAutolink exts)
+                     , (#{const MKDEXT_STRIKETHROUGH}, extStrikethrough exts)
+                     , (#{const MKDEXT_LAX_HTML_BLOCKS}, extLaxHtmlBlocks exts)
+                     , (#{const MKDEXT_SPACE_HEADERS}, extSpaceHeaders exts)
+                     , (#{const MKDEXT_SUPERSCRIPT}, extSuperscript exts)
                      ]
 
 
diff --git a/src/Text/Sundown/Renderers/Html.hs b/src/Text/Sundown/Renderers/Html.hs
--- a/src/Text/Sundown/Renderers/Html.hs
+++ b/src/Text/Sundown/Renderers/Html.hs
@@ -8,8 +8,11 @@
        , HtmlRenderMode (..)
        ) where
 
+import Foreign.Marshal
+import Foreign.Ptr
+import Foreign.Storable
 
-import Foreign
+import System.IO.Unsafe
 
 import Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
@@ -63,11 +66,11 @@
 
 -- | All the 'HtmlRenderMode' disabled
 noHtmlModes :: HtmlRenderMode
-noHtmlModes = HtmlRenderMode False False False False False False False False False
+noHtmlModes = HtmlRenderMode False False False False False False False False False False
 
 -- | All the 'HtmlRenderMode' enabled
 allHtmlModes :: HtmlRenderMode
-allHtmlModes = HtmlRenderMode True True True True True True True True True
+allHtmlModes = HtmlRenderMode True True True True True True True True True True
 
 -- | Converts punctuation in Html entities,
 -- <http://daringfireball.net/projects/smartypants/>
diff --git a/src/Text/Sundown/Renderers/Html/Foreign.hsc b/src/Text/Sundown/Renderers/Html/Foreign.hsc
--- a/src/Text/Sundown/Renderers/Html/Foreign.hsc
+++ b/src/Text/Sundown/Renderers/Html/Foreign.hsc
@@ -28,19 +28,21 @@
                                      , htmlToc :: Bool -- ^ Include a table of contents in the output
                                      , htmlHardWrap :: Bool
                                      , htmlUseXhtml :: Bool -- ^ Produce XHTML output instead of HTML
+                                     , htmlEscape :: Bool
                                      }
 
 
 instance Flag HtmlRenderMode where
-  flagIndexes mode = [ (0, htmlSkipHtml mode)
-                     , (1, htmlSkipStyle mode)
-                     , (2, htmlSkipImages mode)
-                     , (3, htmlSkipLinks mode)
-                     , (4, htmlExpandTabs mode)
-                     , (5, htmlSafelink mode)
-                     , (6, htmlToc mode)
-                     , (7, htmlHardWrap mode)
-                     , (8, htmlUseXhtml mode)
+  flagIndexes mode = [ (#{const HTML_SKIP_HTML}, htmlSkipHtml mode)
+                     , (#{const HTML_SKIP_STYLE}, htmlSkipStyle mode)
+                     , (#{const HTML_SKIP_IMAGES}, htmlSkipImages mode)
+                     , (#{const HTML_SKIP_LINKS}, htmlSkipLinks mode)
+                     , (#{const HTML_EXPAND_TABS}, htmlExpandTabs mode)
+                     , (#{const HTML_SAFELINK}, htmlSafelink mode)
+                     , (#{const HTML_TOC}, htmlToc mode)
+                     , (#{const HTML_HARD_WRAP}, htmlHardWrap mode)
+                     , (#{const HTML_USE_XHTML}, htmlUseXhtml mode)
+                     , (#{const HTML_ESCAPE}, htmlEscape mode)
                      ]
 
 data HtmlRenderOptions
diff --git a/sundown.cabal b/sundown.cabal
--- a/sundown.cabal
+++ b/sundown.cabal
@@ -1,6 +1,6 @@
 Cabal-version:          >= 1.6
 Name:                   sundown
-Version:                0.4
+Version:                0.4.1
 Author:                 Francesco Mazzoli (f@mazzo.li)
 Maintainer:             Francesco Mazzoli (f@mazzo.li)
 Build-Type:             Simple
@@ -8,7 +8,7 @@
 Build-Type:             Simple
 Category:               Foreign binding, Text
 Synopsis:               Bindings to the sundown markdown library
-Tested-With:            GHC==7.0.2
+Tested-With:            GHC==7.2.2
 Description:
   Bindings to the github fork of sundown, a nice C markdown library:
   <https://github.com/tanoku/sundown>
@@ -24,9 +24,9 @@
                       , bytestring
 
   GHC-Options:          -Wall -O2 -fno-cse
-  
+
   Extensions:           ForeignFunctionInterface, EmptyDataDecls
-  
+
   Exposed-Modules:      Text.Sundown
                       , Text.Sundown.Markdown
                       , Text.Sundown.Renderers.Html
@@ -39,9 +39,9 @@
   C-Sources:            cbits/autolink.c, cbits/buffer.c, cbits/houdini_href_e.c,
                         cbits/houdini_html_e.c, cbits/html.c, cbits/html_smartypants.c,
                         cbits/markdown.c, cbits/stack.c
-  
+
   Include-Dirs:         cbits
-  
+
   Includes:             autolink.h, buffer.h, html.h, html_blocks.h, markdown.h, stack.h
 
   Install-includes:     autolink.h, buffer.h, houdini.h, html.h, html_blocks.h, markdown.h, stack.h
