diff --git a/cbits/markdown.c b/cbits/markdown.c
--- a/cbits/markdown.c
+++ b/cbits/markdown.c
@@ -758,7 +758,7 @@
 static size_t
 char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
 {
-	struct buf *link, *link_url;
+	struct buf *link, *link_url, *link_text;
 	size_t link_len, rewind;
 
 	if (!rndr->cb.link)
@@ -772,7 +772,14 @@
 		bufput(link_url, link->data, link->size);
 
 		ob->size -= rewind;
-		rndr->cb.link(ob, link_url, NULL, link, rndr->opaque);
+		if (rndr->cb.normal_text) {
+			link_text = rndr_newbuf(rndr, BUFFER_SPAN);
+			rndr->cb.normal_text(link_text, link, rndr->opaque);
+			rndr->cb.link(ob, link_url, NULL, link_text, rndr->opaque);
+			rndr_popbuf(rndr, BUFFER_SPAN);
+		} else {
+			rndr->cb.link(ob, link_url, NULL, link, rndr->opaque);
+		}
 		rndr_popbuf(rndr, BUFFER_SPAN);
 	}
 
@@ -1775,7 +1782,7 @@
 	while (i < size && data[i] != '>' && data[i] != ' ')
 		i++;
 
-	if (i < size && data[i] == '>')
+	if (i < size)
 		curtag = find_block_tag((char *)data + 1, i - 1);
 
 	/* handling of special cases */
@@ -1862,7 +1869,14 @@
 }
 
 static void
-parse_table_row(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, size_t columns, int *col_data)
+parse_table_row(
+	struct buf *ob,
+	struct sd_markdown *rndr,
+	uint8_t *data,
+	size_t size,
+	size_t columns,
+	int *col_data,
+	int header_flag)
 {
 	size_t i = 0, col;
 	struct buf *row_work = 0;
@@ -1895,7 +1909,7 @@
 			cell_end--;
 
 		parse_inline(cell_work, rndr, data + cell_start, 1 + cell_end - cell_start);
-		rndr->cb.table_cell(row_work, cell_work, col_data[col], rndr->opaque);
+		rndr->cb.table_cell(row_work, cell_work, col_data[col] | header_flag, rndr->opaque);
 
 		rndr_popbuf(rndr, BUFFER_SPAN);
 		i++;
@@ -1903,7 +1917,7 @@
 
 	for (; col < columns; ++col) {
 		struct buf empty_cell = { 0, 0, 0, 0 };
-		rndr->cb.table_cell(row_work, &empty_cell, col_data[col], rndr->opaque);
+		rndr->cb.table_cell(row_work, &empty_cell, col_data[col] | header_flag, rndr->opaque);
 	}
 
 	rndr->cb.table_row(ob, row_work, rndr->opaque);
@@ -1912,7 +1926,13 @@
 }
 
 static size_t
-parse_table_header(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, size_t *columns, int **column_data)
+parse_table_header(
+	struct buf *ob,
+	struct sd_markdown *rndr,
+	uint8_t *data,
+	size_t size,
+	size_t *columns,
+	int **column_data)
 {
 	int pipes;
 	size_t i = 0, col, header_end, under_end;
@@ -1948,8 +1968,6 @@
 	for (col = 0; col < *columns && i < under_end; ++col) {
 		size_t dashes = 0;
 
-		(*column_data)[col] |= MKD_TABLE_HEADER;
-
 		while (i < under_end && data[i] == ' ')
 			i++;
 
@@ -1982,12 +2000,23 @@
 	if (col < *columns)
 		return 0;
 
-	parse_table_row(ob, rndr, data, header_end, *columns, *column_data);
+	parse_table_row(
+		ob, rndr, data,
+		header_end,
+		*columns,
+		*column_data,
+		MKD_TABLE_HEADER
+	);
+
 	return under_end + 1;
 }
 
 static size_t
-parse_table(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size)
+parse_table(
+	struct buf *ob,
+	struct sd_markdown *rndr,
+	uint8_t *data,
+	size_t size)
 {
 	size_t i;
 
@@ -2018,7 +2047,15 @@
 				break;
 			}
 
-			parse_table_row(body_work, rndr, data + row_start, i - row_start, columns, col_data);
+			parse_table_row(
+				body_work,
+				rndr,
+				data + row_start,
+				i - row_start,
+				columns,
+				col_data, 0
+			);
+
 			i++;
 		}
 
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
@@ -38,13 +38,13 @@
     -- Allocate buffers
     ob <- c_bufnew 64
     ib <- c_bufnew . fromIntegral . BS.length $ input
-    
+
     -- Put the input content into the buffer
     c_bufputs ib input
-    
+
     -- Do the markdown
     c_sdhtml_renderer callbacks options mode
-    
+
     let maxNesting = fromIntegral $ fromMaybe defaultMaxNesting maxNestingM
     markdown <- c_sd_markdown_new exts maxNesting callbacks (castPtr options)
 
@@ -52,13 +52,13 @@
     c_sd_markdown_render ob cs size markdown
 
     c_sd_markdown_free markdown
-    
+
     -- Get the result
     output <- peek ob >>= getBufferData
-    
+
     c_bufrelease ib
-    c_bufrelease ob    
-    
+    c_bufrelease ob
+
     return output
 
 -- | All the 'HtmlRenderMode' disabled
@@ -77,15 +77,15 @@
   unsafePerformIO $ do
     ob <- c_bufnew 64
     ib <- c_bufnew $ fromInteger . toInteger $ BS.length input
-    
+
     c_bufputs ib input
 
     Buffer {bufData = cs, bufSize = size} <- peek ib
     c_sdhtml_smartypants ob cs size
-    
+
     output <- peek ob >>= getBufferData
-    
+
     c_bufrelease ib
     c_bufrelease ob
-    
+
     return output
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
@@ -7,7 +7,6 @@
        , c_sdhtml_smartypants
        ) where
 
-
 import Foreign
 import Foreign.C.String
 import Foreign.C.Types
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.3
+Version:                0.4
 Author:                 Francesco Mazzoli (f@mazzo.li)
 Maintainer:             Francesco Mazzoli (f@mazzo.li)
 Build-Type:             Simple
