diff --git a/cbits/autolink.c b/cbits/autolink.c
--- a/cbits/autolink.c
+++ b/cbits/autolink.c
@@ -15,12 +15,17 @@
  */
 
 #include "buffer.h"
+#include "autolink.h"
 
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <ctype.h>
 
+#if defined(_WIN32)
+#define strncasecmp	_strnicmp
+#endif
+
 int
 sd_autolink_issafe(const uint8_t *link, size_t link_len)
 {
@@ -128,7 +133,7 @@
 }
 
 static size_t
-check_domain(uint8_t *data, size_t size)
+check_domain(uint8_t *data, size_t size, int allow_short)
 {
 	size_t i, np = 0;
 
@@ -140,13 +145,27 @@
 		else if (!isalnum(data[i]) && data[i] != '-') break;
 	}
 
-	/* a valid domain needs to have at least a dot.
-	 * that's as far as we get */
-	return np ? i : 0;
+	if (allow_short) {
+		/* We don't need a valid domain in the strict sense (with
+		 * least one dot; so just make sure it's composed of valid
+		 * domain characters and return the length of the the valid
+		 * sequence. */
+		return i;
+	} else {
+		/* a valid domain needs to have at least a dot.
+		 * that's as far as we get */
+		return np ? i : 0;
+	}
 }
 
 size_t
-sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
+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;
 
@@ -156,7 +175,7 @@
 	if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
 		return 0;
 
-	link_end = check_domain(data, size);
+	link_end = check_domain(data, size, 0);
 
 	if (link_end == 0)
 		return 0;
@@ -176,7 +195,13 @@
 }
 
 size_t
-sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
+sd_autolink__email(
+	size_t *rewind_p,
+	struct buf *link,
+	uint8_t *data,
+	size_t offset,
+	size_t size,
+	unsigned int flags)
 {
 	size_t link_end, rewind;
 	int nb = 0, np = 0;
@@ -225,7 +250,13 @@
 }
 
 size_t
-sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
+sd_autolink__url(
+	size_t *rewind_p,
+	struct buf *link,
+	uint8_t *data,
+	size_t offset,
+	size_t size,
+	unsigned int flags)
 {
 	size_t link_end, rewind = 0, domain_len;
 
@@ -237,9 +268,14 @@
 
 	if (!sd_autolink_issafe(data - rewind, size + rewind))
 		return 0;
+
 	link_end = strlen("://");
 
-	domain_len = check_domain(data + link_end, size - link_end);
+	domain_len = check_domain(
+		data + link_end,
+		size - link_end,
+		flags & SD_AUTOLINK_SHORT_DOMAINS);
+
 	if (domain_len == 0)
 		return 0;
 
diff --git a/cbits/autolink.h b/cbits/autolink.h
--- a/cbits/autolink.h
+++ b/cbits/autolink.h
@@ -19,17 +19,32 @@
 
 #include "buffer.h"
 
-extern int
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+	SD_AUTOLINK_SHORT_DOMAINS = (1 << 0),
+};
+
+int
 sd_autolink_issafe(const uint8_t *link, size_t link_len);
 
-extern size_t
-sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
+size_t
+sd_autolink__www(size_t *rewind_p, struct buf *link,
+	uint8_t *data, size_t offset, size_t size, unsigned int flags);
 
-extern size_t
-sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
+size_t
+sd_autolink__email(size_t *rewind_p, struct buf *link,
+	uint8_t *data, size_t offset, size_t size, unsigned int flags);
 
-extern size_t
-sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
+size_t
+sd_autolink__url(size_t *rewind_p, struct buf *link,
+	uint8_t *data, size_t offset, size_t size, unsigned int flags);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
 
diff --git a/cbits/buffer.c b/cbits/buffer.c
--- a/cbits/buffer.c
+++ b/cbits/buffer.c
@@ -127,7 +127,9 @@
 
 	if (n < 0) {
 #ifdef _MSC_VER
+		va_start(ap, fmt);
 		n = _vscprintf(fmt, ap);
+		va_end(ap);
 #else
 		return;
 #endif
diff --git a/cbits/buffer.h b/cbits/buffer.h
--- a/cbits/buffer.h
+++ b/cbits/buffer.h
@@ -22,6 +22,10 @@
 #include <stdarg.h>
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #if defined(_MSC_VER)
 #define __attribute__(x)
 #define inline
@@ -84,5 +88,9 @@
 
 /* bufprintf: formatted printing to a buffer */
 void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/cbits/markdown.c b/cbits/markdown.c
--- a/cbits/markdown.c
+++ b/cbits/markdown.c
@@ -25,6 +25,10 @@
 #include <ctype.h>
 #include <stdio.h>
 
+#if defined(_WIN32)
+#define strncasecmp	_strnicmp
+#endif
+
 #define REF_TABLE_SIZE 8
 
 #define BUFFER_BLOCK 0
@@ -767,7 +771,7 @@
 
 	link = rndr_newbuf(rndr, BUFFER_SPAN);
 
-	if ((link_len = sd_autolink__www(&rewind, link, data, offset, size)) > 0) {
+	if ((link_len = sd_autolink__www(&rewind, link, data, offset, size, 0)) > 0) {
 		link_url = rndr_newbuf(rndr, BUFFER_SPAN);
 		BUFPUTSL(link_url, "http://");
 		bufput(link_url, link->data, link->size);
@@ -799,7 +803,7 @@
 
 	link = rndr_newbuf(rndr, BUFFER_SPAN);
 
-	if ((link_len = sd_autolink__email(&rewind, link, data, offset, size)) > 0) {
+	if ((link_len = sd_autolink__email(&rewind, link, data, offset, size, 0)) > 0) {
 		ob->size -= rewind;
 		rndr->cb.autolink(ob, link, MKDA_EMAIL, rndr->opaque);
 	}
@@ -819,7 +823,7 @@
 
 	link = rndr_newbuf(rndr, BUFFER_SPAN);
 
-	if ((link_len = sd_autolink__url(&rewind, link, data, offset, size)) > 0) {
+	if ((link_len = sd_autolink__url(&rewind, link, data, offset, size, 0)) > 0) {
 		ob->size -= rewind;
 		rndr->cb.autolink(ob, link, MKDA_NORMAL, rndr->opaque);
 	}
@@ -1150,9 +1154,10 @@
 	return n >= 3;
 }
 
-/* check if a line is a code fence; return its size if it is */
+/* check if a line begins with a code fence; return the
+ * width of the code fence */
 static size_t
-is_codefence(uint8_t *data, size_t size, struct buf *syntax)
+prefix_codefence(uint8_t *data, size_t size)
 {
 	size_t i = 0, n = 0;
 	uint8_t c;
@@ -1177,43 +1182,56 @@
 	if (n < 3)
 		return 0;
 
-	if (syntax != NULL) {
-		size_t syn = 0;
+	return i;
+}
 
-		while (i < size && data[i] == ' ')
-			i++;
+/* check if a line is a code fence; return its size if it is */
+static size_t
+is_codefence(uint8_t *data, size_t size, struct buf *syntax)
+{
+	size_t i = 0, syn_len = 0;
+	uint8_t *syn_start;
 
-		syntax->data = data + i;
+	i = prefix_codefence(data, size);
+	if (i == 0)
+		return 0;
 
-		if (i < size && data[i] == '{') {
-			i++; syntax->data++;
+	while (i < size && data[i] == ' ')
+		i++;
 
-			while (i < size && data[i] != '}' && data[i] != '\n') {
-				syn++; i++;
-			}
+	syn_start = data + i;
 
-			if (i == size || data[i] != '}')
-				return 0;
+	if (i < size && data[i] == '{') {
+		i++; syn_start++;
 
-			/* strip all whitespace at the beginning and the end
-			 * of the {} block */
-			while (syn > 0 && _isspace(syntax->data[0])) {
-				syntax->data++; syn--;
-			}
+		while (i < size && data[i] != '}' && data[i] != '\n') {
+			syn_len++; i++;
+		}
 
-			while (syn > 0 && _isspace(syntax->data[syn - 1]))
-				syn--;
+		if (i == size || data[i] != '}')
+			return 0;
 
-			i++;
-		} else {
-			while (i < size && !_isspace(data[i])) {
-				syn++; i++;
-			}
+		/* strip all whitespace at the beginning and the end
+		 * of the {} block */
+		while (syn_len > 0 && _isspace(syn_start[0])) {
+			syn_start++; syn_len--;
 		}
 
-		syntax->size = syn;
+		while (syn_len > 0 && _isspace(syn_start[syn_len - 1]))
+			syn_len--;
+
+		i++;
+	} else {
+		while (i < size && !_isspace(data[i])) {
+			syn_len++; i++;
+		}
 	}
 
+	if (syntax) {
+		syntax->data = syn_start;
+		syntax->size = syn_len;
+	}
+
 	while (i < size && data[i] != '\n') {
 		if (!_isspace(data[i]))
 			return 0;
@@ -1416,19 +1434,48 @@
 	while (i < size) {
 		for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */;
 
-		if (is_empty(data + i, size - i) || (level = is_headerline(data + i, size - i)) != 0)
+		if (is_empty(data + i, size - i))
 			break;
 
-		if (rndr->ext_flags & MKDEXT_LAX_HTML_BLOCKS) {
-			if (data[i] == '<' && rndr->cb.blockhtml && parse_htmlblock(ob, rndr, data + i, size - i, 0)) {
+		if ((level = is_headerline(data + i, size - i)) != 0)
+			break;
+
+		if (is_atxheader(rndr, data + i, size - i) ||
+			is_hrule(data + i, size - i) ||
+			prefix_quote(data + i, size - i)) {
+			end = i;
+			break;
+		}
+
+		/*
+		 * Early termination of a paragraph with the same logic
+		 * as Markdown 1.0.0. If this logic is applied, the
+		 * Markdown 1.0.3 test suite won't pass cleanly
+		 *
+		 * :: If the first character in a new line is not a letter,
+		 * let's check to see if there's some kind of block starting
+		 * here
+		 */
+		if ((rndr->ext_flags & MKDEXT_LAX_SPACING) && !isalnum(data[i])) {
+			if (prefix_oli(data + i, size - i) ||
+				prefix_uli(data + i, size - i)) {
 				end = i;
 				break;
 			}
-		}
 
-		if (is_atxheader(rndr, data + i, size - i) || is_hrule(data + i, size - i)) {
-			end = i;
-			break;
+			/* see if an html block starts here */
+			if (data[i] == '<' && rndr->cb.blockhtml &&
+				parse_htmlblock(ob, rndr, data + i, size - i, 0)) {
+				end = i;
+				break;
+			}
+
+			/* see if a code fence starts here */
+			if ((rndr->ext_flags & MKDEXT_FENCED_CODE) != 0 &&
+				is_codefence(data + i, size - i, NULL) != 0) {
+				end = i;
+				break;
+			}
 		}
 
 		i = end;
@@ -1500,9 +1547,10 @@
 
 	while (beg < size) {
 		size_t fence_end;
+		struct buf fence_trail = { 0, 0, 0, 0 };
 
-		fence_end = is_codefence(data + beg, size - beg, NULL);
-		if (fence_end != 0) {
+		fence_end = is_codefence(data + beg, size - beg, &fence_trail);
+		if (fence_end != 0 && fence_trail.size == 0) {
 			beg += fence_end;
 			break;
 		}
@@ -1577,8 +1625,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;
+	int in_empty = 0, has_inside_empty = 0, in_fence = 0;
 
 	/* keeping track of the first indentation prefix */
 	while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
@@ -1606,6 +1653,8 @@
 
 	/* process the following lines */
 	while (beg < size) {
+		size_t has_next_uli = 0, has_next_oli = 0;
+
 		end++;
 
 		while (end < size && data[end - 1] != '\n')
@@ -1625,9 +1674,18 @@
 
 		pre = i;
 
-		has_next_uli = prefix_uli(data + beg + i, end - beg - i);
-		has_next_oli = prefix_oli(data + beg + i, end - beg - i);
+		if (rndr->ext_flags & MKDEXT_FENCED_CODE) {
+			if (is_codefence(data + beg + i, end - beg - i, NULL) != 0)
+				in_fence = !in_fence;
+		}
 
+		/* Only check for new list items if we are **not** inside
+		 * a fenced code block */
+		if (!in_fence) {
+			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) ||
@@ -1647,10 +1705,12 @@
 			if (!sublist)
 				sublist = work->size;
 		}
-		/* joining only indented stuff after empty lines */
-		else if (in_empty && i < 4) {
-				*flags |= MKD_LI_END;
-				break;
+		/* joining only indented stuff after empty lines;
+		 * note that now we only require 1 space of indentation
+		 * to continue a list */
+		else if (in_empty && pre == 0) {
+			*flags |= MKD_LI_END;
+			break;
 		}
 		else if (in_empty) {
 			bufputc(work, '\n');
@@ -1758,7 +1818,12 @@
 /* htmlblock_end • checking end of HTML block : </tag>[ \t]*\n[ \t*]\n */
 /*	returns the length on match, 0 otherwise */
 static size_t
-htmlblock_end(const char *tag, size_t tag_len, struct sd_markdown *rndr, uint8_t *data, size_t size)
+htmlblock_end_tag(
+	const char *tag,
+	size_t tag_len,
+	struct sd_markdown *rndr,
+	uint8_t *data,
+	size_t size)
 {
 	size_t i, w;
 
@@ -1776,25 +1841,60 @@
 	i += w;
 	w = 0;
 
-	if (rndr->ext_flags & MKDEXT_LAX_HTML_BLOCKS) {
-		if (i < size)
-			w = is_empty(data + i, size - i);
-	} else  {
-		if (i < size && (w = is_empty(data + i, size - i)) == 0)
-			return 0; /* non-blank line after tag line */
-	}
+	if (i < size)
+		w = is_empty(data + i, size - i);
 
 	return i + w;
 }
 
+static size_t
+htmlblock_end(const char *curtag,
+	struct sd_markdown *rndr,
+	uint8_t *data,
+	size_t size,
+	int start_of_line)
+{
+	size_t tag_size = strlen(curtag);
+	size_t i = 1, end_tag;
+	int block_lines = 0;
 
+	while (i < size) {
+		i++;
+		while (i < size && !(data[i - 1] == '<' && data[i] == '/')) {
+			if (data[i] == '\n')
+				block_lines++;
+
+			i++;
+		}
+
+		/* If we are only looking for unindented tags, skip the tag
+		 * if it doesn't follow a newline.
+		 *
+		 * The only exception to this is if the tag is still on the
+		 * initial line; in that case it still counts as a closing
+		 * tag
+		 */
+		if (start_of_line && block_lines > 0 && data[i - 2] != '\n')
+			continue;
+
+		if (i + 2 + tag_size >= size)
+			break;
+
+		end_tag = htmlblock_end_tag(curtag, tag_size, rndr, data + i - 1, size - i + 1);
+		if (end_tag)
+			return i + end_tag - 1;
+	}
+
+	return 0;
+}
+
+
 /* parse_htmlblock • parsing of inline HTML block */
 static size_t
 parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int do_render)
 {
-	size_t i, j = 0;
+	size_t i, j = 0, tag_end;
 	const char *curtag = NULL;
-	int found;
 	struct buf work = { data, 0, 0, 0 };
 
 	/* identification of the opening tag */
@@ -1855,40 +1955,23 @@
 
 	/* looking for an unindented matching closing tag */
 	/*	followed by a blank line */
-	i = 1;
-	found = 0;
+	tag_end = htmlblock_end(curtag, rndr, data, size, 1);
 
 	/* if not found, trying a second pass looking for indented match */
 	/* but not if tag is "ins" or "del" (following original Markdown.pl) */
-	if (strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0) {
-		size_t tag_size = strlen(curtag);
-		i = 1;
-		while (i < size) {
-			i++;
-			while (i < size && !(data[i - 1] == '<' && data[i] == '/'))
-				i++;
-
-			if (i + 2 + tag_size >= size)
-				break;
-
-			j = htmlblock_end(curtag, tag_size, rndr, data + i - 1, size - i + 1);
-
-			if (j) {
-				i += j - 1;
-				found = 1;
-				break;
-			}
-		}
+	if (!tag_end && strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0) {
+		tag_end = htmlblock_end(curtag, rndr, data, size, 0);
 	}
 
-	if (!found) return 0;
+	if (!tag_end)
+		return 0;
 
 	/* the end of the block has been found */
-	work.size = i;
+	work.size = tag_end;
 	if (do_render && rndr->cb.blockhtml)
 		rndr->cb.blockhtml(ob, &work, rndr->opaque);
 
-	return i;
+	return tag_end;
 }
 
 static void
@@ -1970,10 +2053,13 @@
 
 	header_end = i;
 
+	while (header_end > 0 && _isspace(data[header_end - 1]))
+		header_end--;
+
 	if (data[0] == '|')
 		pipes--;
 
-	if (i > 2 && data[i - 1] == '|')
+	if (header_end && data[header_end - 1] == '|')
 		pipes--;
 
 	*columns = pipes + 1;
@@ -2247,8 +2333,8 @@
 			line_end = title_end;
 			title_end = i; } }
 
-	if (!line_end)
-		return 0; /* garbage after the link */
+	if (!line_end || link_end == link_offset)
+		return 0; /* garbage after the link empty link */
 
 	/* a valid ref has been found, filling-in return structures */
 	if (last)
@@ -2258,6 +2344,8 @@
 		struct link_ref *ref;
 
 		ref = add_link_ref(refs, data + id_offset, id_end - id_offset);
+		if (!ref)
+			return 0;
 
 		ref->link = bufnew(link_end - link_offset);
 		bufput(ref->link, data + link_offset, link_end - link_offset);
@@ -2455,9 +2543,9 @@
 void
 sd_version(int *ver_major, int *ver_minor, int *ver_revision)
 {
-	*ver_major = UPSKIRT_VER_MAJOR;
-	*ver_minor = UPSKIRT_VER_MINOR;
-	*ver_revision = UPSKIRT_VER_REVISION;
+	*ver_major = SUNDOWN_VER_MAJOR;
+	*ver_minor = SUNDOWN_VER_MINOR;
+	*ver_revision = SUNDOWN_VER_REVISION;
 }
 
 /* vim: set filetype=c: */
diff --git a/cbits/markdown.h b/cbits/markdown.h
--- a/cbits/markdown.h
+++ b/cbits/markdown.h
@@ -22,11 +22,15 @@
 #include "buffer.h"
 #include "autolink.h"
 
-#define UPSKIRT_VERSION "1.15.2"
-#define UPSKIRT_VER_MAJOR 1
-#define UPSKIRT_VER_MINOR 15
-#define UPSKIRT_VER_REVISION 2
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+#define SUNDOWN_VERSION "1.16.0"
+#define SUNDOWN_VER_MAJOR 1
+#define SUNDOWN_VER_MINOR 16
+#define SUNDOWN_VER_REVISION 0
+
 /********************
  * TYPE DEFINITIONS *
  ********************/
@@ -52,9 +56,9 @@
 	MKDEXT_FENCED_CODE = (1 << 2),
 	MKDEXT_AUTOLINK = (1 << 3),
 	MKDEXT_STRIKETHROUGH = (1 << 4),
-	MKDEXT_LAX_HTML_BLOCKS = (1 << 5),
 	MKDEXT_SPACE_HEADERS = (1 << 6),
 	MKDEXT_SUPERSCRIPT = (1 << 7),
+	MKDEXT_LAX_SPACING = (1 << 8),
 };
 
 /* sd_callbacks - functions for rendering parsed data */
@@ -124,6 +128,10 @@
 
 extern void
 sd_version(int *major, int *minor, int *revision);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
 
diff --git a/cbits/stack.h b/cbits/stack.h
--- a/cbits/stack.h
+++ b/cbits/stack.h
@@ -3,6 +3,10 @@
 
 #include <stdlib.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct stack {
 	void **item;
 	size_t size;
@@ -17,5 +21,9 @@
 
 void *stack_pop(struct stack *);
 void *stack_top(struct stack *);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
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
@@ -17,22 +17,23 @@
 #include "markdown.h"
 
 -- | A set of switches to enable or disable markdown features.
-data Extensions = Extensions { extNoIntraEmphasis :: Bool -- ^ Turn off underscores insode a word
-                                                         --   does designating emphasis.
-                             , extTables :: Bool
-                             , extFencedCode :: Bool -- ^ Turns on a non-indentation form of
-                                                    -- code-blocks, by blocking off a regionwith ~
-                                                    -- or \`.
-                             , extAutolink :: Bool -- ^ Turn things that look like URLs and email
-                                                  -- addresses into links
-                             , extStrikethrough :: Bool -- ^ Surround text with `~` to designate it
-                                                       -- as struck through
-                             , extLaxHtmlBlocks :: Bool -- ^ Allow HTML markup inside of paragraphs,
-                                                       -- instead requireing tags to be on separate
-                                                       -- lines
-                             , extSpaceHeaders :: Bool
-                             , extSuperscript :: Bool
-                             }
+data Extensions = Extensions
+  { extNoIntraEmphasis :: Bool
+    -- ^ Turn off underscores insode a word does designating emphasis.
+  , extTables :: Bool
+  , extFencedCode :: Bool
+    -- ^ Turns on a non-indentation form of code-blocks, by blocking off a
+    --   regionwith ~ or \`.
+  , extAutolink :: Bool
+    -- ^ Turn things that look like URLs and email addresses into links
+  , extStrikethrough :: Bool
+    -- ^ Surround text with `~` to designate it as struck through
+  , extSpaceHeaders :: Bool
+  , extSuperscript :: Bool
+  , extLaxSpacing :: Bool
+    -- ^ Allow blocks inside of paragraphs, instead requireing tags to be on
+    --   separate lines
+  }
 
 instance Flag Extensions where
   flagIndexes exts = [ (#{const MKDEXT_NO_INTRA_EMPHASIS}, extNoIntraEmphasis exts)
@@ -40,9 +41,9 @@
                      , (#{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)
+                     , (#{const MKDEXT_LAX_SPACING}, extLaxSpacing exts)
                      ]
 
 
diff --git a/sundown.cabal b/sundown.cabal
--- a/sundown.cabal
+++ b/sundown.cabal
@@ -1,49 +1,47 @@
-Cabal-version:          >= 1.6
-Name:                   sundown
-Version:                0.4.1.2
-Author:                 Francesco Mazzoli (f@mazzo.li)
-Maintainer:             Francesco Mazzoli (f@mazzo.li)
-Build-Type:             Simple
-License:                PublicDomain
-Build-Type:             Simple
-Category:               Foreign binding, Text
-Synopsis:               Bindings to the sundown markdown library
-Tested-With:            GHC==7.2.2
-Homepage:               https://github.com/bitonic/sundown
-Bug-Reports:            https://github.com/bitonic/sundown/issues
+Cabal-version:      >= 1.6
+Name:               sundown
+Version:            0.4.2
+Author:             Francesco Mazzoli (f@mazzo.li)
+Maintainer:         Francesco Mazzoli (f@mazzo.li)
+Build-Type:         Simple
+License:            PublicDomain
+Build-Type:         Simple
+Category:           Foreign binding, Text
+Synopsis:           Bindings to the sundown markdown library
+Tested-With:        GHC==7.4.2, GHC==7.2.2, GHC==7.0.4, GHC==6.12.3
+Homepage:           https://github.com/bitonic/sundown
+Bug-Reports:        https://github.com/bitonic/sundown/issues
 Description:
-  Bindings to the github fork of sundown, a nice C markdown library:
-  <https://github.com/tanoku/sundown>
+  Bindings to GitHub's C markdown library: <https://github.com/tanoku/sundown>
 
 source-repository head
   type:     git
   location: git://github.com/bitonic/sundown.git
 
 Library
-  Hs-Source-Dirs:       src
-
-  Build-Depends:        base >= 3 && < 5
-                      , bytestring
-
-  GHC-Options:          -Wall -O2 -fno-cse
-
-  Extensions:           ForeignFunctionInterface, EmptyDataDecls
+  Hs-Source-Dirs:   src
+  Build-Depends:    base >= 3 && < 5, bytestring
+  GHC-Options:      -Wall -O2 -fno-cse
+  Extensions:       ForeignFunctionInterface, EmptyDataDecls
 
-  Exposed-Modules:      Text.Sundown
-                      , Text.Sundown.Markdown
-                      , Text.Sundown.Renderers.Html
+  Exposed-Modules:  Text.Sundown,
+                    Text.Sundown.Markdown,
+                    Text.Sundown.Renderers.Html
 
-  Other-Modules:        Text.Sundown.Buffer.Foreign
-                      , Text.Sundown.Renderers.Html.Foreign
-                      , Text.Sundown.Flag
-                      , Text.Sundown.Markdown.Foreign
+  Other-Modules:    Text.Sundown.Buffer.Foreign,
+                    Text.Sundown.Renderers.Html.Foreign,
+                    Text.Sundown.Flag,
+                    Text.Sundown.Markdown.Foreign
 
-  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
+  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
+  Include-Dirs:     cbits
 
-  Includes:             autolink.h, buffer.h, html.h, html_blocks.h, markdown.h, stack.h
+  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
+  Install-includes: autolink.h, buffer.h, houdini.h, html.h, html_blocks.h,
+                    markdown.h, stack.h
